TensorIndexList.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_CXX11_TENSOR_TENSOR_INDEX_LIST_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_INDEX_LIST_H
12 
13 #if defined(EIGEN_HAS_CONSTEXPR) && defined(EIGEN_HAS_VARIADIC_TEMPLATES)
14 
15 #define EIGEN_HAS_INDEX_LIST
16 
17 namespace Eigen {
18 
39 template <DenseIndex n>
40 struct type2index {
41  static const DenseIndex value = n;
42  constexpr operator DenseIndex() const { return n; }
43  void set(DenseIndex val) {
44  eigen_assert(val == n);
45  }
46 };
47 
48 namespace internal {
49 template <typename T>
50 void update_value(T& val, DenseIndex new_val) {
51  val = new_val;
52 }
53 template <DenseIndex n>
54 void update_value(type2index<n>& val, DenseIndex new_val) {
55  val.set(new_val);
56 }
57 
58 template <typename T>
59 struct is_compile_time_constant {
60  static constexpr bool value = false;
61 };
62 
63 template <DenseIndex idx>
64 struct is_compile_time_constant<type2index<idx> > {
65  static constexpr bool value = true;
66 };
67 template <DenseIndex idx>
68 struct is_compile_time_constant<const type2index<idx> > {
69  static constexpr bool value = true;
70 };
71 template <DenseIndex idx>
72 struct is_compile_time_constant<type2index<idx>& > {
73  static constexpr bool value = true;
74 };
75 template <DenseIndex idx>
76 struct is_compile_time_constant<const type2index<idx>& > {
77  static constexpr bool value = true;
78 };
79 
80 template <DenseIndex Idx>
81 struct tuple_coeff {
82  template <typename... T>
83  static constexpr DenseIndex get(const DenseIndex i, const std::tuple<T...>& t) {
84  return std::get<Idx>(t) * (i == Idx) + tuple_coeff<Idx-1>::get(i, t) * (i != Idx);
85  }
86  template <typename... T>
87  static void set(const DenseIndex i, std::tuple<T...>& t, const DenseIndex value) {
88  if (i == Idx) {
89  update_value(std::get<Idx>(t), value);
90  } else {
91  tuple_coeff<Idx-1>::set(i, t, value);
92  }
93  }
94 
95  template <typename... T>
96  static constexpr bool value_known_statically(const DenseIndex i, const std::tuple<T...>& t) {
97  return ((i == Idx) & is_compile_time_constant<typename std::tuple_element<Idx, std::tuple<T...> >::type>::value) ||
98  tuple_coeff<Idx-1>::value_known_statically(i, t);
99  }
100 
101  template <typename... T>
102  static constexpr bool values_up_to_known_statically(const std::tuple<T...>& t) {
103  return is_compile_time_constant<typename std::tuple_element<Idx, std::tuple<T...> >::type>::value &&
104  tuple_coeff<Idx-1>::values_up_to_known_statically(t);
105  }
106 
107  template <typename... T>
108  static constexpr bool values_up_to_statically_known_to_increase(const std::tuple<T...>& t) {
109  return is_compile_time_constant<typename std::tuple_element<Idx, std::tuple<T...> >::type>::value &&
110  is_compile_time_constant<typename std::tuple_element<Idx-1, std::tuple<T...> >::type>::value &&
111  std::get<Idx>(t) > std::get<Idx-1>(t) &&
112  tuple_coeff<Idx-1>::values_up_to_statically_known_to_increase(t);
113  }
114 };
115 
116 template <>
117 struct tuple_coeff<0> {
118  template <typename... T>
119  static constexpr DenseIndex get(const DenseIndex i, const std::tuple<T...>& t) {
120  // eigen_assert (i == 0); // gcc fails to compile assertions in constexpr
121  return std::get<0>(t) * (i == 0);
122  }
123  template <typename... T>
124  static void set(const DenseIndex i, std::tuple<T...>& t, const DenseIndex value) {
125  eigen_assert (i == 0);
126  update_value(std::get<0>(t), value);
127  }
128  template <typename... T>
129  static constexpr bool value_known_statically(const DenseIndex i, const std::tuple<T...>&) {
130  // eigen_assert (i == 0); // gcc fails to compile assertions in constexpr
131  return is_compile_time_constant<typename std::tuple_element<0, std::tuple<T...> >::type>::value & (i == 0);
132  }
133 
134  template <typename... T>
135  static constexpr bool values_up_to_known_statically(const std::tuple<T...>&) {
136  return is_compile_time_constant<typename std::tuple_element<0, std::tuple<T...> >::type>::value;
137  }
138 
139  template <typename... T>
140  static constexpr bool values_up_to_statically_known_to_increase(const std::tuple<T...>&) {
141  return true;
142  }
143 };
144 } // namespace internal
145 
146 
147 template<typename FirstType, typename... OtherTypes>
148 struct IndexList : std::tuple<FirstType, OtherTypes...> {
149  EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC constexpr DenseIndex operator[] (const DenseIndex i) const {
150  return internal::tuple_coeff<std::tuple_size<std::tuple<FirstType, OtherTypes...> >::value-1>::get(i, *this);
151  }
152  EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC void set(const DenseIndex i, const DenseIndex value) {
153  return internal::tuple_coeff<std::tuple_size<std::tuple<FirstType, OtherTypes...> >::value-1>::set(i, *this, value);
154  }
155 
156  constexpr IndexList(const std::tuple<FirstType, OtherTypes...>& other) : std::tuple<FirstType, OtherTypes...>(other) { }
157  constexpr IndexList() : std::tuple<FirstType, OtherTypes...>() { }
158 
159  constexpr bool value_known_statically(const DenseIndex i) const {
160  return internal::tuple_coeff<std::tuple_size<std::tuple<FirstType, OtherTypes...> >::value-1>::value_known_statically(i, *this);
161  }
162  constexpr bool all_values_known_statically() const {
163  return internal::tuple_coeff<std::tuple_size<std::tuple<FirstType, OtherTypes...> >::value-1>::values_up_to_known_statically(*this);
164  }
165 
166  constexpr bool values_statically_known_to_increase() const {
167  return internal::tuple_coeff<std::tuple_size<std::tuple<FirstType, OtherTypes...> >::value-1>::values_up_to_statically_known_to_increase(*this);
168  }
169 };
170 
171 
172 template<typename FirstType, typename... OtherTypes>
173 constexpr IndexList<FirstType, OtherTypes...> make_index_list(FirstType val1, OtherTypes... other_vals) {
174  return std::make_tuple(val1, other_vals...);
175 }
176 
177 
178 namespace internal {
179 
180 template<typename FirstType, typename... OtherTypes> size_t array_prod(const IndexList<FirstType, OtherTypes...>& sizes) {
181  size_t result = 1;
182  for (int i = 0; i < array_size<IndexList<FirstType, OtherTypes...> >::value; ++i) {
183  result *= sizes[i];
184  }
185  return result;
186 }
187 
188 template<typename FirstType, typename... OtherTypes> struct array_size<IndexList<FirstType, OtherTypes...> > {
189  static const size_t value = std::tuple_size<std::tuple<FirstType, OtherTypes...> >::value;
190 };
191 template<typename FirstType, typename... OtherTypes> struct array_size<const IndexList<FirstType, OtherTypes...> > {
192  static const size_t value = std::tuple_size<std::tuple<FirstType, OtherTypes...> >::value;
193 };
194 
195 template<DenseIndex n, typename FirstType, typename... OtherTypes> constexpr DenseIndex array_get(IndexList<FirstType, OtherTypes...>& a) {
196  return std::get<n>(a);
197 }
198 template<DenseIndex n, typename FirstType, typename... OtherTypes> constexpr DenseIndex array_get(const IndexList<FirstType, OtherTypes...>& a) {
199  return std::get<n>(a);
200 }
201 
202 template <typename T>
203 struct index_known_statically {
204  constexpr bool operator() (DenseIndex) const {
205  return false;
206  }
207 };
208 
209 template <typename FirstType, typename... OtherTypes>
210 struct index_known_statically<IndexList<FirstType, OtherTypes...> > {
211  constexpr bool operator() (const DenseIndex i) const {
212  return IndexList<FirstType, OtherTypes...>().value_known_statically(i);
213  }
214 };
215 
216 template <typename FirstType, typename... OtherTypes>
217 struct index_known_statically<const IndexList<FirstType, OtherTypes...> > {
218  constexpr bool operator() (const DenseIndex i) const {
219  return IndexList<FirstType, OtherTypes...>().value_known_statically(i);
220  }
221 };
222 
223 template <typename T>
224 struct all_indices_known_statically {
225  constexpr bool operator() () const {
226  return false;
227  }
228 };
229 
230 template <typename FirstType, typename... OtherTypes>
231 struct all_indices_known_statically<IndexList<FirstType, OtherTypes...> > {
232  constexpr bool operator() () const {
233  return IndexList<FirstType, OtherTypes...>().all_values_known_statically();
234  }
235 };
236 
237 template <typename FirstType, typename... OtherTypes>
238 struct all_indices_known_statically<const IndexList<FirstType, OtherTypes...> > {
239  constexpr bool operator() () const {
240  return IndexList<FirstType, OtherTypes...>().all_values_known_statically();
241  }
242 };
243 
244 template <typename T>
245 struct indices_statically_known_to_increase {
246  constexpr bool operator() () const {
247  return false;
248  }
249 };
250 
251 template <typename FirstType, typename... OtherTypes>
252 struct indices_statically_known_to_increase<IndexList<FirstType, OtherTypes...> > {
253  constexpr bool operator() () const {
254  return IndexList<FirstType, OtherTypes...>().values_statically_known_to_increase();
255  }
256 };
257 
258 template <typename FirstType, typename... OtherTypes>
259 struct indices_statically_known_to_increase<const IndexList<FirstType, OtherTypes...> > {
260  constexpr bool operator() () const {
261  return IndexList<FirstType, OtherTypes...>().values_statically_known_to_increase();
262  }
263 };
264 
265 template <typename Tx>
266 struct index_statically_eq {
267  constexpr bool operator() (DenseIndex, DenseIndex) const {
268  return false;
269  }
270 };
271 
272 template <typename FirstType, typename... OtherTypes>
273 struct index_statically_eq<IndexList<FirstType, OtherTypes...> > {
274  constexpr bool operator() (const DenseIndex i, const DenseIndex value) const {
275  return IndexList<FirstType, OtherTypes...>().value_known_statically(i) &
276  (IndexList<FirstType, OtherTypes...>()[i] == value);
277  }
278 };
279 
280 template <typename FirstType, typename... OtherTypes>
281 struct index_statically_eq<const IndexList<FirstType, OtherTypes...> > {
282  constexpr bool operator() (const DenseIndex i, const DenseIndex value) const {
283  return IndexList<FirstType, OtherTypes...>().value_known_statically(i) &
284  (IndexList<FirstType, OtherTypes...>()[i] == value);
285  }
286 };
287 
288 template <typename T>
289 struct index_statically_ne {
290  constexpr bool operator() (DenseIndex, DenseIndex) const {
291  return false;
292  }
293 };
294 
295 template <typename FirstType, typename... OtherTypes>
296 struct index_statically_ne<IndexList<FirstType, OtherTypes...> > {
297  constexpr bool operator() (const DenseIndex i, const DenseIndex value) const {
298  return IndexList<FirstType, OtherTypes...>().value_known_statically(i) &
299  (IndexList<FirstType, OtherTypes...>()[i] != value);
300  }
301 };
302 
303 template <typename FirstType, typename... OtherTypes>
304 struct index_statically_ne<const IndexList<FirstType, OtherTypes...> > {
305  constexpr bool operator() (const DenseIndex i, const DenseIndex value) const {
306  return IndexList<FirstType, OtherTypes...>().value_known_statically(i) &
307  (IndexList<FirstType, OtherTypes...>()[i] != value);
308  }
309 };
310 
311 
312 template <typename T>
313 struct index_statically_gt {
314  constexpr bool operator() (DenseIndex, DenseIndex) const {
315  return false;
316  }
317 };
318 
319 template <typename FirstType, typename... OtherTypes>
320 struct index_statically_gt<IndexList<FirstType, OtherTypes...> > {
321  constexpr bool operator() (const DenseIndex i, const DenseIndex value) const {
322  return IndexList<FirstType, OtherTypes...>().value_known_statically(i) &
323  (IndexList<FirstType, OtherTypes...>()[i] > value);
324  }
325 };
326 
327 template <typename FirstType, typename... OtherTypes>
328 struct index_statically_gt<const IndexList<FirstType, OtherTypes...> > {
329  constexpr bool operator() (const DenseIndex i, const DenseIndex value) const {
330  return IndexList<FirstType, OtherTypes...>().value_known_statically(i) &
331  (IndexList<FirstType, OtherTypes...>()[i] > value);
332  }
333 };
334 
335 template <typename T>
336 struct index_statically_lt {
337  constexpr bool operator() (DenseIndex, DenseIndex) const {
338  return false;
339  }
340 };
341 
342 template <typename FirstType, typename... OtherTypes>
343 struct index_statically_lt<IndexList<FirstType, OtherTypes...> > {
344  constexpr bool operator() (const DenseIndex i, const DenseIndex value) const {
345  return IndexList<FirstType, OtherTypes...>().value_known_statically(i) &
346  (IndexList<FirstType, OtherTypes...>()[i] < value);
347  }
348 };
349 
350 template <typename FirstType, typename... OtherTypes>
351 struct index_statically_lt<const IndexList<FirstType, OtherTypes...> > {
352  constexpr bool operator() (const DenseIndex i, const DenseIndex value) const {
353  return IndexList<FirstType, OtherTypes...>().value_known_statically(i) &
354  (IndexList<FirstType, OtherTypes...>()[i] < value);
355  }
356 };
357 
358 } // end namespace internal
359 } // end namespace Eigen
360 
361 #else
362 
363 namespace Eigen {
364 namespace internal {
365 
366 // No C++11 support
367 template <typename T>
368 struct index_known_statically {
369  EIGEN_ALWAYS_INLINE EIGEN_DEVICE_FUNC bool operator() (DenseIndex) const{
370  return false;
371  }
372 };
373 
374 template <typename T>
375 struct all_indices_known_statically {
376  EIGEN_ALWAYS_INLINE EIGEN_DEVICE_FUNC bool operator() () const {
377  return false;
378  }
379 };
380 
381 template <typename T>
382 struct indices_statically_known_to_increase {
383  EIGEN_ALWAYS_INLINE EIGEN_DEVICE_FUNC bool operator() () const {
384  return false;
385  }
386 };
387 
388 template <typename T>
389 struct index_statically_eq {
390  EIGEN_ALWAYS_INLINE EIGEN_DEVICE_FUNC bool operator() (DenseIndex, DenseIndex) const{
391  return false;
392  }
393 };
394 
395 template <typename T>
396 struct index_statically_ne {
397  EIGEN_ALWAYS_INLINE EIGEN_DEVICE_FUNC bool operator() (DenseIndex, DenseIndex) const{
398  return false;
399  }
400 };
401 
402 template <typename T>
403 struct index_statically_gt {
404  EIGEN_ALWAYS_INLINE EIGEN_DEVICE_FUNC bool operator() (DenseIndex, DenseIndex) const{
405  return false;
406  }
407 };
408 
409 template <typename T>
410 struct index_statically_lt {
411  EIGEN_ALWAYS_INLINE EIGEN_DEVICE_FUNC bool operator() (DenseIndex, DenseIndex) const{
412  return false;
413  }
414 };
415 
416 } // end namespace internal
417 } // end namespace Eigen
418 
419 #endif
420 
421 #endif // EIGEN_CXX11_TENSOR_TENSOR_INDEX_LIST_H
Namespace containing all symbols from the Eigen library.
Definition: CXX11Meta.h:13