1010#ifndef XTENSOR_SLICE_HPP
1111#define XTENSOR_SLICE_HPP
1212
13+ #include < concepts>
1314#include < cstddef>
1415#include < map>
1516#include < type_traits>
@@ -35,33 +36,73 @@ namespace xt
3536{
3637
3738 /* *********************
38- * xslice declaration *
39+ * xslice type traits *
3940 **********************/
4041
41- template <class D >
42- class xslice
42+ // Forward declarations
43+ template <class T >
44+ class xrange ;
45+
46+ template <class T >
47+ class xstepped_range ;
48+
49+ template <class T >
50+ class xall ;
51+
52+ template <class T >
53+ class xnewaxis ;
54+
55+ template <class T >
56+ class xkeep_slice ;
57+
58+ template <class T >
59+ class xdrop_slice ;
60+
61+ namespace detail
4362 {
44- public:
63+ template <class S >
64+ struct is_xslice_impl : std::false_type
65+ {
66+ };
67+
68+ template <class T >
69+ struct is_xslice_impl <xrange<T>> : std::true_type
70+ {
71+ };
4572
46- using derived_type = D;
73+ template <class T >
74+ struct is_xslice_impl <xstepped_range<T>> : std::true_type
75+ {
76+ };
4777
48- derived_type& derived_cast () noexcept ;
49- const derived_type& derived_cast () const noexcept ;
78+ template <class T >
79+ struct is_xslice_impl <xall<T>> : std::true_type
80+ {
81+ };
5082
51- protected:
83+ template <class T >
84+ struct is_xslice_impl <xnewaxis<T>> : std::true_type
85+ {
86+ };
5287
53- xslice () = default ;
54- ~xslice () = default ;
88+ template <class T >
89+ struct is_xslice_impl <xkeep_slice<T>> : std::true_type
90+ {
91+ };
5592
56- xslice (const xslice&) = default ;
57- xslice& operator =(const xslice&) = default ;
93+ template <class T >
94+ struct is_xslice_impl <xdrop_slice<T>> : std::true_type
95+ {
96+ };
97+ }
5898
59- xslice (xslice&&) = default ;
60- xslice& operator =(xslice&&) = default ;
99+ template <class S >
100+ struct is_xslice : detail::is_xslice_impl<S>
101+ {
61102 };
62103
63104 template <class S >
64- using is_xslice = std::is_base_of<xslice<S>, S> ;
105+ concept xslice_concept = is_xslice<S>::value ;
65106
66107 template <class ... E>
67108 using has_xslice = std::disjunction<is_xslice<E>...>;
@@ -99,7 +140,7 @@ namespace xt
99140 **********************/
100141
101142 template <class T >
102- class xrange : public xslice <xrange<T>>
143+ class xrange
103144 {
104145 public:
105146
@@ -143,7 +184,7 @@ namespace xt
143184 ******************************/
144185
145186 template <class T >
146- class xstepped_range : public xslice <xstepped_range<T>>
187+ class xstepped_range
147188 {
148189 public:
149190
@@ -188,7 +229,7 @@ namespace xt
188229 ********************/
189230
190231 template <class T >
191- class xall : public xslice <xall<T>>
232+ class xall
192233 {
193234 public:
194235
@@ -259,7 +300,7 @@ namespace xt
259300 ************************/
260301
261302 template <class T >
262- class xnewaxis : public xslice <xnewaxis<T>>
303+ class xnewaxis
263304 {
264305 public:
265306
@@ -320,7 +361,7 @@ namespace xt
320361 }
321362
322363 template <class T >
323- class xkeep_slice : public xslice <xkeep_slice<T>>
364+ class xkeep_slice
324365 {
325366 public:
326367
@@ -428,7 +469,7 @@ namespace xt
428469 }
429470
430471 template <class T >
431- class xdrop_slice : public xslice <xdrop_slice<T>>
472+ class xdrop_slice
432473 {
433474 public:
434475
@@ -778,14 +819,11 @@ namespace xt
778819 template <class S >
779820 inline std::size_t get_size (const S& slice) noexcept
780821 {
781- if constexpr (is_xslice <S>::value )
822+ if constexpr (xslice_concept <S>)
782823 {
783824 return slice.size ();
784825 }
785- else
786- {
787- return 1 ;
788- }
826+ return 1 ;
789827 }
790828
791829 /* ******************************************************
@@ -795,37 +833,31 @@ namespace xt
795833 template <class S >
796834 inline std::size_t step_size (const S& slice, std::size_t idx) noexcept
797835 {
798- if constexpr (is_xslice <S>::value )
836+ if constexpr (xslice_concept <S>)
799837 {
800838 return slice.step_size (idx);
801839 }
802- else
803- {
804- return 0 ;
805- }
840+ return 0 ;
806841 }
807842
808843 template <class S >
809844 inline std::size_t step_size (const S& slice, std::size_t idx, std::size_t n) noexcept
810845 {
811- if constexpr (is_xslice <S>::value )
846+ if constexpr (xslice_concept <S>)
812847 {
813848 return slice.step_size (idx, n);
814849 }
815- else
816- {
817- return 0 ;
818- }
850+ return 0 ;
819851 }
820852
821853 /* ********************************************
822854 * homogeneous value for integral and slices *
823855 *********************************************/
824856
825857 template <class S , class I >
826- inline std:: size_t value (const S& slice, I i) noexcept
858+ inline auto value (const S& slice, I i) noexcept
827859 {
828- if constexpr (is_xslice <S>::value )
860+ if constexpr (xslice_concept <S>)
829861 {
830862 using ST = typename S::size_type;
831863 return slice (static_cast <ST>(i));
@@ -966,22 +998,6 @@ namespace xt
966998 template <class E , class SL >
967999 using get_slice_type = typename detail::get_slice_type_impl<E, std::remove_reference_t <SL>>::type;
9681000
969- /* ************************
970- * xslice implementation *
971- *************************/
972-
973- template <class D >
974- inline auto xslice<D>::derived_cast() noexcept -> derived_type&
975- {
976- return *static_cast <derived_type*>(this );
977- }
978-
979- template <class D >
980- inline auto xslice<D>::derived_cast() const noexcept -> const derived_type&
981- {
982- return *static_cast <const derived_type*>(this );
983- }
984-
9851001 /* ************************
9861002 * xrange implementation *
9871003 *************************/
0 commit comments