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 14 #if EIGEN_HAS_CONSTEXPR && EIGEN_HAS_VARIADIC_TEMPLATES 15 16 #define EIGEN_HAS_INDEX_LIST 17 18 namespace Eigen { 19 20 /** \internal 21 * 22 * \class TensorIndexList 23 * \ingroup CXX11_Tensor_Module 24 * 25 * \brief Set of classes used to encode a set of Tensor dimensions/indices. 26 * 27 * The indices in the list can be known at compile time or at runtime. A mix 28 * of static and dynamic indices can also be provided if needed. The tensor 29 * code will attempt to take advantage of the indices that are known at 30 * compile time to optimize the code it generates. 31 * 32 * This functionality requires a c++11 compliant compiler. If your compiler 33 * is older you need to use arrays of indices instead. 34 * 35 * Several examples are provided in the cxx11_tensor_index_list.cpp file. 36 * 37 * \sa Tensor 38 */ 39 40 template <DenseIndex n> 41 struct type2index { 42 static const DenseIndex value = n; DenseIndextype2index43 EIGEN_DEVICE_FUNC constexpr operator DenseIndex() const { return n; } settype2index44 EIGEN_DEVICE_FUNC void set(DenseIndex val) { 45 eigen_assert(val == n); 46 } 47 }; 48 49 // This can be used with IndexPairList to get compile-time constant pairs, 50 // such as IndexPairList<type2indexpair<1,2>, type2indexpair<3,4>>(). 51 template <DenseIndex f, DenseIndex s> 52 struct type2indexpair { 53 static const DenseIndex first = f; 54 static const DenseIndex second = s; 55 56 constexpr EIGEN_DEVICE_FUNC operator IndexPair<DenseIndex>() const { 57 return IndexPair<DenseIndex>(f, s); 58 } 59 settype2indexpair60 EIGEN_DEVICE_FUNC void set(const IndexPair<DenseIndex>& val) { 61 eigen_assert(val.first == f); 62 eigen_assert(val.second == s); 63 } 64 }; 65 66 67 template<DenseIndex n> struct NumTraits<type2index<n> > 68 { 69 typedef DenseIndex Real; 70 enum { 71 IsComplex = 0, 72 RequireInitialization = false, 73 ReadCost = 1, 74 AddCost = 1, 75 MulCost = 1 76 }; 77 78 EIGEN_DEVICE_FUNC static inline Real epsilon() { return 0; } 79 EIGEN_DEVICE_FUNC static inline Real dummy_precision() { return 0; } 80 EIGEN_DEVICE_FUNC static inline Real highest() { return n; } 81 EIGEN_DEVICE_FUNC static inline Real lowest() { return n; } 82 }; 83 84 namespace internal { 85 template <typename T> 86 EIGEN_DEVICE_FUNC void update_value(T& val, DenseIndex new_val) { 87 val = new_val; 88 } 89 template <DenseIndex n> 90 EIGEN_DEVICE_FUNC void update_value(type2index<n>& val, DenseIndex new_val) { 91 val.set(new_val); 92 } 93 94 template <typename T> 95 EIGEN_DEVICE_FUNC void update_value(T& val, IndexPair<DenseIndex> new_val) { 96 val = new_val; 97 } 98 template <DenseIndex f, DenseIndex s> 99 EIGEN_DEVICE_FUNC void update_value(type2indexpair<f, s>& val, IndexPair<DenseIndex> new_val) { 100 val.set(new_val); 101 } 102 103 104 template <typename T> 105 struct is_compile_time_constant { 106 static constexpr bool value = false; 107 }; 108 109 template <DenseIndex idx> 110 struct is_compile_time_constant<type2index<idx> > { 111 static constexpr bool value = true; 112 }; 113 template <DenseIndex idx> 114 struct is_compile_time_constant<const type2index<idx> > { 115 static constexpr bool value = true; 116 }; 117 template <DenseIndex idx> 118 struct is_compile_time_constant<type2index<idx>& > { 119 static constexpr bool value = true; 120 }; 121 template <DenseIndex idx> 122 struct is_compile_time_constant<const type2index<idx>& > { 123 static constexpr bool value = true; 124 }; 125 126 template <DenseIndex f, DenseIndex s> 127 struct is_compile_time_constant<type2indexpair<f, s> > { 128 static constexpr bool value = true; 129 }; 130 template <DenseIndex f, DenseIndex s> 131 struct is_compile_time_constant<const type2indexpair<f, s> > { 132 static constexpr bool value = true; 133 }; 134 template <DenseIndex f, DenseIndex s> 135 struct is_compile_time_constant<type2indexpair<f, s>& > { 136 static constexpr bool value = true; 137 }; 138 template <DenseIndex f, DenseIndex s> 139 struct is_compile_time_constant<const type2indexpair<f, s>& > { 140 static constexpr bool value = true; 141 }; 142 143 144 template<typename... T> 145 struct IndexTuple; 146 147 template<typename T, typename... O> 148 struct IndexTuple<T, O...> { 149 EIGEN_DEVICE_FUNC constexpr IndexTuple() : head(), others() { } 150 EIGEN_DEVICE_FUNC constexpr IndexTuple(const T& v, const O... o) : head(v), others(o...) { } 151 152 constexpr static int count = 1 + sizeof...(O); 153 T head; 154 IndexTuple<O...> others; 155 typedef T Head; 156 typedef IndexTuple<O...> Other; 157 }; 158 159 template<typename T> 160 struct IndexTuple<T> { 161 EIGEN_DEVICE_FUNC constexpr IndexTuple() : head() { } 162 EIGEN_DEVICE_FUNC constexpr IndexTuple(const T& v) : head(v) { } 163 164 constexpr static int count = 1; 165 T head; 166 typedef T Head; 167 }; 168 169 170 template<int N, typename... T> 171 struct IndexTupleExtractor; 172 173 template<int N, typename T, typename... O> 174 struct IndexTupleExtractor<N, T, O...> { 175 176 typedef typename IndexTupleExtractor<N-1, O...>::ValType ValType; 177 178 EIGEN_DEVICE_FUNC static constexpr ValType& get_val(IndexTuple<T, O...>& val) { 179 return IndexTupleExtractor<N-1, O...>::get_val(val.others); 180 } 181 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); 184 } 185 template <typename V> 186 EIGEN_DEVICE_FUNC static void set_val(IndexTuple<T, O...>& val, V& new_val) { 187 IndexTupleExtractor<N-1, O...>::set_val(val.others, new_val); 188 } 189 190 }; 191 192 template<typename T, typename... O> 193 struct IndexTupleExtractor<0, T, O...> { 194 195 typedef T ValType; 196 197 EIGEN_DEVICE_FUNC static constexpr ValType& get_val(IndexTuple<T, O...>& val) { 198 return val.head; 199 } 200 EIGEN_DEVICE_FUNC static constexpr const ValType& get_val(const IndexTuple<T, O...>& val) { 201 return val.head; 202 } 203 template <typename V> 204 EIGEN_DEVICE_FUNC static void set_val(IndexTuple<T, O...>& val, V& new_val) { 205 val.head = new_val; 206 } 207 }; 208 209 210 211 template <int N, typename T, typename... O> 212 EIGEN_DEVICE_FUNC constexpr typename IndexTupleExtractor<N, T, O...>::ValType& array_get(IndexTuple<T, O...>& tuple) { 213 return IndexTupleExtractor<N, T, O...>::get_val(tuple); 214 } 215 template <int N, typename T, typename... O> 216 EIGEN_DEVICE_FUNC constexpr const typename IndexTupleExtractor<N, T, O...>::ValType& array_get(const IndexTuple<T, O...>& tuple) { 217 return IndexTupleExtractor<N, T, O...>::get_val(tuple); 218 } 219 template <typename T, typename... O> 220 struct array_size<IndexTuple<T, O...> > { 221 static const size_t value = IndexTuple<T, O...>::count; 222 }; 223 template <typename T, typename... O> 224 struct array_size<const IndexTuple<T, O...> > { 225 static const size_t value = IndexTuple<T, O...>::count; 226 }; 227 228 229 230 231 template <DenseIndex Idx, typename ValueT> 232 struct tuple_coeff { 233 template <typename... T> 234 EIGEN_DEVICE_FUNC static constexpr ValueT get(const DenseIndex i, const IndexTuple<T...>& t) { 235 // return array_get<Idx>(t) * (i == Idx) + tuple_coeff<Idx-1>::get(i, t) * (i != Idx); 236 return (i == Idx ? array_get<Idx>(t) : tuple_coeff<Idx-1, ValueT>::get(i, t)); 237 } 238 template <typename... T> 239 EIGEN_DEVICE_FUNC static void set(const DenseIndex i, IndexTuple<T...>& t, const ValueT& value) { 240 if (i == Idx) { 241 update_value(array_get<Idx>(t), value); 242 } else { 243 tuple_coeff<Idx-1, ValueT>::set(i, t, value); 244 } 245 } 246 247 template <typename... T> 248 EIGEN_DEVICE_FUNC static constexpr bool value_known_statically(const DenseIndex i, const IndexTuple<T...>& 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); 251 } 252 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); 257 } 258 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 && 263 array_get<Idx>(t) > array_get<Idx-1>(t) && 264 tuple_coeff<Idx-1, ValueT>::values_up_to_statically_known_to_increase(t); 265 } 266 }; 267 268 template <typename ValueT> 269 struct tuple_coeff<0, ValueT> { 270 template <typename... T> 271 EIGEN_DEVICE_FUNC static constexpr ValueT get(const DenseIndex /*i*/, const IndexTuple<T...>& t) { 272 // eigen_assert (i == 0); // gcc fails to compile assertions in constexpr 273 return array_get<0>(t)/* * (i == 0)*/; 274 } 275 template <typename... T> 276 EIGEN_DEVICE_FUNC static void set(const DenseIndex i, IndexTuple<T...>& t, const ValueT value) { 277 eigen_assert (i == 0); 278 update_value(array_get<0>(t), value); 279 } 280 template <typename... T> 281 EIGEN_DEVICE_FUNC static constexpr bool value_known_statically(const DenseIndex i, const IndexTuple<T...>&) { 282 return is_compile_time_constant<typename IndexTupleExtractor<0, T...>::ValType>::value & (i == 0); 283 } 284 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; 288 } 289 290 template <typename... T> 291 EIGEN_DEVICE_FUNC static constexpr bool values_up_to_statically_known_to_increase(const IndexTuple<T...>&) { 292 return true; 293 } 294 }; 295 } // namespace internal 296 297 298 299 template<typename FirstType, typename... OtherTypes> 300 struct IndexList : internal::IndexTuple<FirstType, OtherTypes...> { 301 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC constexpr DenseIndex operator[] (const DenseIndex i) const { 302 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >::value-1, DenseIndex>::get(i, *this); 303 } 304 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC constexpr DenseIndex get(const DenseIndex i) const { 305 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >::value-1, DenseIndex>::get(i, *this); 306 } 307 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC void set(const DenseIndex i, const DenseIndex value) { 308 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >::value-1, DenseIndex>::set(i, *this, value); 309 } 310 311 EIGEN_DEVICE_FUNC constexpr IndexList(const internal::IndexTuple<FirstType, OtherTypes...>& other) : internal::IndexTuple<FirstType, OtherTypes...>(other) { } 312 EIGEN_DEVICE_FUNC constexpr IndexList(FirstType& first, OtherTypes... other) : internal::IndexTuple<FirstType, OtherTypes...>(first, other...) { } 313 EIGEN_DEVICE_FUNC constexpr IndexList() : internal::IndexTuple<FirstType, OtherTypes...>() { } 314 315 EIGEN_DEVICE_FUNC constexpr bool value_known_statically(const DenseIndex i) const { 316 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >::value-1, DenseIndex>::value_known_statically(i, *this); 317 } 318 EIGEN_DEVICE_FUNC constexpr bool all_values_known_statically() const { 319 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >::value-1, DenseIndex>::values_up_to_known_statically(*this); 320 } 321 322 EIGEN_DEVICE_FUNC constexpr bool values_statically_known_to_increase() const { 323 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >::value-1, DenseIndex>::values_up_to_statically_known_to_increase(*this); 324 } 325 }; 326 327 328 template<typename FirstType, typename... OtherTypes> 329 constexpr IndexList<FirstType, OtherTypes...> make_index_list(FirstType val1, OtherTypes... other_vals) { 330 return IndexList<FirstType, OtherTypes...>(val1, other_vals...); 331 } 332 333 334 template<typename FirstType, typename... OtherTypes> 335 struct IndexPairList : internal::IndexTuple<FirstType, OtherTypes...> { 336 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC constexpr IndexPair<DenseIndex> operator[] (const DenseIndex i) const { 337 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >::value-1, IndexPair<DenseIndex>>::get(i, *this); 338 } 339 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC void set(const DenseIndex i, const IndexPair<DenseIndex> value) { 340 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...>>::value-1, IndexPair<DenseIndex> >::set(i, *this, value); 341 } 342 343 EIGEN_DEVICE_FUNC constexpr IndexPairList(const internal::IndexTuple<FirstType, OtherTypes...>& other) : internal::IndexTuple<FirstType, OtherTypes...>(other) { } 344 EIGEN_DEVICE_FUNC constexpr IndexPairList() : internal::IndexTuple<FirstType, OtherTypes...>() { } 345 346 EIGEN_DEVICE_FUNC constexpr bool value_known_statically(const DenseIndex i) const { 347 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >::value-1, DenseIndex>::value_known_statically(i, *this); 348 } 349 }; 350 351 namespace internal { 352 353 template<typename FirstType, typename... OtherTypes> size_t array_prod(const IndexList<FirstType, OtherTypes...>& sizes) { 354 size_t result = 1; 355 for (int i = 0; i < array_size<IndexList<FirstType, OtherTypes...> >::value; ++i) { 356 result *= sizes[i]; 357 } 358 return result; 359 } 360 361 template<typename FirstType, typename... OtherTypes> struct array_size<IndexList<FirstType, OtherTypes...> > { 362 static const size_t value = array_size<IndexTuple<FirstType, OtherTypes...> >::value; 363 }; 364 template<typename FirstType, typename... OtherTypes> struct array_size<const IndexList<FirstType, OtherTypes...> > { 365 static const size_t value = array_size<IndexTuple<FirstType, OtherTypes...> >::value; 366 }; 367 368 template<typename FirstType, typename... OtherTypes> struct array_size<IndexPairList<FirstType, OtherTypes...> > { 369 static const size_t value = std::tuple_size<std::tuple<FirstType, OtherTypes...> >::value; 370 }; 371 template<typename FirstType, typename... OtherTypes> struct array_size<const IndexPairList<FirstType, OtherTypes...> > { 372 static const size_t value = std::tuple_size<std::tuple<FirstType, OtherTypes...> >::value; 373 }; 374 375 template<DenseIndex N, typename FirstType, typename... OtherTypes> EIGEN_DEVICE_FUNC constexpr DenseIndex array_get(IndexList<FirstType, OtherTypes...>& a) { 376 return IndexTupleExtractor<N, FirstType, OtherTypes...>::get_val(a); 377 } 378 template<DenseIndex N, typename FirstType, typename... OtherTypes> EIGEN_DEVICE_FUNC constexpr DenseIndex array_get(const IndexList<FirstType, OtherTypes...>& a) { 379 return IndexTupleExtractor<N, FirstType, OtherTypes...>::get_val(a); 380 } 381 382 template <typename T> 383 struct index_known_statically_impl { 384 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex) { 385 return false; 386 } 387 }; 388 389 template <typename FirstType, typename... OtherTypes> 390 struct index_known_statically_impl<IndexList<FirstType, OtherTypes...> > { 391 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex i) { 392 return IndexList<FirstType, OtherTypes...>().value_known_statically(i); 393 } 394 }; 395 396 template <typename FirstType, typename... OtherTypes> 397 struct index_known_statically_impl<const IndexList<FirstType, OtherTypes...> > { 398 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex i) { 399 return IndexList<FirstType, OtherTypes...>().value_known_statically(i); 400 } 401 }; 402 403 404 template <typename T> 405 struct all_indices_known_statically_impl { 406 static constexpr bool run() { 407 return false; 408 } 409 }; 410 411 template <typename FirstType, typename... OtherTypes> 412 struct all_indices_known_statically_impl<IndexList<FirstType, OtherTypes...> > { 413 EIGEN_DEVICE_FUNC static constexpr bool run() { 414 return IndexList<FirstType, OtherTypes...>().all_values_known_statically(); 415 } 416 }; 417 418 template <typename FirstType, typename... OtherTypes> 419 struct all_indices_known_statically_impl<const IndexList<FirstType, OtherTypes...> > { 420 EIGEN_DEVICE_FUNC static constexpr bool run() { 421 return IndexList<FirstType, OtherTypes...>().all_values_known_statically(); 422 } 423 }; 424 425 426 template <typename T> 427 struct indices_statically_known_to_increase_impl { 428 EIGEN_DEVICE_FUNC static constexpr bool run() { 429 return false; 430 } 431 }; 432 433 template <typename FirstType, typename... OtherTypes> 434 struct indices_statically_known_to_increase_impl<IndexList<FirstType, OtherTypes...> > { 435 EIGEN_DEVICE_FUNC static constexpr bool run() { 436 return Eigen::IndexList<FirstType, OtherTypes...>().values_statically_known_to_increase(); 437 } 438 }; 439 440 template <typename FirstType, typename... OtherTypes> 441 struct indices_statically_known_to_increase_impl<const IndexList<FirstType, OtherTypes...> > { 442 EIGEN_DEVICE_FUNC static constexpr bool run() { 443 return Eigen::IndexList<FirstType, OtherTypes...>().values_statically_known_to_increase(); 444 } 445 }; 446 447 448 template <typename Tx> 449 struct index_statically_eq_impl { 450 EIGEN_DEVICE_FUNC static constexpr bool run(DenseIndex, DenseIndex) { 451 return false; 452 } 453 }; 454 455 template <typename FirstType, typename... OtherTypes> 456 struct index_statically_eq_impl<IndexList<FirstType, OtherTypes...> > { 457 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex i, const DenseIndex value) { 458 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 459 (IndexList<FirstType, OtherTypes...>().get(i) == value); 460 } 461 }; 462 463 template <typename FirstType, typename... OtherTypes> 464 struct index_statically_eq_impl<const IndexList<FirstType, OtherTypes...> > { 465 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex i, const DenseIndex value) { 466 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 467 (IndexList<FirstType, OtherTypes...>().get(i) == value); 468 } 469 }; 470 471 472 template <typename T> 473 struct index_statically_ne_impl { 474 EIGEN_DEVICE_FUNC static constexpr bool run(DenseIndex, DenseIndex) { 475 return false; 476 } 477 }; 478 479 template <typename FirstType, typename... OtherTypes> 480 struct index_statically_ne_impl<IndexList<FirstType, OtherTypes...> > { 481 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex i, const DenseIndex value) { 482 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 483 (IndexList<FirstType, OtherTypes...>().get(i) != value); 484 } 485 }; 486 487 template <typename FirstType, typename... OtherTypes> 488 struct index_statically_ne_impl<const IndexList<FirstType, OtherTypes...> > { 489 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex i, const DenseIndex value) { 490 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 491 (IndexList<FirstType, OtherTypes...>().get(i) != value); 492 } 493 }; 494 495 496 template <typename T> 497 struct index_statically_gt_impl { 498 EIGEN_DEVICE_FUNC static constexpr bool run(DenseIndex, DenseIndex) { 499 return false; 500 } 501 }; 502 503 template <typename FirstType, typename... OtherTypes> 504 struct index_statically_gt_impl<IndexList<FirstType, OtherTypes...> > { 505 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex i, const DenseIndex value) { 506 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 507 (IndexList<FirstType, OtherTypes...>().get(i) > value); 508 } 509 }; 510 511 template <typename FirstType, typename... OtherTypes> 512 struct index_statically_gt_impl<const IndexList<FirstType, OtherTypes...> > { 513 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex i, const DenseIndex value) { 514 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 515 (IndexList<FirstType, OtherTypes...>().get(i) > value); 516 } 517 }; 518 519 520 521 template <typename T> 522 struct index_statically_lt_impl { 523 EIGEN_DEVICE_FUNC static constexpr bool run(DenseIndex, DenseIndex) { 524 return false; 525 } 526 }; 527 528 template <typename FirstType, typename... OtherTypes> 529 struct index_statically_lt_impl<IndexList<FirstType, OtherTypes...> > { 530 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex i, const DenseIndex value) { 531 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 532 (IndexList<FirstType, OtherTypes...>().get(i) < value); 533 } 534 }; 535 536 template <typename FirstType, typename... OtherTypes> 537 struct index_statically_lt_impl<const IndexList<FirstType, OtherTypes...> > { 538 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex i, const DenseIndex value) { 539 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 540 (IndexList<FirstType, OtherTypes...>().get(i) < value); 541 } 542 }; 543 544 545 546 template <typename Tx> 547 struct index_pair_first_statically_eq_impl { 548 EIGEN_DEVICE_FUNC static constexpr bool run(DenseIndex, DenseIndex) { 549 return false; 550 } 551 }; 552 553 template <typename FirstType, typename... OtherTypes> 554 struct index_pair_first_statically_eq_impl<IndexPairList<FirstType, OtherTypes...> > { 555 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex i, const DenseIndex value) { 556 return IndexPairList<FirstType, OtherTypes...>().value_known_statically(i) & 557 (IndexPairList<FirstType, OtherTypes...>().operator[](i).first == value); 558 } 559 }; 560 561 template <typename FirstType, typename... OtherTypes> 562 struct index_pair_first_statically_eq_impl<const IndexPairList<FirstType, OtherTypes...> > { 563 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex i, const DenseIndex value) { 564 return IndexPairList<FirstType, OtherTypes...>().value_known_statically(i) & 565 (IndexPairList<FirstType, OtherTypes...>().operator[](i).first == value); 566 } 567 }; 568 569 570 571 template <typename Tx> 572 struct index_pair_second_statically_eq_impl { 573 EIGEN_DEVICE_FUNC static constexpr bool run(DenseIndex, DenseIndex) { 574 return false; 575 } 576 }; 577 578 template <typename FirstType, typename... OtherTypes> 579 struct index_pair_second_statically_eq_impl<IndexPairList<FirstType, OtherTypes...> > { 580 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex i, const DenseIndex value) { 581 return IndexPairList<FirstType, OtherTypes...>().value_known_statically(i) & 582 (IndexPairList<FirstType, OtherTypes...>().operator[](i).second == value); 583 } 584 }; 585 586 template <typename FirstType, typename... OtherTypes> 587 struct index_pair_second_statically_eq_impl<const IndexPairList<FirstType, OtherTypes...> > { 588 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex i, const DenseIndex value) { 589 return IndexPairList<FirstType, OtherTypes...>().value_known_statically(i) & 590 (IndexPairList<FirstType, OtherTypes...>().operator[](i).second == value); 591 } 592 }; 593 594 595 } // end namespace internal 596 } // end namespace Eigen 597 598 #else 599 600 namespace Eigen { 601 namespace internal { 602 603 template <typename T> 604 struct index_known_statically_impl { 605 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(const DenseIndex) { 606 return false; 607 } 608 }; 609 610 template <typename T> 611 struct all_indices_known_statically_impl { 612 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run() { 613 return false; 614 } 615 }; 616 617 template <typename T> 618 struct indices_statically_known_to_increase_impl { 619 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run() { 620 return false; 621 } 622 }; 623 624 template <typename T> 625 struct index_statically_eq_impl { 626 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(DenseIndex, DenseIndex) { 627 return false; 628 } 629 }; 630 631 template <typename T> 632 struct index_statically_ne_impl { 633 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(DenseIndex, DenseIndex) { 634 return false; 635 } 636 }; 637 638 template <typename T> 639 struct index_statically_gt_impl { 640 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(DenseIndex, DenseIndex) { 641 return false; 642 } 643 }; 644 645 template <typename T> 646 struct index_statically_lt_impl { 647 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(DenseIndex, DenseIndex) { 648 return false; 649 } 650 }; 651 652 template <typename Tx> 653 struct index_pair_first_statically_eq_impl { 654 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(DenseIndex, DenseIndex) { 655 return false; 656 } 657 }; 658 659 template <typename Tx> 660 struct index_pair_second_statically_eq_impl { 661 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(DenseIndex, DenseIndex) { 662 return false; 663 } 664 }; 665 666 667 668 } // end namespace internal 669 } // end namespace Eigen 670 671 #endif 672 673 674 namespace Eigen { 675 namespace internal { 676 template <typename T> 677 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_known_statically(DenseIndex i) { 678 return index_known_statically_impl<T>::run(i); 679 } 680 681 template <typename T> 682 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool all_indices_known_statically() { 683 return all_indices_known_statically_impl<T>::run(); 684 } 685 686 template <typename T> 687 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool indices_statically_known_to_increase() { 688 return indices_statically_known_to_increase_impl<T>::run(); 689 } 690 691 template <typename T> 692 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_statically_eq(DenseIndex i, DenseIndex value) { 693 return index_statically_eq_impl<T>::run(i, value); 694 } 695 696 template <typename T> 697 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_statically_ne(DenseIndex i, DenseIndex value) { 698 return index_statically_ne_impl<T>::run(i, value); 699 } 700 701 template <typename T> 702 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_statically_gt(DenseIndex i, DenseIndex value) { 703 return index_statically_gt_impl<T>::run(i, value); 704 } 705 706 template <typename T> 707 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_statically_lt(DenseIndex i, DenseIndex value) { 708 return index_statically_lt_impl<T>::run(i, value); 709 } 710 711 template <typename T> 712 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_pair_first_statically_eq(DenseIndex i, DenseIndex value) { 713 return index_pair_first_statically_eq_impl<T>::run(i, value); 714 } 715 716 template <typename T> 717 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_pair_second_statically_eq(DenseIndex i, DenseIndex value) { 718 return index_pair_second_statically_eq_impl<T>::run(i, value); 719 } 720 721 } // end namespace internal 722 } // end namespace Eigen 723 724 725 #endif // EIGEN_CXX11_TENSOR_TENSOR_INDEX_LIST_H 726