diff --git a/include/xtensor/core/xassign.hpp b/include/xtensor/core/xassign.hpp index 904113814..d3339cf5f 100644 --- a/include/xtensor/core/xassign.hpp +++ b/include/xtensor/core/xassign.hpp @@ -214,7 +214,7 @@ namespace xt template inline void assign_xexpression(xexpression& e1, const xexpression& e2) { - if constexpr (has_assign_to::value) + if constexpr (has_assign_to()) { e2.derived_cast().assign_to(e1); } @@ -266,15 +266,14 @@ namespace xt } template - inline auto is_linear_assign(const E1& e1, const E2& e2) - -> std::enable_if_t::value, bool> + inline auto is_linear_assign(const E1& e1, const E2& e2) -> std::enable_if_t(), bool> { return (E1::contiguous_layout && E2::contiguous_layout && linear_static_layout()) || (e1.is_contiguous() && e2.has_linear_assign(e1.strides())); } template - inline auto is_linear_assign(const E1&, const E2&) -> std::enable_if_t::value, bool> + inline auto is_linear_assign(const E1&, const E2&) -> std::enable_if_t(), bool> { return false; } @@ -304,8 +303,8 @@ namespace xt return std::is_reference::value; } - static constexpr bool value = has_strides::value - && has_step_leading::value && stepper_deref(); + static constexpr bool value = has_strides() && has_step_leading::value + && stepper_deref(); }; template @@ -1002,13 +1001,13 @@ namespace xt const strides_type& m_strides; }; - template ::value || !possible, bool> = true> + template () || !possible, bool> = true> loop_sizes_t get_loop_sizes(const E1& e1, const E2&) { return {false, true, 1, e1.size(), e1.dimension(), e1.dimension()}; } - template ::value && possible, bool> = true> + template () && possible, bool> = true> loop_sizes_t get_loop_sizes(const E1& e1, const E2& e2) { using shape_value_type = typename E1::shape_type::value_type; diff --git a/include/xtensor/core/xeval.hpp b/include/xtensor/core/xeval.hpp index 5ccbc1db9..f54987635 100644 --- a/include/xtensor/core/xeval.hpp +++ b/include/xtensor/core/xeval.hpp @@ -147,7 +147,7 @@ namespace xt */ template inline auto as_strided(E&& e) - -> std::enable_if_t>::value && detail::has_same_layout(), E&&> + -> std::enable_if_t>() && detail::has_same_layout(), E&&> { return std::forward(e); } @@ -155,8 +155,7 @@ namespace xt /// @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(), + (!(has_data_interface>() && detail::has_same_layout())) && detail::has_fixed_dims(), detail::as_xtensor_container_t> { return e; @@ -164,7 +163,7 @@ namespace xt template inline auto as_strided(E&& e) -> std::enable_if_t< - (!(has_data_interface>::value && detail::has_same_layout())) + (!(has_data_interface>() && detail::has_same_layout())) && (!detail::has_fixed_dims()), detail::as_xarray_container_t> { diff --git a/include/xtensor/core/xexpression.hpp b/include/xtensor/core/xexpression.hpp index 855c69706..75f4234d8 100644 --- a/include/xtensor/core/xexpression.hpp +++ b/include/xtensor/core/xexpression.hpp @@ -525,15 +525,16 @@ namespace xt using inner_shape_type = typename E::inner_shape_type; using shape_type = typename E::shape_type; - using strides_type = xtl::mpl:: - eval_if_t, detail::expr_strides_type, get_strides_type>; - using backstrides_type = xtl::mpl:: - eval_if_t, detail::expr_backstrides_type, get_strides_type>; - using inner_strides_type = xtl::mpl:: - eval_if_t, detail::expr_inner_strides_type, get_strides_type>; - using inner_backstrides_type = xtl::mpl:: - eval_if_t, detail::expr_inner_backstrides_type, get_strides_type>; - using storage_type = xtl::mpl::eval_if_t, detail::expr_storage_type, make_invalid_type<>>; + using strides_type = typename std:: + conditional_t(), detail::expr_strides_type, get_strides_type>::type; + using backstrides_type = typename std:: + conditional_t(), detail::expr_backstrides_type, get_strides_type>::type; + using inner_strides_type = typename std:: + conditional_t(), detail::expr_inner_strides_type, get_strides_type>::type; + using inner_backstrides_type = typename std:: + conditional_t(), detail::expr_inner_backstrides_type, get_strides_type>::type; + using storage_type = typename std:: + conditional_t(), detail::expr_storage_type, make_invalid_type<>>::type; using stepper = typename E::stepper; using const_stepper = typename E::const_stepper; @@ -638,43 +639,43 @@ namespace xt } template - std::enable_if_t::value, const inner_strides_type&> strides() const + std::enable_if_t(), const inner_strides_type&> strides() const { return m_ptr->strides(); } template - std::enable_if_t::value, const inner_strides_type&> backstrides() const + std::enable_if_t(), const inner_strides_type&> backstrides() const { return m_ptr->backstrides(); } template - std::enable_if_t::value, pointer> data() noexcept + std::enable_if_t(), pointer> data() noexcept { return m_ptr->data(); } template - std::enable_if_t::value, pointer> data() const noexcept + std::enable_if_t(), pointer> data() const noexcept { return m_ptr->data(); } template - std::enable_if_t::value, size_type> data_offset() const noexcept + std::enable_if_t(), size_type> data_offset() const noexcept { return m_ptr->data_offset(); } template - std::enable_if_t::value, typename T::storage_type&> storage() noexcept + std::enable_if_t(), typename T::storage_type&> storage() noexcept { return m_ptr->storage(); } template - std::enable_if_t::value, const typename T::storage_type&> storage() const noexcept + std::enable_if_t(), const typename T::storage_type&> storage() const noexcept { return m_ptr->storage(); } diff --git a/include/xtensor/core/xfunction.hpp b/include/xtensor/core/xfunction.hpp index 6459e998d..929f9dc77 100644 --- a/include/xtensor/core/xfunction.hpp +++ b/include/xtensor/core/xfunction.hpp @@ -133,7 +133,7 @@ namespace xt struct xcontainer_inner_types> { // Added indirection for MSVC 2017 bug with the operator value_type() - using func_return_type = typename meta_identity< + using func_return_type = typename std::type_identity< decltype(std::declval()(std::declval>>()...))>::type; using value_type = std::decay_t; using reference = func_return_type; @@ -156,7 +156,7 @@ namespace xt template struct overlapping_memory_checker_traits< E, - std::enable_if_t::value && is_specialization_of::value>> + std::enable_if_t() && is_specialization_of::value>> { template = 0> static bool check_tuple(const std::tuple&, const memory_range&) diff --git a/include/xtensor/core/xiterable.hpp b/include/xtensor/core/xiterable.hpp index 14d386207..1abdc1220 100644 --- a/include/xtensor/core/xiterable.hpp +++ b/include/xtensor/core/xiterable.hpp @@ -293,7 +293,7 @@ namespace xt }; template - using linear_iterator_traits = linear_iterator_traits_impl::value>; + using linear_iterator_traits = linear_iterator_traits_impl()>; } /** diff --git a/include/xtensor/core/xmath.hpp b/include/xtensor/core/xmath.hpp index 827e84219..16fe8bcc9 100644 --- a/include/xtensor/core/xmath.hpp +++ b/include/xtensor/core/xmath.hpp @@ -350,13 +350,13 @@ namespace xt namespace detail { template - std::enable_if_t::value, R> fill_init(T init) + std::enable_if_t(), R> fill_init(T init) { return R(init); } template - std::enable_if_t::value, R> fill_init(T init) + std::enable_if_t(), R> fill_init(T init) { R result; std::fill(std::begin(result), std::end(result), init); diff --git a/include/xtensor/core/xsemantic.hpp b/include/xtensor/core/xsemantic.hpp index bafad4aca..8a7bca37e 100644 --- a/include/xtensor/core/xsemantic.hpp +++ b/include/xtensor/core/xsemantic.hpp @@ -224,7 +224,7 @@ namespace xt template struct overlapping_memory_checker_traits< E, - std::enable_if_t::value && is_crtp_base_of::value>> + std::enable_if_t() && is_crtp_base_of::value>> { static bool check_overlap(const E& expr, const memory_range& dst_range) { diff --git a/include/xtensor/core/xshape.hpp b/include/xtensor/core/xshape.hpp index 6988e69f3..e395d6157 100644 --- a/include/xtensor/core/xshape.hpp +++ b/include/xtensor/core/xshape.hpp @@ -138,7 +138,7 @@ namespace xt * @param shape the shape to test * @return bool */ - template ::value>> + template ()>> inline bool has_shape(const E& e, const S& shape) { return e.shape().size() == shape.size() diff --git a/include/xtensor/misc/xmanipulation.hpp b/include/xtensor/misc/xmanipulation.hpp index e20095f3e..9272f4c7c 100644 --- a/include/xtensor/misc/xmanipulation.hpp +++ b/include/xtensor/misc/xmanipulation.hpp @@ -214,7 +214,7 @@ namespace xt template inline void compute_transposed_strides(E&& e, const S& shape, X& strides) { - if constexpr (has_data_interface>::value) + if constexpr (has_data_interface>()) { std::copy(e.strides().crbegin(), e.strides().crend(), strides.begin()); } diff --git a/include/xtensor/utils/xutils.hpp b/include/xtensor/utils/xutils.hpp index e93d8e688..ee302bde1 100644 --- a/include/xtensor/utils/xutils.hpp +++ b/include/xtensor/utils/xutils.hpp @@ -101,16 +101,6 @@ namespace xt template using disable_integral_t = std::enable_if_t::value, R>; - /******************************** - * meta identity implementation * - ********************************/ - - template - struct meta_identity - { - using type = T; - }; - /*************************************** * is_specialization_of implementation * ***************************************/ @@ -370,14 +360,16 @@ namespace xt res[i] = normalize_axis(expr.dimension(), axes[i]); } - XTENSOR_ASSERT(std::all_of( - res.begin(), - res.end(), - [&expr](auto ax_el) - { - return ax_el < expr.dimension(); - } - )); + XTENSOR_ASSERT( + std::all_of( + res.begin(), + res.end(), + [&expr](auto ax_el) + { + return ax_el < expr.dimension(); + } + ) + ); return res; } @@ -389,14 +381,16 @@ namespace xt normalize_axis(E& expr, C&& axes) { static_cast(expr); - XTENSOR_ASSERT(std::all_of( - axes.begin(), - axes.end(), - [&expr](auto ax_el) - { - return ax_el < expr.dimension(); - } - )); + XTENSOR_ASSERT( + std::all_of( + axes.begin(), + axes.end(), + [&expr](auto ax_el) + { + return ax_el < expr.dimension(); + } + ) + ); return std::forward(axes); } @@ -417,14 +411,16 @@ namespace xt } ); - XTENSOR_ASSERT(std::all_of( - res.begin(), - res.end(), - [&expr](auto ax_el) - { - return ax_el < expr.dimension(); - } - )); + XTENSOR_ASSERT( + std::all_of( + res.begin(), + res.end(), + [&expr](auto ax_el) + { + return ax_el < expr.dimension(); + } + ) + ); return res; } @@ -439,14 +435,16 @@ namespace xt R res; xt::resize_container(res, std::size(axes)); std::copy(std::begin(axes), std::end(axes), std::begin(res)); - XTENSOR_ASSERT(std::all_of( - res.begin(), - res.end(), - [&expr](auto ax_el) - { - return ax_el < expr.dimension(); - } - )); + XTENSOR_ASSERT( + std::all_of( + res.begin(), + res.end(), + [&expr](auto ax_el) + { + return ax_el < expr.dimension(); + } + ) + ); return res; } @@ -456,14 +454,16 @@ namespace xt R&&> { static_cast(expr); - XTENSOR_ASSERT(std::all_of( - std::begin(axes), - std::end(axes), - [&expr](auto ax_el) - { - return ax_el < expr.dimension(); - } - )); + XTENSOR_ASSERT( + std::all_of( + std::begin(axes), + std::end(axes), + [&expr](auto ax_el) + { + return ax_el < expr.dimension(); + } + ) + ); return std::move(axes); } @@ -471,20 +471,21 @@ namespace xt * get_value_type * ******************/ - template > - struct get_value_type - { - using type = T; - }; - template - struct get_value_type> + constexpr auto get_value_type() { - using type = typename T::value_type; - }; + if constexpr (requires { typename T::value_type; }) + { + return std::type_identity{}; + } + else + { + return std::type_identity{}; + } + } template - using get_value_type_t = typename get_value_type::type; + using get_value_type_t = typename decltype(get_value_type())::type; /********************** * get implementation * @@ -533,81 +534,70 @@ namespace xt * has_storage_type implementation * ***********************************/ - template - struct has_storage_type : std::false_type - { - }; - template struct xcontainer_inner_types; template - struct has_storage_type::storage_type>> - : std::negation< - std::is_same::storage_type>::type, invalid_type>> - { + concept has_storage_type_concept = requires { + typename xcontainer_inner_types::storage_type; + requires !std::is_same_v::storage_type>::type, invalid_type>; }; + template + constexpr bool has_storage_type() + { + return has_storage_type_concept; + } + /************************************* * has_data_interface implementation * *************************************/ - template - struct has_data_interface : std::false_type - { - }; - template - struct has_data_interface().data())>> : std::true_type - { - }; + concept has_data_interface_concept = requires { std::declval().data(); }; template - concept has_data_interface_concept = has_data_interface::value; - - template - struct has_strides : std::false_type + constexpr bool has_data_interface() { - }; + return has_data_interface_concept; + } template - struct has_strides().strides())>> : std::true_type - { - }; + concept has_strides_concept = requires { std::declval().strides(); }; - template - struct has_iterator_interface : std::false_type + template + constexpr bool has_strides() { - }; + return has_strides_concept; + } template - struct has_iterator_interface().begin())>> : std::true_type - { - }; + concept has_iterator_interface_concept = requires { std::declval().begin(); }; template - concept has_iterator_interface_concept = has_iterator_interface::value; + constexpr bool has_iterator_interface() + { + return has_iterator_interface_concept; + } /****************************** * is_iterator implementation * ******************************/ - template - struct is_iterator : std::false_type - { + template + concept iterator_concept = requires { + *std::declval(); + std::declval() == std::declval(); + std::declval() != std::declval(); + ++(*std::declval()); + (*std::declval())++; }; template - struct is_iterator< - E, - void_t< - decltype(*std::declval(), std::declval() == std::declval(), std::declval() != std::declval(), ++(*std::declval()), (*std::declval())++, std::true_type())>> - : std::true_type + constexpr bool is_iterator() { - }; - - template - concept iterator_concept = is_iterator::value; + return iterator_concept; + } /************************* * conditional type cast * @@ -739,38 +729,35 @@ namespace xt * has_assign_to * *****************/ - template - struct has_assign_to : std::false_type - { - }; + template + concept has_assign_to_concept = requires { std::declval().assign_to(std::declval()); }; template - struct has_assign_to().assign_to(std::declval()))>> - : std::true_type + constexpr bool has_assign_to() { - }; + return has_assign_to_concept; + } template - constexpr bool has_assign_to_v = has_assign_to::value; + constexpr bool has_assign_to_v = has_assign_to(); /************************************* * overlapping_memory_checker_traits * *************************************/ - template - struct has_memory_address : std::false_type - { - }; + template + concept has_memory_address_concept = requires { std::addressof(*std::declval().begin()); }; template - struct has_memory_address().begin()))>> : std::true_type + constexpr bool has_memory_address() { - }; + return has_memory_address_concept; + } template - concept with_memory_address_concept = has_memory_address>::value; + concept with_memory_address_concept = has_memory_address_concept>; template - concept without_memory_address_concept = !has_memory_address>::value; + concept without_memory_address_concept = !has_memory_address_concept>; struct memory_range { @@ -814,7 +801,7 @@ namespace xt }; template - struct overlapping_memory_checker_traits::value>> + struct overlapping_memory_checker_traits()>> { static bool check_overlap(const E& expr, const memory_range& dst_range) { @@ -864,23 +851,23 @@ namespace xt }; template - struct overlapping_memory_checker::value>> + struct overlapping_memory_checker()>> : overlapping_memory_checker_base { explicit overlapping_memory_checker(const Dst& aDst) : overlapping_memory_checker_base( - [&]() - { - if (aDst.size() == 0) - { - return memory_range(); - } - else - { - return memory_range(std::addressof(*aDst.begin()), std::addressof(*aDst.rbegin())); - } - }() - ) + [&]() + { + if (aDst.size() == 0) + { + return memory_range(); + } + else + { + return memory_range(std::addressof(*aDst.begin()), std::addressof(*aDst.rbegin())); + } + }() + ) { } }; @@ -918,102 +905,120 @@ namespace xt }; #endif - /******************** - * get_strides_type * - ********************/ + /*************** + * get_strides * + ***************/ - template - struct get_strides_type - { - using type = typename rebind_container::type; - }; + template + class xbuffer_adaptor; - template - struct get_strides_type> + namespace detail { - // TODO we could compute the strides statically here. - // But we'll need full constexpr support to have a - // homogenous ``compute_strides`` method - using type = std::array; - }; + template + inline constexpr bool is_fixed_shape_v = false; - template - class xbuffer_adaptor; + template + inline constexpr bool is_fixed_shape_v> = true; - template - struct get_strides_type> - { - // In bindings this mapping is called by reshape_view with an inner shape of type - // xbuffer_adaptor. - // Since we cannot create a buffer adaptor holding data, we map it to an std::vector. - using type = std::vector< - typename xbuffer_adaptor::value_type, - typename xbuffer_adaptor::allocator_type>; - }; + template + inline constexpr bool is_xbuffer_adaptor_v = false; + template + inline constexpr bool is_xbuffer_adaptor_v> = true; - template - using get_strides_t = typename get_strides_type::type; + template + concept fixed_shape_type = is_fixed_shape_v; + + template + concept xbuffer_adaptor_type = is_xbuffer_adaptor_v; + } + + template + constexpr auto get_strides() + { + if constexpr (detail::fixed_shape_type) + { + // TODO we could compute the strides statically here. + // But we'll need full constexpr support to have a + // homogenous ``compute_strides`` method + return std::type_identity>{}; + } + else if constexpr (detail::xbuffer_adaptor_type) + { + // In bindings this mapping is called by reshape_view with an inner shape of type + // xbuffer_adaptor. + // Since we cannot create a buffer adaptor holding data, we map it to an std::vector. + return std::type_identity>{}; + } + else + { + return std::type_identity::type>{}; + } + } + + template + using get_strides_t = typename decltype(get_strides())::type; + + // Lazy metafunction wrapper around ``get_strides``. Kept so callers can defer the mapping + // inside ``std::conditional_t::type``, where ``::type`` is only evaluated on the + // selected branch (see xshared_expression in xexpression.hpp). + template + struct get_strides_type + { + using type = get_strides_t; + }; /******************* * inner_reference * *******************/ - template - struct inner_reference + constexpr auto get_inner_reference() { using storage_type = std::decay_t; - using type = std::conditional_t< - std::is_const>::value, - typename storage_type::const_reference, - typename storage_type::reference>; - }; + if constexpr (std::is_const>::value) + { + return std::type_identity{}; + } + else + { + return std::type_identity{}; + } + } template - using inner_reference_t = typename inner_reference::type; + using inner_reference_t = typename decltype(get_inner_reference())::type; /************ * get_rank * ************/ - template - struct get_rank - { - static constexpr std::size_t value = SIZE_MAX; + // Define the requirement + template + concept HasRank = requires { + T::rank; // Checks if T::rank exists as a type nested member }; template - struct get_rank + constexpr std::size_t has_rank() { - static constexpr std::size_t value = E::rank; - }; - - /****************** - * has_fixed_rank * - ******************/ + return HasRank; + } template - struct has_fixed_rank + constexpr std::size_t get_rank() { - using type = std::integral_constant>::value != SIZE_MAX>; - }; + if constexpr (HasRank>) + { + return std::decay_t::rank; + } + return SIZE_MAX; + } template - using has_fixed_rank_t = typename has_fixed_rank>::type; - - /************ - * has_rank * - ************/ - - template - struct has_rank + constexpr std::size_t has_fixed_rank() { - using type = std::integral_constant>::value == N>; - }; - - template - using has_rank_t = typename has_rank, N>::type; - + return get_rank() != SIZE_MAX; + } } #endif diff --git a/include/xtensor/views/xdynamic_view.hpp b/include/xtensor/views/xdynamic_view.hpp index 5ab298f23..c100d2cae 100644 --- a/include/xtensor/views/xdynamic_view.hpp +++ b/include/xtensor/views/xdynamic_view.hpp @@ -50,9 +50,9 @@ namespace xt #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 8 static constexpr auto - random_instantiation_var_for_gcc8_data_iface = has_data_interface>::value; + random_instantiation_var_for_gcc8_data_iface = has_data_interface>(); static constexpr auto - random_instantiation_var_for_gcc8_has_strides = has_strides>::value; + random_instantiation_var_for_gcc8_has_strides = has_strides>(); #endif // TODO: implement efficient stepper specific to the dynamic_view diff --git a/include/xtensor/views/xfunctor_view.hpp b/include/xtensor/views/xfunctor_view.hpp index 1c76a91b5..8325d07e5 100644 --- a/include/xtensor/views/xfunctor_view.hpp +++ b/include/xtensor/views/xfunctor_view.hpp @@ -93,24 +93,24 @@ namespace xt using difference_type = typename xexpression_type::difference_type; using shape_type = typename xexpression_type::shape_type; - using strides_type = xtl::mpl::eval_if_t< - has_strides, + using strides_type = typename std::conditional_t< + has_strides(), detail::expr_strides_type, - get_strides_type>; - using backstrides_type = xtl::mpl::eval_if_t< - has_strides, + get_strides_type>::type; + using backstrides_type = typename std::conditional_t< + has_strides(), detail::expr_backstrides_type, - get_strides_type>; + get_strides_type>::type; using inner_shape_type = typename xexpression_type::inner_shape_type; - using inner_strides_type = xtl::mpl::eval_if_t< - has_strides, + using inner_strides_type = typename std::conditional_t< + has_strides(), detail::expr_inner_strides_type, - get_strides_type>; - using inner_backstrides_type = xtl::mpl::eval_if_t< - has_strides, + get_strides_type>::type; + using inner_backstrides_type = typename std::conditional_t< + has_strides(), detail::expr_inner_backstrides_type, - get_strides_type>; + get_strides_type>::type; using bool_load_type = xt::bool_load_type; diff --git a/include/xtensor/views/xrepeat.hpp b/include/xtensor/views/xrepeat.hpp index 0c119c9af..c43873c6c 100644 --- a/include/xtensor/views/xrepeat.hpp +++ b/include/xtensor/views/xrepeat.hpp @@ -64,10 +64,10 @@ namespace xt static constexpr bool is_const = std::is_const>::value; - using extract_storage_type = xtl::mpl::eval_if_t< - has_data_interface, + using extract_storage_type = typename std::conditional_t< + has_data_interface(), detail::expr_storage_type, - make_invalid_type<>>; + make_invalid_type<>>::type; using storage_type = std::conditional_t; }; diff --git a/include/xtensor/views/xstrided_view_base.hpp b/include/xtensor/views/xstrided_view_base.hpp index 28f233d87..0591f9eaa 100644 --- a/include/xtensor/views/xstrided_view_base.hpp +++ b/include/xtensor/views/xstrided_view_base.hpp @@ -87,7 +87,7 @@ namespace xt template struct provides_data_interface - : std::conjunction>, std::negation>> + : std::bool_constant>() && !is_flat_expression_adaptor::value> { }; } @@ -278,7 +278,7 @@ namespace xt template using flat_storage_getter = std::conditional_t< - has_data_interface>::value, + has_data_interface>(), inner_storage_getter, flat_adaptor_getter>; @@ -654,7 +654,7 @@ namespace xt template inline bool xstrided_view_base::has_linear_assign(const O& str) const noexcept { - return has_data_interface::value && str.size() == strides().size() + return has_data_interface() && str.size() == strides().size() && std::equal(str.cbegin(), str.cend(), strides().begin()); } diff --git a/include/xtensor/views/xview.hpp b/include/xtensor/views/xview.hpp index 025df0ae4..780836959 100644 --- a/include/xtensor/views/xview.hpp +++ b/include/xtensor/views/xview.hpp @@ -135,27 +135,26 @@ namespace xt : false; }; - template - struct is_strided_slice_impl : std::true_type - { - }; + template + inline constexpr bool is_strided_slice_impl = true; + template + inline constexpr bool is_strided_slice_impl> = false; + template + inline constexpr bool is_strided_slice_impl> = false; - template - struct is_strided_slice_impl> : std::false_type - { - }; + template + concept is_strided_slice_concept = is_strided_slice_impl; - template - struct is_strided_slice_impl> : std::false_type + template + constexpr bool is_strided_slice() { - }; + return (is_strided_slice_concept> && ...); + } // If we have no discontiguous slices, we can calculate strides for this view. template struct is_strided_view - : std::integral_constant< - bool, - std::conjunction, is_strided_slice_impl>...>::value> + : std::integral_constant() && is_strided_slice()> { }; @@ -228,7 +227,7 @@ namespace xt struct is_contiguous_view : std::integral_constant< bool, - has_data_interface::value + has_data_interface() && !( E::static_layout == layout_type::column_major && static_cast(static_dimension::value) != sizeof...(S) @@ -309,10 +308,10 @@ namespace xt static constexpr bool is_const = std::is_const>::value; - using extract_storage_type = xtl::mpl::eval_if_t< - has_data_interface, + using extract_storage_type = typename std::conditional_t< + has_data_interface(), detail::expr_storage_type, - make_invalid_type<>>; + make_invalid_type<>>::type; using storage_type = std::conditional_t; }; @@ -397,15 +396,15 @@ namespace xt using inner_shape_type = typename iterable_base::inner_shape_type; using shape_type = typename xview_shape_type::type; - using xexpression_inner_strides_type = xtl::mpl::eval_if_t< - has_strides, + using xexpression_inner_strides_type = typename std::conditional_t< + has_strides(), detail::expr_inner_strides_type, - get_strides_type>; + get_strides_type>::type; - using xexpression_inner_backstrides_type = xtl::mpl::eval_if_t< - has_strides, + using xexpression_inner_backstrides_type = typename std::conditional_t< + has_strides(), detail::expr_inner_backstrides_type, - get_strides_type>; + get_strides_type>::type; using storage_type = typename inner_types::storage_type; @@ -437,11 +436,11 @@ namespace xt using const_stepper = typename iterable_base::const_stepper; using linear_iterator = std::conditional_t< - has_data_interface::value && is_strided_view, + has_data_interface() && is_strided_view, std::conditional_t, typename iterable_base::linear_iterator>; using const_linear_iterator = std::conditional_t< - has_data_interface::value && is_strided_view, + has_data_interface() && is_strided_view, typename xexpression_type::const_linear_iterator, typename iterable_base::const_linear_iterator>; diff --git a/test/test_sfinae.cpp b/test/test_sfinae.cpp index f79277ac7..d2e8cc8ca 100644 --- a/test/test_sfinae.cpp +++ b/test/test_sfinae.cpp @@ -20,13 +20,13 @@ namespace xt { - template ::value, int> = 0> + template () != 2), int> = 0> inline size_t sfinae_rank_basic_func(E&&) { return 0; } - template ::value, int> = 0> + template () == 2), int> = 0> inline size_t sfinae_rank_basic_func(E&&) { return 2; @@ -50,19 +50,19 @@ namespace xt EXPECT_TRUE(sfinae_rank_basic_func(2ul * c) == 0ul); } - template ::value, int> = 0> + template () == SIZE_MAX), int> = 0> inline size_t sfinae_rank_func(E&&) { return 0; } - template ::value, int> = 0> + template () == 1), int> = 0> inline size_t sfinae_rank_func(E&&) { return 1; } - template ::value, int> = 0> + template () == 2), int> = 0> inline size_t sfinae_rank_func(E&&) { return 2; @@ -86,13 +86,13 @@ namespace xt EXPECT_TRUE(sfinae_rank_func(2ul * c) == 0ul); } - template ::value, int> = 0> + template (), int> = 0> inline bool sfinae_fixed_func(E&&) { return false; } - template ::value, int> = 0> + template (), int> = 0> inline bool sfinae_fixed_func(E&&) { return true; @@ -116,28 +116,17 @@ namespace xt EXPECT_TRUE(sfinae_fixed_func(2ul * c) == false); } - template - struct sfinae_get_rank - { - static const size_t rank = xt::get_rank::value; - - static size_t value() - { - return rank; - } - }; - TEST(sfinae, get_rank) { xt::xtensor A = xt::zeros({2}); xt::xtensor B = xt::zeros({2, 2}); xt::xarray C = xt::zeros({2, 2}); - EXPECT_TRUE(sfinae_get_rank::value() == 1ul); - EXPECT_TRUE(sfinae_get_rank::value() == 2ul); - EXPECT_TRUE(sfinae_get_rank::value() == SIZE_MAX); - EXPECT_TRUE(sfinae_get_rank::value() == SIZE_MAX); - EXPECT_TRUE(sfinae_get_rank::value() == SIZE_MAX); - EXPECT_TRUE(sfinae_get_rank::value() == SIZE_MAX); + static_assert(get_rank() == 1ul); + static_assert(get_rank() == 2ul); + static_assert(get_rank() == SIZE_MAX); + static_assert(get_rank() == SIZE_MAX); + static_assert(get_rank() == SIZE_MAX); + static_assert(get_rank() == SIZE_MAX); } } diff --git a/test/test_xeval.cpp b/test/test_xeval.cpp index f585bfd43..c788b325f 100644 --- a/test/test_xeval.cpp +++ b/test/test_xeval.cpp @@ -61,7 +61,7 @@ namespace xt #define EXPECT_LAYOUT(EXPRESSION, LAYOUT) EXPECT_TRUE((decltype(EXPRESSION)::static_layout == LAYOUT)) -#define HAS_DATA_INTERFACE(EXPRESSION) has_data_interface>::value +#define HAS_DATA_INTERFACE(EXPRESSION) has_data_interface>() #define EXPECT_XARRAY(EXPRESSION) \ EXPECT_TRUE(!detail::is_array::shape_type>::value) diff --git a/test/test_xutils.cpp b/test/test_xutils.cpp index e46a883c8..4fbf476a3 100644 --- a/test/test_xutils.cpp +++ b/test/test_xutils.cpp @@ -124,14 +124,10 @@ namespace xt TEST(utils, has_data_interface) { - bool b = has_data_interface>::value; - EXPECT_TRUE(b); - b = has_data_interface>::value; - EXPECT_TRUE(b); - b = has_data_interface>::value; - EXPECT_TRUE(b); - b = has_data_interface>>::value; - EXPECT_TRUE(b); + static_assert(has_data_interface_concept>); + static_assert(has_data_interface_concept>); + static_assert(has_data_interface_concept>); + static_assert(has_data_interface_concept>>); xarray a = xarray::from_shape({3, 4, 5}); auto f = a + a - 23; @@ -139,39 +135,27 @@ namespace xt auto vv2 = strided_view(v2, {all(), 2}); auto v3 = strided_view(f, {all(), 2}); - b = has_data_interface::value; - EXPECT_TRUE(b); - b = has_data_interface::value; - EXPECT_TRUE(b); - b = has_data_interface::value; - EXPECT_FALSE(b); + static_assert(has_data_interface_concept); + static_assert(has_data_interface_concept); + static_assert(!has_data_interface_concept); } TEST(utils, has_storage_type) { - bool b = has_storage_type>::value; - EXPECT_TRUE(b); + static_assert(has_storage_type>()); xarray x, y; - b = has_storage_type::value; - EXPECT_FALSE(b); - - b = has_storage_type::value; - EXPECT_TRUE(b); - b = has_storage_type::value; - EXPECT_FALSE(b); + static_assert(!has_storage_type()); + static_assert(has_storage_type()); + static_assert(!has_storage_type()); } TEST(utils, has_strides) { - bool b = has_strides>::value; - EXPECT_TRUE(b); - b = has_strides>::value; - EXPECT_TRUE(b); - b = has_strides>::value; - EXPECT_TRUE(b); - b = has_strides>>::value; - EXPECT_TRUE(b); + static_assert(has_strides>()); + static_assert(has_strides>()); + static_assert(has_strides>()); + static_assert(has_strides>>()); xarray a = xarray::from_shape({3, 4, 5}); auto f = a + a - 23; @@ -179,15 +163,12 @@ namespace xt auto vv2 = strided_view(v2, {all(), 2}); auto v3 = strided_view(f, {all(), 2}); - b = has_strides::value; - EXPECT_TRUE(b); - b = has_strides::value; - EXPECT_TRUE(b); + static_assert(has_strides()); + static_assert(has_strides()); #ifndef _MSC_VER // TODO fix this test for MSVC 2015! - b = has_strides::value; - EXPECT_TRUE(b); + static_assert(has_strides()); #endif }