28 concept tag = impl::tag_traits<T>::is_tag;
43 using selector =
typename impl::tag_traits<T>::selector;
46 template<
typename T1,
typename T2>
47 concept same_selector = std::same_as< selector<T1>,
selector<T2>>;
56 static constexpr bool is_tag =
true;
57 static constexpr bool is_direct =
false;
58 using core =
typename T::core;
59 static constexpr bool is_selector = T::is_selector;
60 using selector =
typename T::selector;
61 template<selector_tag T2>
62 using retag =
typename T::template retag<T2>;
66 requires std::derived_from<T, tag_base>
69 static constexpr bool is_tag =
true;
70 static constexpr bool is_direct =
true;
72 static constexpr bool is_selector =
true;
74 template<selector_tag T2>
80 using core =
typename impl::tag_traits<T>::core;
82 template<
typename T1,
typename T2>
83 concept same_tag = std::same_as< core<T1>, core<T2>>;
85 template< selector_tag T2, tag T>
86 using retag =
typename impl::tag_traits<T>::template retag<T2>;
88 template< tag T, std::
size_t b, std::
size_t e>
90 static constexpr bool is_tag =
true;
91 static constexpr bool is_direct =
false;
92 using core = sr_tag< T, b, e>;
93 static constexpr bool is_selector =
false;
95 template<selector_tag T2>
96 using retag = sr_tag< T2, b, e>;
98 static constexpr bool is_static =
true;
99 static constexpr std::size_t begin = b;
100 static constexpr std::size_t end = e;
103 template<
typename T>
104 concept static_tag =
tag<T> && T::is_static;
106 template<
typename T>
107 concept non_static_tag =
tag<T> && (!static_tag<T>);
112 using index_carrier_type = std::size_t;
116 template<
tag ... TL>
119 template<
tag ... TL>
120 class iterator_class;
122 template<
tag ... TL>
125 template<
typename E,
tag ... TL>
131 struct range_base {};
134 template<
typename T>
135 concept is_range = std::derived_from< T, impl::range_base>;
138 struct index_base {};
140 template< tag T, tag ... TL>
141 struct element_traits;
144 struct element_traits< T> : std::false_type {};
146 template< tag T, tag T2, tag ... TL>
147 requires same_selector<T, T2>
148 struct element_traits< T, T2, TL ...> : std::true_type {};
150 template< tag T, tag T2, tag ... TL>
151 requires (!same_selector<T, T2>)
152 struct element_traits< T, T2, TL ...> : element_traits< T, TL ...> {};
154 template<
typename T,
typename ... TL>
155 concept one_of = element_traits< T, TL...>::value;
157 template< tag T, tag ... TL>
158 struct position_traits;
160 template< tag T, tag T2, tag ... TL>
161 requires same_selector<T, T2>
162 struct position_traits< T, T2, TL ...>
163 : std::integral_constant< std::size_t, 0>
166 template< tag T, tag T2, tag ... TL>
167 requires (!same_selector<T, T2>)
168 struct position_traits< T, T2, TL ...>
169 : std::integral_constant< std::size_t, position_traits< T, TL ...>::value + 1>
172 template<
typename T,
typename ... TL>
173 inline constexpr std::size_t position_of = position_traits< T, TL...>::value;
181 template<
typename ... TL>
186 template<
typename TA,
typename TB>
187 struct concat_traits;
189 template< tag TA, tag TB>
190 struct concat_traits< TA, TB> {
194 template< tag TA, tag ... LB>
195 struct concat_traits< TA, tag_list< LB ...>> {
196 using type = tag_list< TA, LB ...>;
199 template<
typename TA,
typename TB>
200 using concat_list =
typename concat_traits< TA, TB>::type;
202 template<
typename LA,
typename LB>
203 struct subtract_traits;
205 template< tag ... TLA>
206 struct subtract_traits< tag_list<TLA...>, tag_list<>> {
207 using type = tag_list<TLA...>;
210 template< tag TA, tag ... TLA, tag TB>
211 requires same_selector< TA, TB>
212 struct subtract_traits< tag_list<TA, TLA...>, tag_list<TB>>
214 using type = tag_list<TLA ...>;
217 template< tag TA, tag ... TLA, tag TB>
218 requires (!same_selector< TA, TB>)
219 struct subtract_traits< tag_list<TA, TLA...>, tag_list<TB>>
222 using removed_a =
typename subtract_traits< tag_list<TLA ...>, tag_list<TB>>::type;
224 using type = concat_list< TA, removed_a>;
227 template< tag ... TLA, tag TB, tag ... TLB>
228 struct subtract_traits< tag_list<TLA...>, tag_list<TB, TLB...>>
231 using removed_a =
typename subtract_traits<tag_list<TLA...>, tag_list<TB>>::type;
233 using type =
typename subtract_traits<removed_a, tag_list<TLB ...>>::type;
236 template< selector_tag T, tag ... TL>
239 template< selector_tag T, tag T0, tag ... TL>
240 requires same_selector<T, T0>
241 struct pick_traits< T, T0, TL ...>
246 template< selector_tag T, tag T0, tag ... TL>
247 requires (!same_selector<T, T0>)
248 struct pick_traits< T, T0, TL ...>
249 : pick_traits< T, TL ...>
252 template< std::size_t I, tag ... TL>
253 struct pick_index_traits;
255 template< tag T0, tag ... TL>
256 struct pick_index_traits< 0, T0, TL ...>
261 template< std::size_t I, tag T0, tag ... TL>
262 struct pick_index_traits< I, T0, TL ...>
263 : pick_index_traits< I-1, TL ...>
266 template<
typename A,
typename B>
267 struct same_list_traits;
269 template< tag ... AL, tag ... BL>
270 requires (
sizeof...(AL) ==
sizeof...(BL))
271 struct same_list_traits< tag_list<AL...>, tag_list<BL...>>
273 static constexpr bool value = (same_selector<AL, BL> && ...);
276 template<
typename A,
typename B>
277 concept same_selector_list = same_list_traits< A, B>::value;
279 template<
typename A,
typename B>
280 struct subset_traits;
282 template< tag ... AL, tag ... BL>
283 struct subset_traits< tag_list<AL...>, tag_list<BL...>>
285 static constexpr bool value = (one_of<AL, BL...> && ...);
288 template<
typename A,
typename B>
289 concept subset_selector = subset_traits< A, B>::value;
292 template<
typename T,
typename ... TL>
293 requires impl::one_of<T, TL...>
294 using pick =
typename impl::pick_traits< T, TL...>::type;
296 template< std::size_t I,
typename ... TL>
297 requires (I <
sizeof...(TL))
298 using pick_index =
typename impl::pick_index_traits< I, TL...>::type;
308 class index_class< T> :
public impl::index_base {
310 index_class() noexcept
313 constexpr explicit index_class(index_carrier_type< T> v) noexcept
317 index_class< T2> retag()
const
319 return index_class< T2>(i_);
321 index_carrier_type<T> value()
const noexcept
325 template< std::
size_t I>
327 auto&&
get()
const noexcept
329 return std::get< I>(i_);
331 template< same_selector<T> T2>
332 auto&&
get()
const noexcept
337 index_carrier_type< T> i_;
351 class iterator_class< T> {
353 iterator_class() noexcept
356 explicit iterator_class(index_carrier_type< T> v) noexcept
359 index_class< T> operator*() const noexcept
361 return index_class< T>(v_);
363 bool operator==(
const iterator_class<T>& b)
const noexcept
367 bool operator!=(
const iterator_class<T>& b)
const noexcept
371 iterator_class<T>& operator++() noexcept
376 iterator_class<T> operator++(
int)
noexcept
383 index_carrier_type< T> v_;
397 template< non_static_tag T>
398 class range_class< T> :
public impl::range_base {
402 range_class() noexcept
405 explicit range_class(index_carrier_type< T> e) noexcept
408 range_class(index_carrier_type< T> b, index_carrier_type< T> e) noexcept
411 range_class(
const range_class<T>& b) =
default;
412 range_class<T>& operator=(
const range_class<T>& b) =
default;
413 range_class(range_class<T>&& b) noexcept
419 range_class<T>& operator=(range_class<T>&& b)
noexcept
427 template<
tag ... TL2>
428 requires (
sizeof...(TL2) >= 1)
429 explicit range_class(
const range_class< TL2...>& r) noexcept
430 : b_(r.template get<selector>().begin_value()), e_(r.template get<selector>().end_value())
432 template<
typename T2>
433 requires same_tag<T, T2>
434 bool operator==(
const range_class<T2>& b)
const
436 return b_ == b.begin_value() && e_ == b.end_value();
438 template<
typename T2>
439 requires same_tag<T, T2>
440 bool operator!=(
const range_class<T2>& b)
const
442 return b_ != b.begin_value() || e_ != b.end_value();
445 range_class< T2> retag()
const
447 return range_class< T2>(b_, e_);
451 return i.value() - b_;
453 index_carrier_type<T>
size()
const
457 iterator_class<selector>
begin()
const noexcept
459 return iterator_class<selector>(b_);
461 iterator_class<selector>
end()
const noexcept
463 return iterator_class<selector>(e_);
465 index_carrier_type<T> begin_value()
const noexcept
469 index_carrier_type<T> end_value()
const noexcept
473 template< same_selector< T> T2>
474 auto&&
get()
const noexcept
478 template< std::
size_t I>
480 auto&&
get()
const noexcept
484 template< std::
size_t I>
488 index_carrier_type< T> b_, e_;
492 template< static_tag T>
499 constexpr explicit range_class(index_carrier_type< T> e)
501 if (0 != T::begin || e != T::end)
503 throw std::logic_error(
"WTF");
506 constexpr range_class(index_carrier_type< T> b, index_carrier_type< T> e)
508 if (b != T::begin || e != T::end)
510 throw std::logic_error(
"WTF");
513 template< tag ... TL2>
514 requires (
sizeof...(TL2) >= 1)
515 explicit range_class(
const range_class< TL2...>&)
noexcept
516 requires pick<
selector, TL2...>::is_static
518 template<
typename T2>
519 requires same_tag<T, T2>
520 constexpr bool operator==(
const range_class<T2>&)
const
524 template<
typename T2>
525 requires same_tag<T, T2>
526 constexpr bool operator!=(
const range_class<T2>&)
const
530 template< static_tag T2>
531 static constexpr range_class< T2> retag()
533 return range_class< T2>();
535 static index_carrier_type<T> flat(
const index_class< selector>& i)
537 return i.value() - T::begin;
539 static constexpr index_carrier_type<T>
size()
541 return T::end - T::begin;
543 static iterator_class<selector>
begin() noexcept
545 return iterator_class<selector>(T::begin);
547 static iterator_class<selector>
end() noexcept
549 return iterator_class<selector>(T::end);
551 static constexpr index_carrier_type<T> begin_value() noexcept
555 static constexpr index_carrier_type<T> end_value() noexcept
559 template< same_selector< T> T2>
560 static constexpr auto get() noexcept
562 return range_class<T>{};
564 template< std::
size_t I>
566 auto&&
get()
const noexcept
570 template< std::
size_t I>
583 template<
tag ... TL>
584 class index_class :
public impl::index_base {
586 index_class() noexcept
587 : i_(index_carrier_type< TL>(0) ...)
589 constexpr index_class(index_carrier_type< TL> ... vl) noexcept
590 : i_(index_class< TL>(vl) ...)
592 index_class(index_class< TL> ... vl) noexcept
600 template< std::
size_t I>
601 requires (I <
sizeof...(TL))
602 auto&&
get()
const noexcept
604 return std::get< I>(i_);
611 template< impl::one_of< TL ...> T>
612 auto&&
get() const noexcept
614 return std::get< index_class< T>>(i_);
617 std::tuple< index_class< TL> ...> i_;
622 class index_class<> :
public impl::index_base {
624 constexpr index_class() noexcept
637 template<
tag ... TL1,
tag ... TL2>
640 return index_class< TL1 ..., TL2 ...>(ia.template get< TL1>() ..., ib.template get< TL2>() ...);
644 template< tag T1, tag ... TL2>
645 std::ostream& operator<<(std::ostream& o, index_class<T1, TL2 ...> v)
647 ((o <<
"[" << v.template get<T1>()), ..., (o <<
"," << v.template get<TL2>())), o <<
"]";
653 template<
tag ... TL>
654 class iterator_class {
656 iterator_class() noexcept
657 : rngp_(
nullptr), it_(iterator_class< TL>(0) ...)
659 iterator_class(
const range_class< TL...>* rngp, iterator_class< selector<TL>> ... v) noexcept
660 : rngp_(rngp), it_(v ...)
662 index_class< selector<TL> ...> operator*() const noexcept
664 return index_class< selector<TL> ...>(*std::get< iterator_class< selector< TL>>>(it_)...);
666 bool operator==(
const iterator_class<TL ...>& b)
const noexcept
668 return equal<
sizeof...(TL)>(b);
670 bool operator!=(
const iterator_class<TL ...>& b)
const noexcept
672 return !equal<
sizeof...(TL)>(b);
674 iterator_class<TL ...>& operator++() noexcept
676 increment<
sizeof...(TL)>();
679 iterator_class<TL ...> operator++(
int)
noexcept
686 template< std::
size_t I>
687 bool equal(
const iterator_class<TL ...>& b)
const noexcept
691 if (std::get<I - 1>(it_) != std::get<I - 1>(b.it_))
693 return equal< I - 1>(b);
701 template< std::
size_t I>
702 void increment() noexcept
704 auto&& iti = std::get<I - 1>(it_);
708 auto&& rngi = rng().template get<I - 1>();
709 if (iti != rngi.end())
716 const range_class< TL...>& rng()
const
720 const range_class< TL...>* rngp_;
721 std::tuple< iterator_class< selector<TL>> ...> it_;
732 template<
tag ... TL>
733 class range_class :
public impl::range_base {
735 range_class()
noexcept
737 range_class(
const range_class< TL> & ... vl)
noexcept requires (
sizeof...(TL) > 0)
741 template<
tag ... TL2>
742 requires (
sizeof...(TL2) >=
sizeof...(TL))
743 explicit range_class(
const range_class< TL2...> & r) noexcept
759 iterator_class<TL ...>
begin() const noexcept
761 return iterator_class<TL ...>(
this, get_begin< TL>() ...);
767 iterator_class<TL ...>
end() const noexcept
769 return iterator_class<TL ...>(
this, get_end< TL>() ...);
776 template<
typename T>
778 && non_static_tag< pick<selector<T>, TL ...>>
779 auto&&
get() const noexcept
781 return std::get< range_class< pick<selector<T>, TL ...>>>(i_);
788 template<
typename T>
790 && static_tag< pick<selector<T>, TL ...>>
791 static constexpr auto get() noexcept
793 return range_class< pick<selector<T>, TL ...>>{};
800 template< std::
size_t I>
801 auto&&
get() const noexcept
803 return std::get< I>(i_);
806 template< std::
size_t I>
807 using get_tag = std::tuple_element_t<I, std::tuple<TL ...>>;
811 auto get_begin() const noexcept
813 auto&& rngi = std::get< range_class< T>>(i_);
817 auto get_end() const noexcept
819 auto&& rngi = std::get< range_class< T>>(i_);
820 if constexpr (impl::position_of<T, TL ...> == 0)
825 using i_type = std::tuple< range_class< TL> ...>;
837 template<
tag ... TL1,
tag ... TL2>
840 return range_class< TL1 ..., TL2 ...>(rnga.template get< TL1>() ..., rngb.template get< TL2>() ...);
848 static constexpr std::size_t static_multiplier = 1;
849 static constexpr bool has_dynamic_multiplier =
true;
850 template<
typename T2>
851 static std::size_t dynamic_multiplier(T2&& r)
853 return r.template get<selector<T>>().size();
858 requires T::is_static
859 struct size_traits<T>
861 static constexpr std::size_t static_multiplier = T::end - T::begin;
862 static constexpr bool has_dynamic_multiplier =
false;
866 class multiplier_class
872 explicit multiplier_class(std::size_t v)
875 void assign_value(std::size_t v)
879 std::size_t value()
const
887 template< tag T, std::
size_t s>
890 static constexpr bool is_tag =
true;
891 static constexpr bool is_direct =
false;
892 using core = sm_tag< T, s>;
893 static constexpr bool is_selector =
false;
895 template<selector_tag T2>
896 using retag = sm_tag< T2, s>;
898 static constexpr bool has_static_multiplier =
true;
899 static constexpr std::size_t static_multiplier = s;
902 template< tag T, std::
size_t b, std::
size_t e, std::
size_t s>
905 static constexpr bool is_tag =
true;
906 static constexpr bool is_direct =
false;
907 using core = sm_tag< T, s>;
908 static constexpr bool is_selector =
false;
910 template<selector_tag T2>
911 using retag = sm_tag< T2, s>;
913 static constexpr bool is_static =
true;
914 static constexpr std::size_t begin = b;
915 static constexpr std::size_t end = e;
917 static constexpr bool has_static_multiplier =
true;
918 static constexpr std::size_t static_multiplier = s;
921 template<
typename T>
922 concept has_static_multiplier =
requires {
924 {T::has_static_multiplier} -> std::convertible_to<bool>;
925 requires T::has_static_multiplier;
928 template< tag T, std::
size_t s>
929 class multiplier_class<sm_tag<T, s>>
934 static constexpr std::size_t value()
940 template< tag ... TL>
941 struct multiplier_list_traits;
944 struct multiplier_list_traits<>
946 static constexpr std::size_t static_multiplier = 1;
947 using multiplier_tag_list = tag_list<>;
948 static constexpr bool has_dynamic_multiplier =
false;
951 template< tag T0, tag ... TL>
952 requires (!multiplier_list_traits< TL ...>::has_dynamic_multiplier)
953 struct multiplier_list_traits< T0, TL ...>
956 using head_traits = size_traits<T0>;
957 using tail_traits = multiplier_list_traits< TL ...>;
959 static constexpr std::size_t static_multiplier = head_traits::static_multiplier * tail_traits::static_multiplier;
961 using head_multiplier_tag = sm_tag<selector<T0>, tail_traits::static_multiplier>;
962 using tail_multiplier_tag_list =
typename tail_traits::multiplier_tag_list;
964 using multiplier_tag_list = concat_list< head_multiplier_tag, tail_multiplier_tag_list>;
965 static constexpr bool has_dynamic_multiplier = head_traits::has_dynamic_multiplier;
966 template< tag ... TL2, tag ... TL3>
967 static std::size_t fill_dynamic_multiplier(std::tuple< multiplier_class< TL2>...>&,
const range_class<TL3 ...>& r)
968 requires has_dynamic_multiplier
970 return head_traits::dynamic_multiplier(r);
974 template< tag T0, tag ... TL>
975 requires multiplier_list_traits< TL ...>::has_dynamic_multiplier
976 struct multiplier_list_traits< T0, TL ...>
979 using head_traits = size_traits<T0>;
980 using tail_traits = multiplier_list_traits< TL ...>;
982 static constexpr std::size_t static_multiplier = head_traits::static_multiplier * tail_traits::static_multiplier;
984 using head_multiplier_tag = selector<T0>;
985 using tail_multiplier_tag_list =
typename tail_traits::multiplier_tag_list;
987 using multiplier_tag_list = concat_list< head_multiplier_tag, tail_multiplier_tag_list>;
988 static constexpr bool has_dynamic_multiplier =
true;
989 template< tag ... TL2, tag ... TL3>
990 static std::size_t fill_dynamic_multiplier(std::tuple< multiplier_class< TL2>...>& m,
const range_class<TL3 ...>& r)
992 std::size_t dm = tail_traits::fill_dynamic_multiplier(m, r);
993 std::get< multiplier_class<head_multiplier_tag>>(m).assign_value(tail_traits::static_multiplier * dm);
994 if constexpr (head_traits::has_dynamic_multiplier)
996 dm *= head_traits::dynamic_multiplier(r);
1002 template< tag ... TL>
1003 class multiplier_list_class
1006 multiplier_list_class()
1008 template< tag ... TL3>
1009 requires (
sizeof...(TL3) ==
sizeof...(TL))
1010 explicit multiplier_list_class(
const range_class<TL3 ...>& r)
1012 using traits = multiplier_list_traits<pick<selector<TL>, TL3...> ...>;
1013 if constexpr (traits::has_dynamic_multiplier)
1015 traits::fill_dynamic_multiplier(m_, r);
1018 template< tag ... TL3>
1019 requires (
sizeof...(TL3) >=
sizeof...(TL))
1020 explicit multiplier_list_class(
const multiplier_list_class<TL3 ...>& r)
1021 : m_( r.template get<TL>() ...)
1023 template< tag ... TL3, tag ... TL2>
1024 requires same_selector_list<tag_list<TL3...>, tag_list<TL...>>
1025 && subset_selector< tag_list<TL2...>, tag_list<TL...>>
1026 std::size_t flat(
const range_class<TL3 ...>& r,
const index_class<TL2 ...>& i)
const
1028 return (0 + ... + flat_one<TL2>(r, i));
1033 return std::get< multiplier_class<pick<selector<T2>, TL...>>>(m_);
1035 template< std::
size_t I2>
1038 return std::get< I2>(m_);
1041 std::tuple< multiplier_class< TL>...> m_;
1043 template< tag T, tag ... TL3, tag ... TL2>
1044 std::size_t flat_one(
const range_class<TL3 ...>& r,
const index_class<TL2 ...>& i)
const
1046 auto&& ix = i.template get<selector<T>>();
1047 auto&& rx = r.template get<selector<T>>();
1049 std::size_t mv = std::get< multiplier_class< pick<selector<T>, TL...>>>(m_).value();
1050 std::size_t fv = rx.flat(ix);
1055 template<
typename L>
1056 struct multiplier_list_creator;
1058 template<tag ... TL2>
1059 struct multiplier_list_creator< tag_list< TL2 ...>>
1061 using type = multiplier_list_class< TL2 ...>;
1064 template< tag ... TL3>
1065 using multiplier_list =
typename multiplier_list_creator<
typename multiplier_list_traits< TL3...>::multiplier_tag_list>::type;
1067 template< tag RT, tag MT>
1068 struct mixer_traits;
1070 template< tag RT, tag MT>
1071 requires same_tag<RT, selector<MT>>
1072 struct mixer_traits<RT, MT>
1077 template< tag RT, tag MT>
1078 requires same_tag<selector<RT>, MT>
1079 struct mixer_traits<RT, MT>
1084 template< tag RT, tag MT>
1085 requires RT::is_static && MT::has_static_multiplier
1086 struct mixer_traits<RT, MT>
1088 using type = srm_tag<selector<RT>, RT::begin, RT::end, MT::static_multiplier>;
1091 template<
typename RC,
typename MLC>
1092 struct mixer_list_traits;
1095 struct mixer_list_traits< range_class<>, multiplier_list_class<>>
1097 using type = tag_list<>;
1100 template< tag RT, tag ... RL, tag MT, tag ... ML>
1101 requires (
sizeof...(RL) ==
sizeof...(ML))
1102 struct mixer_list_traits< range_class< RT, RL...>, multiplier_list_class< MT, ML...>>
1105 using head_traits = mixer_traits< RT, MT>;
1106 using tail_traits = mixer_list_traits< range_class< RL...>, multiplier_list_class< ML...>>;
1108 using type = concat_list< typename head_traits::type, typename tail_traits::type>;
1112 struct range_demixer_traits
1114 using type = selector<T>;
1118 requires T::is_static
1119 struct range_demixer_traits<T>
1121 using type = sr_tag<selector<T>, T::begin, T::end>;
1125 struct multiplier_demixer_traits
1127 using type = selector<T>;
1131 requires T::has_static_multiplier
1132 struct multiplier_demixer_traits<T>
1134 using type = sm_tag<selector<T>, T::static_multiplier>;
1138 template<
typename E,
tag ... TL>
1141 template<
typename E,
tag ... TL>
1145 template<
typename E,
typename X>
1146 struct tensor_view_creator;
1148 template<
typename E, tag ... TL>
1149 struct tensor_view_creator< E, tag_list< TL...>>
1151 using type = tensor_view< E, TL...>;
1168 template<
typename E,
tag ... TL>
1175 template<
tag ... TL3,
tag ... TL2>
1182 self_& operator=(
const self_&) =
delete;
1183 self_& operator=(self_&&) =
delete;
1205 template<
tag ... TL2>
1207 requires (
sizeof...(TL2) <
sizeof...(TL))
1210 using result_list =
typename impl::subtract_traits<
tag_list< TL...>,
tag_list< TL2...>>::type;
1211 using result_view =
typename impl::tensor_view_creator< E, result_list>::type;
1212 return result_view(rng_, mult_, arr_ + mult_.flat(rng_, i));
1221 template<
tag ... TL2>
1223 requires (
sizeof...(TL2) ==
sizeof...(TL))
1226 return arr_[mult_.flat(rng_, i)];
1238 requires (sizeof...(TL) == 1) && ((TL::has_static_multiplier) && ...) && ((TL::static_multiplier == 1) && ...)
1268 return rng_.template get< selector<T2>>().size();
1276 template< std::
size_t I2>
1279 return rng_.template get< I2>().size();
1292 requires impl::has_static_multiplier< pick< selector<T2>, TL...>>
1295 return pick< selector<T2>, TL...>::static_multiplier;
1300 requires (!impl::has_static_multiplier< pick< selector<T2>, TL...>>)
1303 return mult_.template get< selector<T2>>().value();
1316 template< std::
size_t I2>
1317 requires impl::has_static_multiplier< pick_index< I2, TL...>>
1320 return pick_index< I2, TL...>::static_multiplier;
1324 template< std::
size_t I2>
1325 requires (!impl::has_static_multiplier< pick_index< I2, TL...>>)
1328 return mult_.template get< I2>().value();
1334 impl::multiplier_list_class< typename impl::multiplier_demixer_traits< TL>::type ...> mult_;
1344 template<
typename E,
tag ... TL>
1345 using extract_tensor_view =
typename impl::tensor_view_creator< E,
typename impl::mixer_list_traits<
range_class< TL...>, impl::multiplier_list< TL...>>::type>::type;
1364 template<
typename E,
tag ... TL>
1365 class tensor_class {
1367 tensor_class()
noexcept
1375 template< tag ... TL2>
1376 requires (
sizeof...(TL2) ==
sizeof...(TL))
1389 template<
tag ... TL2>
1390 requires (
sizeof...(TL2) ==
sizeof...(TL))
1406 return view_type(rng_, mult_, arr_.data());
1415 return const_view_type(rng_, mult_, arr_.data());
1428 template<
tag ... TL2>
1430 requires (
sizeof...(TL2) <
sizeof...(TL))
1446 template<
tag ... TL2>
1448 requires (
sizeof...(TL2) <
sizeof...(TL))
1469 template<
tag ... TL2>
1471 requires (
sizeof...(TL2) ==
sizeof...(TL))
1474 return arr_[mult_.flat(rng_, i)];
1483 template<
tag ... TL2>
1485 requires (
sizeof...(TL2) ==
sizeof...(TL))
1488 return arr_[mult_.flat(rng_, i)];
1498 requires (
sizeof...(TL) == 1)
1510 requires (sizeof...(TL) == 1)
1538 impl::multiplier_list< TL ...> mult_;
1539 std::vector< E> arr_;
1544 template<
typename P,
typename C>
1547 template<
typename ... SL,
typename C>
1548 struct permute< tag_list< SL...>, C>
1550 using type =
typename C::template type< SL...>;
1553 template<
typename P,
typename C>
1554 using permute_t =
typename permute< P, C>::type;
1556 template<
typename E, tag ... TL>
1557 struct permutator_tensor_class
1559 template<
typename ... SL>
1560 using type = tensor_class< E, pick<SL, TL...> ...>;
1563 template< tag ... TL>
1564 struct permutator_range_class
1566 template<
typename ... SL>
1567 using type = range_class< pick<SL, TL...> ...>;
1570 struct permutator_range
1572 template<
typename ... SL>
1574 template< tag ... TL>
1575 static auto permute_range(
const range_class<TL...>& r)
1577 using range = range_class< pick<SL, TL...> ...>;
1578 return range((r.template get<SL>() & ...));
1592 template<
typename P,
typename E,
tag ... TL>
1596 template<
typename P,
tag ... TL>
1597 using permute_range_class = impl::permute_t< P, impl::permutator_range_class<TL...>>;
1599 template<
typename P,
tag ... TL>
1602 using permutator = impl::permute_t<P, impl::permutator_range>;
1603 return permutator::permute_range(r);
1611 template< selector_tag T>
1613 static constexpr bool is_tag =
true;
1614 static constexpr bool is_direct =
false;
1616 static constexpr bool is_selector =
true;
1617 using selector = c<T>;
1618 template<selector_tag T2>
1622 template< selector_tag T>
1627 template< selector_tag T>
1628 struct co_traits< c<T>> {
1645 using co = retag< typename impl::co_traits<selector<T>>
::co, T>;
1649 template<
typename X>
1650 struct co_list_traits;
1652 template<
tag ... TL>
1653 struct co_list_traits<
tag_list<TL ...>> {
1663 template<
typename X>
1664 using co_list =
typename impl::co_list_traits< X>::co_list;
1692 template<
typename E, tagged::tag STL0, tagged::tag DTL0>
1695 auto r0 = dvec.
range().template get<DTL0>();
1698 dvec[i0] = svec[i0];
1702 template<
typename E, tagged::tag ... STL, tagged::tag DTL0, tagged::tag ... DTL>
1703 inline void permute_tensor(
const tagged::tensor_view< const E, STL ...>& svec,
const tagged::tensor_view< E, DTL0, DTL ...>& dvec)
1705 auto r0 = dvec.
range().template get<DTL0>();
1708 auto sslice = svec[i0];
1709 auto dslice = dvec[i0];
1711 permute_tensor(sslice, dslice);
1715 template<
typename E, tagged::tag ... STL, tagged::tag ... DTL>
1716 requires (
sizeof...(STL) ==
sizeof...(DTL))
1717 inline void permute_tensor(
const tagged::tensor_class< E, STL ...>& svec, tagged::tensor_class< E, DTL ...>& dvec)
1719 permute_tensor(svec.
view(), dvec.
view());
A list of tagged indexes (a position in an N-dimensional space)
Definition tagged.hpp:584
auto && get() const noexcept
Retrieve individual tagged index by selector tag.
Definition tagged.hpp:612
auto && get() const noexcept
Retrieve individual tagged index by zero-based position.
Definition tagged.hpp:602
A list of tagged ranges (an N-dimensional box)
Definition tagged.hpp:733
iterator_class< TL ... > begin() const noexcept
Lexicographical iterator through the N-dimensional box.
Definition tagged.hpp:759
std::size_t size() const
Size (volume) of the range.
Definition tagged.hpp:751
auto && get() const noexcept
Retrieve individual range by selector tag.
Definition tagged.hpp:779
iterator_class< TL ... > end() const noexcept
Lexicographical iterator through the N-dimensional box.
Definition tagged.hpp:767
static constexpr auto get() noexcept
Retrieve individual range by selector tag.
Definition tagged.hpp:791
auto && get() const noexcept
Retrieve individual range by index.
Definition tagged.hpp:801
A tensor - a multi-dimensional tagged generalization of vector/matrix.
Definition tagged.hpp:1365
const E * flat_data() const
A const pointer to the beginning of the array containing the data.
Definition tagged.hpp:1532
auto operator[](const index_class< TL2 ... > &i) const
Extract an immutable reference to a sub-space of this tensor.
Definition tagged.hpp:1447
E & operator[](const index_class< TL2... > &i)
Access an element of this tensor.
Definition tagged.hpp:1470
const_view_type view() const
Return tensor_view acting as a const reference to the complete tensor_class.
Definition tagged.hpp:1413
E * data()
A pointer to the beginning of the array containing the data.
Definition tagged.hpp:1497
auto operator[](const index_class< TL2 ... > &i)
Extract a reference to a sub-space of this tensor.
Definition tagged.hpp:1429
const range_class< TL ... > & range() const
The range corresponding to this tensor.
Definition tagged.hpp:1458
const E & operator[](const index_class< TL2... > &i) const
Read an element of this tensor.
Definition tagged.hpp:1484
view_type view()
Return tensor_view acting as a reference to the complete tensor_class.
Definition tagged.hpp:1404
E * flat_data()
A pointer to the beginning of the array containing the data.
Definition tagged.hpp:1521
tensor_class(const range_class< TL2 ... > &rng, const E &e) noexcept
Initialize the tensor_class to a size defined by a range_class.
Definition tagged.hpp:1391
tensor_class(const range_class< TL2 ... > &rng)
Initialize the tensor_class to a size defined by a range_class.
Definition tagged.hpp:1377
const E * data() const
A const pointer to the beginning of the array containing the data.
Definition tagged.hpp:1509
A reference to a sub-space of a tensor.
Definition tagged.hpp:1169
auto operator[](const index_class< TL2 ... > &i) const
Extract a sub-space of this sub-space.
Definition tagged.hpp:1206
E * flat_data() const
A pointer to the element at the position defined by the lowermost index values of all dimensions of t...
Definition tagged.hpp:1250
const range_t & range() const
The range corresponding to the sub-space.
Definition tagged.hpp:1190
E & operator[](const index_class< TL2 ... > &i) const
Access an element of this sub-space.
Definition tagged.hpp:1222
E * data() const
A pointer to the beginning of the array containing the sub-space data.
Definition tagged.hpp:1237
static constexpr std::size_t dim_multiplier()
Return the multiplier associated with the dimension specified by a tag.
Definition tagged.hpp:1293
static constexpr std::size_t dimensions
Definition tagged.hpp:1258
static constexpr std::size_t dim_multiplier()
Return the multiplier associated with the dimension specified by an index.
Definition tagged.hpp:1318
std::size_t dim_size() const
Return the sub-space size in a dimension specified by a tag.
Definition tagged.hpp:1266
A bare tag used to select a dimension.
Definition tagged.hpp:36
Any tag used to specify a dimension.
Definition tagged.hpp:28
typename impl::tag_traits< T >::selector selector
Extract selector tag from any tag.
Definition tagged.hpp:43
typename impl::co_list_traits< X >::co_list co_list
Co-tag every element of a tag_list.
Definition tagged.hpp:1664
typename impl::tensor_view_creator< E, typename impl::mixer_list_traits< range_class< TL... >, impl::multiplier_list< TL... > >::type >::type extract_tensor_view
The type of a tensor_view acting as a reference to the complete tensor_class with the given tag list.
Definition tagged.hpp:1345
index_class< TL1 ..., TL2 ... > operator&(const index_class< TL1 ... > &ia, const index_class< TL2 ... > &ib)
Concatenate two (multi-dimensional) indexes together.
Definition tagged.hpp:638
retag< typename impl::co_traits< selector< T > >::co, T > co
Provide a co-tag for a given tag.
Definition tagged.hpp:1645
impl::permute_t< P, impl::permutator_tensor_class< E, TL... > > permute_tensor_class
Provide a tensor_class for the selected dimensions with layout specified by a tagged::tag_list.
Definition tagged.hpp:1593
constexpr range_class< co< T > > operator~(const range_class< T > &r)
Return a co-tagged range with the same extent.
Definition tagged.hpp:1673
A wrapped list of tags.
Definition tagged.hpp:182