diff --git a/include/xtensor/misc/xtl_concepts.hpp b/include/xtensor/misc/xtl_concepts.hpp index 163139812..22ef7b212 100644 --- a/include/xtensor/misc/xtl_concepts.hpp +++ b/include/xtensor/misc/xtl_concepts.hpp @@ -17,10 +17,15 @@ namespace xtl { template concept integral_concept = xtl::is_integral::value; + template concept non_integral_concept = !xtl::is_integral::value; + template concept complex_concept = xtl::is_complex::type::value_type>::value; + + template + concept pointer_concept = std::is_pointer::value; } #endif // XTENSOR_CONCEPTS_HPP diff --git a/include/xtensor/views/xaxis_iterator.hpp b/include/xtensor/views/xaxis_iterator.hpp index 62489b08f..41da6822f 100644 --- a/include/xtensor/views/xaxis_iterator.hpp +++ b/include/xtensor/views/xaxis_iterator.hpp @@ -68,10 +68,7 @@ namespace xt value_type m_sv; template - std::enable_if_t::value, T> get_storage_init(CTA&& e) const; - - template - std::enable_if_t::value, T> get_storage_init(CTA&& e) const; + T get_storage_init(CTA&& e) const; }; template @@ -125,16 +122,16 @@ namespace xt template template - inline std::enable_if_t::value, T> xaxis_iterator::get_storage_init(CTA&& e) const + inline T xaxis_iterator::get_storage_init(CTA&& e) const { - return &e; - } - - template - template - inline std::enable_if_t::value, T> xaxis_iterator::get_storage_init(CTA&& e) const - { - return e; + if constexpr (xtl::pointer_concept) + { + return &e; + } + else + { + return e; + } } /** diff --git a/include/xtensor/views/xaxis_slice_iterator.hpp b/include/xtensor/views/xaxis_slice_iterator.hpp index 108955595..6ee904df9 100644 --- a/include/xtensor/views/xaxis_slice_iterator.hpp +++ b/include/xtensor/views/xaxis_slice_iterator.hpp @@ -69,10 +69,7 @@ namespace xt value_type m_sv; template - std::enable_if_t::value, T> get_storage_init(CTA&& e) const; - - template - std::enable_if_t::value, T> get_storage_init(CTA&& e) const; + T get_storage_init(CTA&& e) const; }; template @@ -99,18 +96,16 @@ namespace xt template template - inline std::enable_if_t::value, T> - xaxis_slice_iterator::get_storage_init(CTA&& e) const - { - return &e; - } - - template - template - inline std::enable_if_t::value, T> - xaxis_slice_iterator::get_storage_init(CTA&& e) const + T xaxis_slice_iterator::get_storage_init(CTA&& e) const { - return e; + if constexpr (xtl::pointer_concept) + { + return &e; + } + else + { + return e; + } } /** diff --git a/include/xtensor/views/xbroadcast.hpp b/include/xtensor/views/xbroadcast.hpp index 412c81fce..1626faaa3 100644 --- a/include/xtensor/views/xbroadcast.hpp +++ b/include/xtensor/views/xbroadcast.hpp @@ -72,6 +72,9 @@ namespace xt template class xbroadcast; + template + concept xbroadcast_concept = is_specialization_of::value; + template struct xiterable_inner_types> { @@ -122,10 +125,9 @@ namespace xt * overlapping_memory_checker_traits * *************************************/ - template - struct overlapping_memory_checker_traits< - E, - std::enable_if_t::value && is_specialization_of::value>> + template + requires(without_memory_address_concept) + struct overlapping_memory_checker_traits { static bool check_overlap(const E& expr, const memory_range& dst_range) { @@ -223,7 +225,7 @@ namespace xt template const_stepper stepper_end(const S& shape, layout_type l) const noexcept; - template ::value>> + template void assign_to(xexpression& e) const; template @@ -463,7 +465,7 @@ namespace xt } template - template + template inline void xbroadcast::assign_to(xexpression& e) const { auto& ed = e.derived_cast(); diff --git a/include/xtensor/views/xoffset_view.hpp b/include/xtensor/views/xoffset_view.hpp index db94e4061..6c8792aa1 100644 --- a/include/xtensor/views/xoffset_view.hpp +++ b/include/xtensor/views/xoffset_view.hpp @@ -38,16 +38,9 @@ namespace xt return xtl::forward_offset(std::forward(t)); } - template < - class align, - class requested_type, - std::size_t N, - class E, - class MF = M, - class = std::enable_if_t< - (std::is_same::value || std::is_same::value) && I <= sizeof(MF), - int>> + template auto proxy_simd_load(const E& expr, std::size_t n) const + requires((std::is_same::value || std::is_same::value) && I <= sizeof(MF)) { // TODO refactor using shuffle only auto batch = expr.template load_simd(n); @@ -61,15 +54,9 @@ namespace xt } } - template < - class align, - class simd, - class E, - class MF = M, - class = std::enable_if_t< - (std::is_same::value || std::is_same::value) && I <= sizeof(MF), - int>> + template auto proxy_simd_store(E& expr, std::size_t n, const simd& batch) const + requires((std::is_same::value || std::is_same::value) && I <= sizeof(MF)) { auto x = expr.template load_simd(n); if (I == 0) diff --git a/include/xtensor/views/xslice.hpp b/include/xtensor/views/xslice.hpp index 4faa17cca..b9d960196 100644 --- a/include/xtensor/views/xslice.hpp +++ b/include/xtensor/views/xslice.hpp @@ -63,9 +63,6 @@ namespace xt template using is_xslice = std::is_base_of, S>; - template - using disable_xslice = typename std::enable_if::value, R>::type; - template using has_xslice = std::disjunction...>; @@ -112,12 +109,12 @@ namespace xt xrange() = default; xrange(size_type start_val, size_type stop_val) noexcept; - template ::value, void>> + template S> operator xrange() const noexcept; // Same as implicit conversion operator but more convenient to call // from a variant visitor - template ::value, void>> + template S> xrange convert() const noexcept; size_type operator()(size_type i) const noexcept; @@ -156,12 +153,12 @@ namespace xt xstepped_range() = default; xstepped_range(size_type start_val, size_type stop_val, size_type step) noexcept; - template ::value, void>> + template S> operator xstepped_range() const noexcept; // Same as implicit conversion operator but more convenient to call // from a variant visitor - template ::value, void>> + template S> xstepped_range convert() const noexcept; size_type operator()(size_type i) const noexcept; @@ -201,12 +198,12 @@ namespace xt xall() = default; explicit xall(size_type size) noexcept; - template ::value, void>> + template S> operator xall() const noexcept; // Same as implicit conversion operator but more convenient to call // from a variant visitor - template ::value, void>> + template S> xall convert() const noexcept; size_type operator()(size_type i) const noexcept; @@ -271,12 +268,12 @@ namespace xt xnewaxis() = default; - template ::value, void>> + template S> operator xnewaxis() const noexcept; // Same as implicit conversion operator but more convenient to call // from a variant visitor - template ::value, void>> + template S> xnewaxis convert() const noexcept; size_type operator()(size_type i) const noexcept; @@ -320,12 +317,6 @@ namespace xt struct is_xkeep_slice> : std::true_type { }; - - template - using disable_xkeep_slice_t = std::enable_if_t>::value, void>; - - template - using enable_xkeep_slice_t = std::enable_if_t>::value, void>; } template @@ -337,19 +328,20 @@ namespace xt using size_type = typename container_type::value_type; using self_type = xkeep_slice; - template > - explicit xkeep_slice(C& cont); + template + explicit xkeep_slice(C& cont) + requires(!detail::is_xkeep_slice>::value); explicit xkeep_slice(container_type&& cont); template xkeep_slice(std::initializer_list t); - template ::value, void>> + template S> operator xkeep_slice() const noexcept; // Same as implicit conversion operator but more convenient to call // from a variant visitor - template ::value, void>> + template S> xkeep_slice convert() const noexcept; size_type operator()(size_type i) const noexcept; @@ -376,17 +368,6 @@ namespace xt friend class xkeep_slice; }; - namespace detail - { - template - using disable_integral_keep = std::enable_if_t< - !xtl::is_integral>::value, - xkeep_slice::value_type>>; - - template - using enable_integral_keep = std::enable_if_t::value, xkeep_slice>; - } - /** * Create a non-contigous slice from a container of indices to keep. * Note: this slice cannot be used in the xstrided_view! @@ -401,19 +382,20 @@ namespace xt * @param indices The indices container * @return instance of xkeep_slice */ - template - inline detail::disable_integral_keep keep(T&& indices) - { - return xkeep_slice::value_type>(std::forward(indices)); - } - template - inline detail::enable_integral_keep keep(T i) + inline auto keep(T&& indices) { - using slice_type = xkeep_slice; - using container_type = typename slice_type::container_type; - container_type tmp = {static_cast(i)}; - return slice_type(std::move(tmp)); + if constexpr (xtl::is_integral>::value) + { + using slice_type = xkeep_slice; + using container_type = typename slice_type::container_type; + container_type tmp = {static_cast(std::forward(indices))}; + return slice_type(std::move(tmp)); + } + else + { + return xkeep_slice::value_type>(std::forward(indices)); + } } template @@ -443,12 +425,6 @@ namespace xt struct is_xdrop_slice> : std::true_type { }; - - template - using disable_xdrop_slice_t = std::enable_if_t>::value, void>; - - template - using enable_xdrop_slice_t = std::enable_if_t>::value, void>; } template @@ -460,19 +436,20 @@ namespace xt using size_type = typename container_type::value_type; using self_type = xdrop_slice; - template > - explicit xdrop_slice(C& cont); + template + explicit xdrop_slice(C& cont) + requires(!detail::is_xdrop_slice>::value); explicit xdrop_slice(container_type&& cont); template xdrop_slice(std::initializer_list t); - template ::value, void>> + template S> operator xdrop_slice() const noexcept; // Same as implicit conversion operator but more convenient to call // from a variant visitor - template ::value, void>> + template S> xdrop_slice convert() const noexcept; size_type operator()(size_type i) const noexcept; @@ -501,17 +478,6 @@ namespace xt friend class xdrop_slice; }; - namespace detail - { - template - using disable_integral_drop = std::enable_if_t< - !xtl::is_integral>::value, - xdrop_slice::value_type>>; - - template - using enable_integral_drop = std::enable_if_t::value, xdrop_slice>; - } - /** * Create a non-contigous slice from a container of indices to drop. * Note: this slice cannot be used in the xstrided_view! @@ -525,19 +491,20 @@ namespace xt * @param indices The container of indices to drop * @return instance of xdrop_slice */ - template - inline detail::disable_integral_drop drop(T&& indices) - { - return xdrop_slice::value_type>(std::forward(indices)); - } - template - inline detail::enable_integral_drop drop(T i) + inline auto drop(T&& indices) { - using slice_type = xdrop_slice; - using container_type = typename slice_type::container_type; - container_type tmp = {static_cast(i)}; - return slice_type(std::move(tmp)); + if constexpr (xtl::is_integral::value) + { + using slice_type = xdrop_slice; + using container_type = typename slice_type::container_type; + container_type tmp = {static_cast(std::forward(indices))}; + return slice_type(std::move(tmp)); + } + else + { + return xdrop_slice::value_type>(std::forward(indices)); + } } template @@ -564,78 +531,48 @@ namespace xt } template - inline std::enable_if_t< - xtl::is_integral::value && xtl::is_integral::value && xtl::is_integral::value, - xstepped_range> - get(std::size_t size) const - { - return get_stepped_range(m_start, m_stop, m_step, size); - } - - template - inline std::enable_if_t< - !xtl::is_integral::value && xtl::is_integral::value && xtl::is_integral::value, - xstepped_range> - get(std::size_t size) const - { - return get_stepped_range(m_step > 0 ? 0 : static_cast(size) - 1, m_stop, m_step, size); - } - - template - inline std::enable_if_t< - xtl::is_integral::value && !xtl::is_integral::value && xtl::is_integral::value, - xstepped_range> - get(std::size_t size) const - { - auto sz = static_cast(size); - return get_stepped_range(m_start, m_step > 0 ? sz : -(sz + 1), m_step, size); - } - - template - inline std::enable_if_t< - xtl::is_integral::value && xtl::is_integral::value && !xtl::is_integral::value, - xrange> - get(std::size_t size) const - { - return xrange(normalize(m_start, size), normalize(m_stop, size)); - } - - template - inline std::enable_if_t< - !xtl::is_integral::value && !xtl::is_integral::value && xtl::is_integral::value, - xstepped_range> - get(std::size_t size) const - { - std::ptrdiff_t start = m_step >= 0 ? 0 : static_cast(size) - 1; - std::ptrdiff_t stop = m_step >= 0 ? static_cast(size) : -1; - return xstepped_range(start, stop, m_step); - } - - template - inline std::enable_if_t< - xtl::is_integral::value && !xtl::is_integral::value && !xtl::is_integral::value, - xrange> - get(std::size_t size) const - { - return xrange(normalize(m_start, size), static_cast(size)); - } - - template - inline std::enable_if_t< - !xtl::is_integral::value && xtl::is_integral::value && !xtl::is_integral::value, - xrange> - get(std::size_t size) const - { - return xrange(0, normalize(m_stop, size)); - } - - template - inline std::enable_if_t< - !xtl::is_integral::value && !xtl::is_integral::value && !xtl::is_integral::value, - xall> - get(std::size_t size) const + auto get(std::size_t size) const { - return xall(static_cast(size)); + if constexpr (xtl::is_integral::value && xtl::is_integral::value && xtl::is_integral::value) + { + return get_stepped_range(m_start, m_stop, m_step, size); + } + else if constexpr (!xtl::is_integral::value && xtl::is_integral::value && xtl::is_integral::value) + { + return get_stepped_range( + m_step > 0 ? 0 : static_cast(size) - 1, + m_stop, + m_step, + size + ); + } + else if constexpr (xtl::is_integral::value && !xtl::is_integral::value && xtl::is_integral::value) + { + auto sz = static_cast(size); + return get_stepped_range(m_start, m_step > 0 ? sz : -(sz + 1), m_step, size); + } + else if constexpr (xtl::is_integral::value && xtl::is_integral::value && !xtl::is_integral::value) + { + return xrange(normalize(m_start, size), normalize(m_stop, size)); + } + else if constexpr (!xtl::is_integral::value && !xtl::is_integral::value && xtl::is_integral::value) + { + std::ptrdiff_t start = m_step >= 0 ? 0 : static_cast(size) - 1; + std::ptrdiff_t stop = m_step >= 0 ? static_cast(size) : -1; + return xstepped_range(start, stop, m_step); + } + else if constexpr (xtl::is_integral::value && !xtl::is_integral::value && !xtl::is_integral::value) + { + return xrange(normalize(m_start, size), static_cast(size)); + } + else if constexpr (!xtl::is_integral::value && xtl::is_integral::value && !xtl::is_integral::value) + { + return xrange(0, normalize(m_stop, size)); + } + else if constexpr (!xtl::is_integral::value && !xtl::is_integral::value && !xtl::is_integral::value) + { + return xall(static_cast(size)); + } } A start() const @@ -774,25 +711,14 @@ namespace xt namespace detail { - template - struct cast_if_integer - { - using type = T; - - type operator()(T t) - { - return t; - } - }; - template - struct cast_if_integer::value>> + struct cast_if_integer { - using type = std::ptrdiff_t; + using type = std::conditional_t::value, std::ptrdiff_t, T>; type operator()(T t) { - return static_cast(t); + return (xtl::is_integral::value) ? static_cast(t) : t; } }; @@ -850,15 +776,16 @@ namespace xt ******************************************************/ template - inline disable_xslice get_size(const S&) noexcept - { - return 1; - } - - template - inline auto get_size(const xslice& slice) noexcept + inline std::size_t get_size(const S& slice) noexcept { - return slice.derived_cast().size(); + if constexpr (is_xslice::value) + { + return slice.size(); + } + else + { + return 1; + } } /******************************************************* @@ -866,27 +793,29 @@ namespace xt *******************************************************/ template - inline disable_xslice step_size(const S&, std::size_t) noexcept - { - return 0; - } - - template - inline disable_xslice step_size(const S&, std::size_t, std::size_t) noexcept + inline std::size_t step_size(const S& slice, std::size_t idx) noexcept { - return 0; - } - - template - inline auto step_size(const xslice& slice, std::size_t idx) noexcept - { - return slice.derived_cast().step_size(idx); + if constexpr (is_xslice::value) + { + return slice.step_size(idx); + } + else + { + return 0; + } } template - inline auto step_size(const xslice& slice, std::size_t idx, std::size_t n) noexcept + inline std::size_t step_size(const S& slice, std::size_t idx, std::size_t n) noexcept { - return slice.derived_cast().step_size(idx, n); + if constexpr (is_xslice::value) + { + return slice.step_size(idx, n); + } + else + { + return 0; + } } /********************************************* @@ -894,16 +823,17 @@ namespace xt *********************************************/ template - inline disable_xslice value(const S& s, I) noexcept + inline std::size_t value(const S& slice, I i) noexcept { - return static_cast(s); - } - - template - inline auto value(const xslice& slice, I i) noexcept - { - using ST = typename S::size_type; - return slice.derived_cast()(static_cast(i)); + if constexpr (is_xslice::value) + { + using ST = typename S::size_type; + return slice(static_cast(i)); + } + else + { + return static_cast(slice); + } } /**************************************** @@ -1064,7 +994,7 @@ namespace xt } template - template + template S> inline xrange::operator xrange() const noexcept { xrange ret; @@ -1074,7 +1004,7 @@ namespace xt } template - template + template S> inline xrange xrange::convert() const noexcept { return xrange(*this); @@ -1143,7 +1073,7 @@ namespace xt } template - template + template S> inline xstepped_range::operator xstepped_range() const noexcept { xstepped_range ret; @@ -1154,7 +1084,7 @@ namespace xt } template - template + template S> inline xstepped_range xstepped_range::convert() const noexcept { return xstepped_range(*this); @@ -1219,14 +1149,14 @@ namespace xt } template - template + template S> inline xall::operator xall() const noexcept { return xall(static_cast(m_size)); } template - template + template S> inline xall xall::convert() const noexcept { return xall(*this); @@ -1285,14 +1215,14 @@ namespace xt ***************************/ template - template + template S> inline xnewaxis::operator xnewaxis() const noexcept { return xnewaxis(); } template - template + template S> inline xnewaxis xnewaxis::convert() const noexcept { return xnewaxis(*this); @@ -1351,8 +1281,9 @@ namespace xt ******************************/ template - template + template inline xkeep_slice::xkeep_slice(C& cont) + requires(!detail::is_xkeep_slice>::value) : m_raw_indices(cont.begin(), cont.end()) { } @@ -1380,7 +1311,7 @@ namespace xt } template - template + template S> inline xkeep_slice::operator xkeep_slice() const noexcept { xkeep_slice ret; @@ -1410,7 +1341,7 @@ namespace xt } template - template + template S> inline xkeep_slice xkeep_slice::convert() const noexcept { return xkeep_slice(*this); @@ -1494,8 +1425,9 @@ namespace xt ******************************/ template - template + template inline xdrop_slice::xdrop_slice(C& cont) + requires(!detail::is_xdrop_slice>::value) : m_raw_indices(cont.begin(), cont.end()) { } @@ -1523,7 +1455,7 @@ namespace xt } template - template + template S> inline xdrop_slice::operator xdrop_slice() const noexcept { xdrop_slice ret; @@ -1561,7 +1493,7 @@ namespace xt } template - template + template S> inline xdrop_slice xdrop_slice::convert() const noexcept { return xdrop_slice(*this); diff --git a/include/xtensor/views/xstrided_view.hpp b/include/xtensor/views/xstrided_view.hpp index b52da8e30..f0fda4214 100644 --- a/include/xtensor/views/xstrided_view.hpp +++ b/include/xtensor/views/xstrided_view.hpp @@ -180,6 +180,9 @@ namespace xt using simd_value_type = xt_simd::simd_type; using bool_load_type = typename base_type::bool_load_type; + static constexpr bool provides_simd_interface = has_simd_interface::value + && L != layout_type::dynamic; + template xstrided_view(CTA&& e, SA&& shape, strides_type&& strides, std::size_t offset, layout_type layout) noexcept; @@ -254,17 +257,13 @@ namespace xt template using simd_return_type = xt_simd::simd_return_type; - template - using enable_simd_interface = std::enable_if_t::value && L != layout_type::dynamic, R>; + template + void store_simd(size_type i, const simd& e) + requires provides_simd_interface; - template - enable_simd_interface store_simd(size_type i, const simd& e); - template < - class align, - class requested_type = value_type, - std::size_t N = xt_simd::simd_traits::size, - class T = xexpression_type> - enable_simd_interface> load_simd(size_type i) const; + template ::size> + simd_return_type load_simd(size_type i) const + requires provides_simd_interface; reference data_element(size_type i); const_reference data_element(size_type i) const; @@ -672,18 +671,18 @@ namespace xt } template - template - inline auto xstrided_view::store_simd(size_type i, const simd& e) - -> enable_simd_interface + template + inline void xstrided_view::store_simd(size_type i, const simd& e) + requires provides_simd_interface { using align_mode = driven_align_mode_t; xt_simd::store_as(&(storage()[i]), e, align_mode()); } template - template - inline auto xstrided_view::load_simd(size_type i) const - -> enable_simd_interface> + template + inline auto xstrided_view::load_simd(size_type i) const -> simd_return_type + requires provides_simd_interface { using align_mode = driven_align_mode_t; return xt_simd::load_as(&(storage()[i]), align_mode()); @@ -824,29 +823,23 @@ namespace xt using type = rebind_container_t; }; - template < - class S, - std::enable_if_t::type>>::value, bool> = true> + template inline void recalculate_shape_impl(S& shape, size_t size) { - using value_type = get_value_type_t>; - XTENSOR_ASSERT(std::count(shape.cbegin(), shape.cend(), -1) <= 1); - auto iter = std::find(shape.begin(), shape.end(), -1); - if (iter != std::end(shape)) + if constexpr (std::is_signed_v::type>>) { - const auto total = std::accumulate(shape.cbegin(), shape.cend(), -1, std::multiplies{}); - const auto missing_dimension = size / total; - (*iter) = static_cast(missing_dimension); + using value_type = get_value_type_t>; + XTENSOR_ASSERT(std::count(shape.cbegin(), shape.cend(), -1) <= 1); + auto iter = std::find(shape.begin(), shape.end(), -1); + if (iter != std::end(shape)) + { + const auto total = std::accumulate(shape.cbegin(), shape.cend(), -1, std::multiplies{}); + const auto missing_dimension = size / total; + (*iter) = static_cast(missing_dimension); + } } } - template < - class S, - std::enable_if_t::type>>::value, bool> = true> - inline void recalculate_shape_impl(S&, size_t) - { - } - template inline auto recalculate_shape(S&& shape, size_t size) { diff --git a/include/xtensor/views/xstrided_view_base.hpp b/include/xtensor/views/xstrided_view_base.hpp index be67ee191..28f233d87 100644 --- a/include/xtensor/views/xstrided_view_base.hpp +++ b/include/xtensor/views/xstrided_view_base.hpp @@ -133,6 +133,9 @@ namespace xt static constexpr bool contiguous_layout = static_layout != layout_type::dynamic && xexpression_type::contiguous_layout; + static constexpr bool + provides_data_interface = detail::provides_data_interface::value; + template xstrided_view_base(CTA&& e, SA&& shape, strides_type&& strides, size_type offset, layout_type layout) noexcept; @@ -171,10 +174,11 @@ namespace xt storage_type& storage() noexcept; const storage_type& storage() const noexcept; - template - std::enable_if_t::value, pointer> data() noexcept; - template - std::enable_if_t::value, const_pointer> data() const noexcept; + pointer data() noexcept + requires(provides_data_interface); + const_pointer data() const noexcept + requires(provides_data_interface); + size_type data_offset() const noexcept; xexpression_type& expression() noexcept; @@ -578,9 +582,8 @@ namespace xt * The first element of the view is at data() + data_offset(). */ template - template - inline auto xstrided_view_base::data() noexcept - -> std::enable_if_t::value, pointer> + inline auto xstrided_view_base::data() noexcept -> pointer + requires(provides_data_interface) { return m_e.data(); } @@ -590,9 +593,8 @@ namespace xt * The first element of the view is at data() + data_offset(). */ template - template - inline auto xstrided_view_base::data() const noexcept - -> std::enable_if_t::value, const_pointer> + inline auto xstrided_view_base::data() const noexcept -> const_pointer + requires(provides_data_interface) { return m_e.data(); } diff --git a/include/xtensor/views/xview.hpp b/include/xtensor/views/xview.hpp index be4c05e1a..ea546d4ff 100644 --- a/include/xtensor/views/xview.hpp +++ b/include/xtensor/views/xview.hpp @@ -720,7 +720,8 @@ namespace xt size_type sliced_access(const xslice& slice, Arg arg, Args... args) const; template ::size_type I, class T, class... Args> - disable_xslice sliced_access(const T& squeeze, Args...) const; + size_type sliced_access(const T& squeeze, Args...) const + requires(!is_xslice::value); using base_index_type = xindex_type_t; @@ -1674,7 +1675,8 @@ namespace xt template template ::size_type I, class T, class... Args> - inline auto xview::sliced_access(const T& squeeze, Args...) const -> disable_xslice + inline auto xview::sliced_access(const T& squeeze, Args...) const -> size_type + requires(!is_xslice::value) { return static_cast(squeeze); } diff --git a/include/xtensor/views/xview_utils.hpp b/include/xtensor/views/xview_utils.hpp index 5c072dbf0..f74eb07e2 100644 --- a/include/xtensor/views/xview_utils.hpp +++ b/include/xtensor/views/xview_utils.hpp @@ -48,15 +48,16 @@ namespace xt constexpr std::size_t newaxis_skip(std::size_t i); template - inline disable_xslice get_slice_value(const S& s, It&) noexcept + inline auto get_slice_value(const S& slice, It& it) noexcept { - return static_cast(s); - } - - template - inline auto get_slice_value(const xslice& slice, It& it) noexcept - { - return slice.derived_cast()(typename S::size_type(*it)); + if constexpr (is_xslice::value) + { + return slice(typename S::size_type(*it)); + } + else + { + return static_cast(slice); + } } /***********************