10 #ifndef EIGEN_CXX11_TENSOR_TENSOR_INDEX_LIST_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_INDEX_LIST_H
14 #if EIGEN_HAS_CONSTEXPR && EIGEN_HAS_VARIADIC_TEMPLATES
16 #define EIGEN_HAS_INDEX_LIST
51 template <Index f, Index s>
52 struct type2indexpair {
67 template<Index n>
struct NumTraits<type2index<
n> >
87 val = internal::convert_index<T>(new_val);
98 template <Index f, Index s>
104 template <
typename T>
105 struct is_compile_time_constant {
106 static constexpr
bool value =
false;
110 struct is_compile_time_constant<type2index<idx> > {
111 static constexpr
bool value =
true;
114 struct is_compile_time_constant<const type2index<idx> > {
115 static constexpr
bool value =
true;
118 struct is_compile_time_constant<type2index<idx>& > {
119 static constexpr
bool value =
true;
122 struct is_compile_time_constant<const type2index<idx>& > {
123 static constexpr
bool value =
true;
126 template <Index f, Index s>
127 struct is_compile_time_constant<type2indexpair<
f,
s> > {
128 static constexpr
bool value =
true;
130 template <Index f, Index s>
131 struct is_compile_time_constant<const type2indexpair<
f,
s> > {
132 static constexpr
bool value =
true;
134 template <Index f, Index s>
135 struct is_compile_time_constant<type2indexpair<
f,
s>& > {
136 static constexpr
bool value =
true;
138 template <Index f, Index s>
139 struct is_compile_time_constant<const type2indexpair<
f,
s>& > {
140 static constexpr
bool value =
true;
144 template<
typename...
T>
147 template<
typename T,
typename...
O>
148 struct IndexTuple<
T,
O...> {
152 constexpr
static int count = 1 +
sizeof...(O);
154 IndexTuple<
O...> others;
156 typedef IndexTuple<
O...> Other;
160 struct IndexTuple<
T> {
164 constexpr
static int count = 1;
170 template<
int N,
typename...
T>
171 struct IndexTupleExtractor;
173 template<
int N,
typename T,
typename...
O>
174 struct IndexTupleExtractor<
N,
T,
O...> {
176 typedef typename IndexTupleExtractor<
N-1,
O...>::ValType ValType;
179 return IndexTupleExtractor<N-1, O...>::get_val(val.others);
182 EIGEN_DEVICE_FUNC static constexpr
const ValType& get_val(
const IndexTuple<T, O...>& val) {
183 return IndexTupleExtractor<N-1, O...>::get_val(val.others);
185 template <
typename V>
187 IndexTupleExtractor<N-1, O...>::set_val(val.others, new_val);
192 template<
typename T,
typename...
O>
193 struct IndexTupleExtractor<0,
T,
O...> {
200 EIGEN_DEVICE_FUNC static constexpr
const ValType& get_val(
const IndexTuple<T, O...>& val) {
203 template <
typename V>
211 template <
int N,
typename T,
typename...
O>
213 return IndexTupleExtractor<N, T, O...>::get_val(
tuple);
215 template <
int N,
typename T,
typename...
O>
217 return IndexTupleExtractor<N, T, O...>::get_val(
tuple);
219 template <
typename T,
typename...
O>
220 struct array_size<IndexTuple<
T,
O...> > {
221 static const size_t value = IndexTuple<
T,
O...>::count;
223 template <
typename T,
typename...
O>
224 struct array_size<const IndexTuple<
T,
O...> > {
225 static const size_t value = IndexTuple<
T,
O...>::count;
231 template <Index Idx,
typename ValueT>
233 template <
typename...
T>
238 template <
typename...
T>
241 update_value(array_get<Idx>(
t),
value);
247 template <
typename...
T>
249 return ((
i == Idx) & is_compile_time_constant<
typename IndexTupleExtractor<Idx, T...>::ValType>::
value) ||
250 tuple_coeff<Idx-1, ValueT>::value_known_statically(
i,
t);
253 template <
typename...
T>
254 EIGEN_DEVICE_FUNC static constexpr
bool values_up_to_known_statically(
const IndexTuple<T...>&
t) {
255 return is_compile_time_constant<
typename IndexTupleExtractor<Idx,
T...>::ValType>
::value &&
256 tuple_coeff<Idx-1, ValueT>::values_up_to_known_statically(
t);
259 template <
typename...
T>
260 EIGEN_DEVICE_FUNC static constexpr
bool values_up_to_statically_known_to_increase(
const IndexTuple<T...>&
t) {
261 return is_compile_time_constant<
typename IndexTupleExtractor<Idx,
T...>::ValType>
::value &&
262 is_compile_time_constant<
typename IndexTupleExtractor<Idx,
T...>::ValType>
::value &&
264 tuple_coeff<Idx-1, ValueT>::values_up_to_statically_known_to_increase(
t);
268 template <
typename ValueT>
269 struct tuple_coeff<0, ValueT> {
270 template <
typename...
T>
273 return array_get<0>(
t);
275 template <
typename...
T>
278 update_value(array_get<0>(
t),
value);
280 template <
typename...
T>
282 return is_compile_time_constant<
typename IndexTupleExtractor<0,
T...>::ValType>
::value && (
i == 0);
285 template <
typename...
T>
286 EIGEN_DEVICE_FUNC static constexpr
bool values_up_to_known_statically(
const IndexTuple<T...>&) {
287 return is_compile_time_constant<
typename IndexTupleExtractor<0,
T...>::ValType>
::value;
290 template <
typename...
T>
291 EIGEN_DEVICE_FUNC static constexpr
bool values_up_to_statically_known_to_increase(
const IndexTuple<T...>&) {
299 template<
typename FirstType,
typename... OtherTypes>
300 struct IndexList : internal::IndexTuple<FirstType, OtherTypes...> {
302 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >
::value-1,
Index>
::get(
i, *
this);
305 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >
::value-1,
Index>
::get(
i, *
this);
308 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >
::value-1,
Index>
::set(
i, *
this,
value);
316 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >
::value-1,
Index>::value_known_statically(
i, *
this);
319 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >
::value-1,
Index>::values_up_to_known_statically(*
this);
323 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >
::value-1,
Index>::values_up_to_statically_known_to_increase(*
this);
327 template <
typename FirstType,
typename... OtherTypes>
329 const IndexList<FirstType, OtherTypes...>& dims) {
331 for (
size_t i = 0;
i < 1 +
sizeof...(OtherTypes); ++
i) {
332 if (
i > 0)
os <<
", ";
339 template<
typename FirstType,
typename... OtherTypes>
340 constexpr IndexList<FirstType, OtherTypes...> make_index_list(FirstType val1, OtherTypes... other_vals) {
341 return IndexList<FirstType, OtherTypes...>(val1, other_vals...);
345 template<
typename FirstType,
typename... OtherTypes>
346 struct IndexPairList : internal::IndexTuple<FirstType, OtherTypes...> {
348 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >
::value-1,
IndexPair<Index>>
::get(
i, *
this);
358 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >
::value-1,
Index>::value_known_statically(
i, *
this);
364 template<
typename FirstType,
typename... OtherTypes>
368 for (
size_t i = 0;
i < array_size<IndexList<FirstType, OtherTypes...> >
::value; ++
i) {
374 template<
typename FirstType,
typename... OtherTypes>
struct array_size<IndexList<FirstType, OtherTypes...> > {
375 static const size_t value = array_size<IndexTuple<FirstType, OtherTypes...> >
::value;
377 template<
typename FirstType,
typename... OtherTypes>
struct array_size<const IndexList<FirstType, OtherTypes...> > {
378 static const size_t value = array_size<IndexTuple<FirstType, OtherTypes...> >
::value;
381 template<
typename FirstType,
typename... OtherTypes>
struct array_size<IndexPairList<FirstType, OtherTypes...> > {
382 static const size_t value = std::tuple_size<std::tuple<FirstType, OtherTypes...> >
::value;
384 template<
typename FirstType,
typename... OtherTypes>
struct array_size<const IndexPairList<FirstType, OtherTypes...> > {
385 static const size_t value = std::tuple_size<std::tuple<FirstType, OtherTypes...> >
::value;
389 return IndexTupleExtractor<N, FirstType, OtherTypes...>::get_val(
a);
392 return IndexTupleExtractor<N, FirstType, OtherTypes...>::get_val(
a);
395 template <
typename T>
396 struct index_known_statically_impl {
402 template <
typename FirstType,
typename... OtherTypes>
403 struct index_known_statically_impl<IndexList<FirstType, OtherTypes...> > {
405 return IndexList<FirstType, OtherTypes...>().value_known_statically(
i);
409 template <
typename FirstType,
typename... OtherTypes>
410 struct index_known_statically_impl<const IndexList<FirstType, OtherTypes...> > {
412 return IndexList<FirstType, OtherTypes...>().value_known_statically(
i);
417 template <
typename T>
418 struct all_indices_known_statically_impl {
419 static constexpr
bool run() {
424 template <
typename FirstType,
typename... OtherTypes>
425 struct all_indices_known_statically_impl<IndexList<FirstType, OtherTypes...> > {
427 return IndexList<FirstType, OtherTypes...>().all_values_known_statically();
431 template <
typename FirstType,
typename... OtherTypes>
432 struct all_indices_known_statically_impl<const IndexList<FirstType, OtherTypes...> > {
434 return IndexList<FirstType, OtherTypes...>().all_values_known_statically();
439 template <
typename T>
440 struct indices_statically_known_to_increase_impl {
446 template <
typename FirstType,
typename... OtherTypes>
447 struct indices_statically_known_to_increase_impl<IndexList<FirstType, OtherTypes...> > {
449 return Eigen::IndexList<FirstType, OtherTypes...>().values_statically_known_to_increase();
453 template <
typename FirstType,
typename... OtherTypes>
454 struct indices_statically_known_to_increase_impl<const IndexList<FirstType, OtherTypes...> > {
456 return Eigen::IndexList<FirstType, OtherTypes...>().values_statically_known_to_increase();
461 template <
typename Tx>
462 struct index_statically_eq_impl {
468 template <
typename FirstType,
typename... OtherTypes>
469 struct index_statically_eq_impl<IndexList<FirstType, OtherTypes...> > {
471 return IndexList<FirstType, OtherTypes...>().value_known_statically(
i) &
472 (IndexList<FirstType, OtherTypes...>().
get(
i) ==
value);
476 template <
typename FirstType,
typename... OtherTypes>
477 struct index_statically_eq_impl<const IndexList<FirstType, OtherTypes...> > {
479 return IndexList<FirstType, OtherTypes...>().value_known_statically(
i) &
480 (IndexList<FirstType, OtherTypes...>().
get(
i) ==
value);
485 template <
typename T>
486 struct index_statically_ne_impl {
492 template <
typename FirstType,
typename... OtherTypes>
493 struct index_statically_ne_impl<IndexList<FirstType, OtherTypes...> > {
495 return IndexList<FirstType, OtherTypes...>().value_known_statically(
i) &
496 (IndexList<FirstType, OtherTypes...>().
get(
i) !=
value);
500 template <
typename FirstType,
typename... OtherTypes>
501 struct index_statically_ne_impl<const IndexList<FirstType, OtherTypes...> > {
503 return IndexList<FirstType, OtherTypes...>().value_known_statically(
i) &
504 (IndexList<FirstType, OtherTypes...>().
get(
i) !=
value);
509 template <
typename T>
510 struct index_statically_gt_impl {
516 template <
typename FirstType,
typename... OtherTypes>
517 struct index_statically_gt_impl<IndexList<FirstType, OtherTypes...> > {
519 return IndexList<FirstType, OtherTypes...>().value_known_statically(
i) &
520 (IndexList<FirstType, OtherTypes...>().
get(
i) >
value);
524 template <
typename FirstType,
typename... OtherTypes>
525 struct index_statically_gt_impl<const IndexList<FirstType, OtherTypes...> > {
527 return IndexList<FirstType, OtherTypes...>().value_known_statically(
i) &
528 (IndexList<FirstType, OtherTypes...>().
get(
i) >
value);
534 template <
typename T>
535 struct index_statically_lt_impl {
541 template <
typename FirstType,
typename... OtherTypes>
542 struct index_statically_lt_impl<IndexList<FirstType, OtherTypes...> > {
544 return IndexList<FirstType, OtherTypes...>().value_known_statically(
i) &
545 (IndexList<FirstType, OtherTypes...>().
get(
i) <
value);
549 template <
typename FirstType,
typename... OtherTypes>
550 struct index_statically_lt_impl<const IndexList<FirstType, OtherTypes...> > {
552 return IndexList<FirstType, OtherTypes...>().value_known_statically(
i) &
553 (IndexList<FirstType, OtherTypes...>().
get(
i) <
value);
559 template <
typename Tx>
560 struct index_pair_first_statically_eq_impl {
566 template <
typename FirstType,
typename... OtherTypes>
567 struct index_pair_first_statically_eq_impl<IndexPairList<FirstType, OtherTypes...> > {
569 return IndexPairList<FirstType, OtherTypes...>().value_known_statically(
i) &
570 (IndexPairList<FirstType, OtherTypes...>().
operator[](
i).first ==
value);
574 template <
typename FirstType,
typename... OtherTypes>
575 struct index_pair_first_statically_eq_impl<const IndexPairList<FirstType, OtherTypes...> > {
577 return IndexPairList<FirstType, OtherTypes...>().value_known_statically(
i) &
578 (IndexPairList<FirstType, OtherTypes...>().
operator[](
i).first ==
value);
584 template <
typename Tx>
585 struct index_pair_second_statically_eq_impl {
591 template <
typename FirstType,
typename... OtherTypes>
592 struct index_pair_second_statically_eq_impl<IndexPairList<FirstType, OtherTypes...> > {
594 return IndexPairList<FirstType, OtherTypes...>().value_known_statically(
i) &
595 (IndexPairList<FirstType, OtherTypes...>().
operator[](
i).second ==
value);
599 template <
typename FirstType,
typename... OtherTypes>
600 struct index_pair_second_statically_eq_impl<const IndexPairList<FirstType, OtherTypes...> > {
602 return IndexPairList<FirstType, OtherTypes...>().value_known_statically(
i) &
603 (IndexPairList<FirstType, OtherTypes...>().
operator[](
i).second ==
value);
616 template <
typename T>
623 template <
typename T>
630 template <
typename T>
637 template <
typename T>
644 template <
typename T>
651 template <
typename T>
658 template <
typename T>
665 template <
typename Tx>
672 template <
typename Tx>
689 template <
typename T>
694 template <
typename T>
699 template <
typename T>
704 template <
typename T>
709 template <
typename T>
714 template <
typename T>
719 template <
typename T>
724 template <
typename T>
729 template <
typename T>
738 #endif // EIGEN_CXX11_TENSOR_TENSOR_INDEX_LIST_H