/*************************************************************************** * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XTENSOR_EVAL_HPP #define XTENSOR_EVAL_HPP #include "xexpression_traits.hpp" #include "xshape.hpp" #include "xtensor_forward.hpp" namespace xt { /** * @defgroup xt_xeval * * Evaluation functions. * Defined in ``xtensor/xeval.hpp`` */ namespace detail { template using is_container = std::is_base_of>, T>; } /** * Force evaluation of xexpression. * * @code{.cpp} * xt::xarray a = {1, 2, 3, 4}; * auto&& b = xt::eval(a); // b is a reference to a, no copy! * auto&& c = xt::eval(a + b); // c is xarray, not an xexpression * @endcode * * @ingroup xt_xeval * @return xt::xarray or xt::xtensor depending on shape type */ template inline auto eval(T&& t) -> std::enable_if_t>::value, T&&> { return std::forward(t); } /// @cond DOXYGEN_INCLUDE_SFINAE template inline auto eval(T&& t) -> std::enable_if_t>::value, temporary_type_t> { return std::forward(t); } /// @endcond namespace detail { /********************************** * has_same_layout implementation * **********************************/ template constexpr bool has_same_layout() { return (std::decay_t::static_layout == L) || (L == layout_type::any); } template constexpr bool has_same_layout(E&&) { return has_same_layout(); } template constexpr bool has_same_layout(E1&&, E2&&) { return has_same_layout::static_layout, E2>(); } /********************************* * has_fixed_dims implementation * *********************************/ template constexpr bool has_fixed_dims() { return detail::is_array::shape_type>::value; } template constexpr bool has_fixed_dims(E&&) { return has_fixed_dims(); } /**************************************** * as_xarray_container_t implementation * ****************************************/ template using as_xarray_container_t = xarray::value_type, layout_remove_any(L)>; /***************************************** * as_xtensor_container_t implementation * *****************************************/ template using as_xtensor_container_t = xtensor< typename std::decay_t::value_type, std::tuple_size::shape_type>::value, layout_remove_any(L)>; } /** * Force evaluation of xexpression not providing a data interface * and convert to the required layout. * * @code{.cpp} * xt::xarray a = {1, 2, 3, 4}; * * // take reference to a (no copy!) * auto&& b = xt::as_strided(a); * * // xarray with the required layout * auto&& c = xt::as_strided(a); * * // xexpression * auto&& a_cast = xt::cast(a); * * // xarray, not an xexpression * auto&& d = xt::as_strided(a_cast); * * // xarray with the required layout * auto&& e = xt::as_strided(a_cast); * @endcode * * @warning This function should be used in a local context only. * Returning the value returned by this function could lead to a dangling reference. * @ingroup xt_xeval * @return The expression when it already provides a data interface with the correct layout, * an evaluated xt::xarray or xt::xtensor depending on shape type otherwise. */ template inline auto as_strided(E&& e) -> std::enable_if_t>::value && detail::has_same_layout(), E&&> { return std::forward(e); } /// @cond DOXYGEN_INCLUDE_SFINAE template inline auto as_strided(E&& e) -> std::enable_if_t< (!(has_data_interface>::value && detail::has_same_layout())) && detail::has_fixed_dims(), detail::as_xtensor_container_t> { return e; } template inline auto as_strided(E&& e) -> std::enable_if_t< (!(has_data_interface>::value && detail::has_same_layout())) && (!detail::has_fixed_dims()), detail::as_xarray_container_t> { return e; } /// @endcond } #endif