1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2014 Benoit Steiner <[email protected]> 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 <Index n> 41 struct type2index { 42 static const Index value = n; Indextype2index43 EIGEN_DEVICE_FUNC constexpr operator Index() const { return n; } settype2index44 EIGEN_DEVICE_FUNC void set(Index 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 <Index f, Index s> 52 struct type2indexpair { 53 static const Index first = f; 54 static const Index second = s; 55 56 constexpr EIGEN_DEVICE_FUNC operator IndexPair<Index>() const { 57 return IndexPair<Index>(f, s); 58 } 59 settype2indexpair60 EIGEN_DEVICE_FUNC void set(const IndexPair<Index>& val) { 61 eigen_assert(val.first == f); 62 eigen_assert(val.second == s); 63 } 64 }; 65 66 67 template<Index n> struct NumTraits<type2index<n> > 68 { 69 typedef Index 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 EIGEN_CONSTEXPR EIGEN_STRONG_INLINE Real epsilon() { return 0; } 79 EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR EIGEN_STRONG_INLINE Real dummy_precision() { return 0; } 80 EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR EIGEN_STRONG_INLINE Real highest() { return n; } 81 EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR EIGEN_STRONG_INLINE Real lowest() { return n; } 82 }; 83 84 namespace internal { 85 template <typename T> 86 EIGEN_DEVICE_FUNC void update_value(T& val, Index new_val) { 87 val = internal::convert_index<T>(new_val); 88 } 89 template <Index n> 90 EIGEN_DEVICE_FUNC void update_value(type2index<n>& val, Index new_val) { 91 val.set(new_val); 92 } 93 94 template <typename T> 95 EIGEN_DEVICE_FUNC void update_value(T& val, IndexPair<Index> new_val) { 96 val = new_val; 97 } 98 template <Index f, Index s> 99 EIGEN_DEVICE_FUNC void update_value(type2indexpair<f, s>& val, IndexPair<Index> 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 <Index idx> 110 struct is_compile_time_constant<type2index<idx> > { 111 static constexpr bool value = true; 112 }; 113 template <Index idx> 114 struct is_compile_time_constant<const type2index<idx> > { 115 static constexpr bool value = true; 116 }; 117 template <Index idx> 118 struct is_compile_time_constant<type2index<idx>& > { 119 static constexpr bool value = true; 120 }; 121 template <Index idx> 122 struct is_compile_time_constant<const type2index<idx>& > { 123 static constexpr bool value = true; 124 }; 125 126 template <Index f, Index s> 127 struct is_compile_time_constant<type2indexpair<f, s> > { 128 static constexpr bool value = true; 129 }; 130 template <Index f, Index s> 131 struct is_compile_time_constant<const type2indexpair<f, s> > { 132 static constexpr bool value = true; 133 }; 134 template <Index f, Index s> 135 struct is_compile_time_constant<type2indexpair<f, s>& > { 136 static constexpr bool value = true; 137 }; 138 template <Index f, Index 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 <Index Idx, typename ValueT> 232 struct tuple_coeff { 233 template <typename... T> 234 EIGEN_DEVICE_FUNC static constexpr ValueT get(const Index 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 Index 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 Index 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 Index /*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 Index 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 Index 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 Index operator[] (const Index i) const { 302 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >::value-1, Index>::get(i, *this); 303 } 304 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC constexpr Index get(const Index i) const { 305 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >::value-1, Index>::get(i, *this); 306 } 307 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC void set(const Index i, const Index value) { 308 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >::value-1, Index>::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 Index i) const { 316 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >::value-1, Index>::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, Index>::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, Index>::values_up_to_statically_known_to_increase(*this); 324 } 325 }; 326 327 template <typename FirstType, typename... OtherTypes> 328 std::ostream& operator<<(std::ostream& os, 329 const IndexList<FirstType, OtherTypes...>& dims) { 330 os << "["; 331 for (size_t i = 0; i < 1 + sizeof...(OtherTypes); ++i) { 332 if (i > 0) os << ", "; 333 os << dims[i]; 334 } 335 os << "]"; 336 return os; 337 } 338 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...); 342 } 343 344 345 template<typename FirstType, typename... OtherTypes> 346 struct IndexPairList : internal::IndexTuple<FirstType, OtherTypes...> { 347 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC constexpr IndexPair<Index> operator[] (const Index i) const { 348 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >::value-1, IndexPair<Index>>::get(i, *this); 349 } 350 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC void set(const Index i, const IndexPair<Index> value) { 351 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...>>::value-1, IndexPair<Index> >::set(i, *this, value); 352 } 353 354 EIGEN_DEVICE_FUNC constexpr IndexPairList(const internal::IndexTuple<FirstType, OtherTypes...>& other) : internal::IndexTuple<FirstType, OtherTypes...>(other) { } 355 EIGEN_DEVICE_FUNC constexpr IndexPairList() : internal::IndexTuple<FirstType, OtherTypes...>() { } 356 357 EIGEN_DEVICE_FUNC constexpr bool value_known_statically(const Index i) const { 358 return internal::tuple_coeff<internal::array_size<internal::IndexTuple<FirstType, OtherTypes...> >::value-1, Index>::value_known_statically(i, *this); 359 } 360 }; 361 362 namespace internal { 363 364 template<typename FirstType, typename... OtherTypes> 365 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index array_prod(const IndexList<FirstType, OtherTypes...>& sizes) { 366 Index result = 1; 367 EIGEN_UNROLL_LOOP 368 for (size_t i = 0; i < array_size<IndexList<FirstType, OtherTypes...> >::value; ++i) { 369 result *= sizes[i]; 370 } 371 return result; 372 } 373 374 template<typename FirstType, typename... OtherTypes> struct array_size<IndexList<FirstType, OtherTypes...> > { 375 static const size_t value = array_size<IndexTuple<FirstType, OtherTypes...> >::value; 376 }; 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; 379 }; 380 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; 383 }; 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; 386 }; 387 388 template<Index N, typename FirstType, typename... OtherTypes> EIGEN_DEVICE_FUNC constexpr Index array_get(IndexList<FirstType, OtherTypes...>& a) { 389 return IndexTupleExtractor<N, FirstType, OtherTypes...>::get_val(a); 390 } 391 template<Index N, typename FirstType, typename... OtherTypes> EIGEN_DEVICE_FUNC constexpr Index array_get(const IndexList<FirstType, OtherTypes...>& a) { 392 return IndexTupleExtractor<N, FirstType, OtherTypes...>::get_val(a); 393 } 394 395 template <typename T> 396 struct index_known_statically_impl { 397 EIGEN_DEVICE_FUNC static constexpr bool run(const Index) { 398 return false; 399 } 400 }; 401 402 template <typename FirstType, typename... OtherTypes> 403 struct index_known_statically_impl<IndexList<FirstType, OtherTypes...> > { 404 EIGEN_DEVICE_FUNC static constexpr bool run(const Index i) { 405 return IndexList<FirstType, OtherTypes...>().value_known_statically(i); 406 } 407 }; 408 409 template <typename FirstType, typename... OtherTypes> 410 struct index_known_statically_impl<const IndexList<FirstType, OtherTypes...> > { 411 EIGEN_DEVICE_FUNC static constexpr bool run(const Index i) { 412 return IndexList<FirstType, OtherTypes...>().value_known_statically(i); 413 } 414 }; 415 416 417 template <typename T> 418 struct all_indices_known_statically_impl { 419 static constexpr bool run() { 420 return false; 421 } 422 }; 423 424 template <typename FirstType, typename... OtherTypes> 425 struct all_indices_known_statically_impl<IndexList<FirstType, OtherTypes...> > { 426 EIGEN_DEVICE_FUNC static constexpr bool run() { 427 return IndexList<FirstType, OtherTypes...>().all_values_known_statically(); 428 } 429 }; 430 431 template <typename FirstType, typename... OtherTypes> 432 struct all_indices_known_statically_impl<const IndexList<FirstType, OtherTypes...> > { 433 EIGEN_DEVICE_FUNC static constexpr bool run() { 434 return IndexList<FirstType, OtherTypes...>().all_values_known_statically(); 435 } 436 }; 437 438 439 template <typename T> 440 struct indices_statically_known_to_increase_impl { 441 EIGEN_DEVICE_FUNC static constexpr bool run() { 442 return false; 443 } 444 }; 445 446 template <typename FirstType, typename... OtherTypes> 447 struct indices_statically_known_to_increase_impl<IndexList<FirstType, OtherTypes...> > { 448 EIGEN_DEVICE_FUNC static constexpr bool run() { 449 return Eigen::IndexList<FirstType, OtherTypes...>().values_statically_known_to_increase(); 450 } 451 }; 452 453 template <typename FirstType, typename... OtherTypes> 454 struct indices_statically_known_to_increase_impl<const IndexList<FirstType, OtherTypes...> > { 455 EIGEN_DEVICE_FUNC static constexpr bool run() { 456 return Eigen::IndexList<FirstType, OtherTypes...>().values_statically_known_to_increase(); 457 } 458 }; 459 460 461 template <typename Tx> 462 struct index_statically_eq_impl { 463 EIGEN_DEVICE_FUNC static constexpr bool run(Index, Index) { 464 return false; 465 } 466 }; 467 468 template <typename FirstType, typename... OtherTypes> 469 struct index_statically_eq_impl<IndexList<FirstType, OtherTypes...> > { 470 EIGEN_DEVICE_FUNC static constexpr bool run(const Index i, const Index value) { 471 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 472 (IndexList<FirstType, OtherTypes...>().get(i) == value); 473 } 474 }; 475 476 template <typename FirstType, typename... OtherTypes> 477 struct index_statically_eq_impl<const IndexList<FirstType, OtherTypes...> > { 478 EIGEN_DEVICE_FUNC static constexpr bool run(const Index i, const Index value) { 479 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 480 (IndexList<FirstType, OtherTypes...>().get(i) == value); 481 } 482 }; 483 484 485 template <typename T> 486 struct index_statically_ne_impl { 487 EIGEN_DEVICE_FUNC static constexpr bool run(Index, Index) { 488 return false; 489 } 490 }; 491 492 template <typename FirstType, typename... OtherTypes> 493 struct index_statically_ne_impl<IndexList<FirstType, OtherTypes...> > { 494 EIGEN_DEVICE_FUNC static constexpr bool run(const Index i, const Index value) { 495 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 496 (IndexList<FirstType, OtherTypes...>().get(i) != value); 497 } 498 }; 499 500 template <typename FirstType, typename... OtherTypes> 501 struct index_statically_ne_impl<const IndexList<FirstType, OtherTypes...> > { 502 EIGEN_DEVICE_FUNC static constexpr bool run(const Index i, const Index value) { 503 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 504 (IndexList<FirstType, OtherTypes...>().get(i) != value); 505 } 506 }; 507 508 509 template <typename T> 510 struct index_statically_gt_impl { 511 EIGEN_DEVICE_FUNC static constexpr bool run(Index, Index) { 512 return false; 513 } 514 }; 515 516 template <typename FirstType, typename... OtherTypes> 517 struct index_statically_gt_impl<IndexList<FirstType, OtherTypes...> > { 518 EIGEN_DEVICE_FUNC static constexpr bool run(const Index i, const Index value) { 519 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 520 (IndexList<FirstType, OtherTypes...>().get(i) > value); 521 } 522 }; 523 524 template <typename FirstType, typename... OtherTypes> 525 struct index_statically_gt_impl<const IndexList<FirstType, OtherTypes...> > { 526 EIGEN_DEVICE_FUNC static constexpr bool run(const Index i, const Index value) { 527 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 528 (IndexList<FirstType, OtherTypes...>().get(i) > value); 529 } 530 }; 531 532 533 534 template <typename T> 535 struct index_statically_lt_impl { 536 EIGEN_DEVICE_FUNC static constexpr bool run(Index, Index) { 537 return false; 538 } 539 }; 540 541 template <typename FirstType, typename... OtherTypes> 542 struct index_statically_lt_impl<IndexList<FirstType, OtherTypes...> > { 543 EIGEN_DEVICE_FUNC static constexpr bool run(const Index i, const Index value) { 544 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 545 (IndexList<FirstType, OtherTypes...>().get(i) < value); 546 } 547 }; 548 549 template <typename FirstType, typename... OtherTypes> 550 struct index_statically_lt_impl<const IndexList<FirstType, OtherTypes...> > { 551 EIGEN_DEVICE_FUNC static constexpr bool run(const Index i, const Index value) { 552 return IndexList<FirstType, OtherTypes...>().value_known_statically(i) & 553 (IndexList<FirstType, OtherTypes...>().get(i) < value); 554 } 555 }; 556 557 558 559 template <typename Tx> 560 struct index_pair_first_statically_eq_impl { 561 EIGEN_DEVICE_FUNC static constexpr bool run(Index, Index) { 562 return false; 563 } 564 }; 565 566 template <typename FirstType, typename... OtherTypes> 567 struct index_pair_first_statically_eq_impl<IndexPairList<FirstType, OtherTypes...> > { 568 EIGEN_DEVICE_FUNC static constexpr bool run(const Index i, const Index value) { 569 return IndexPairList<FirstType, OtherTypes...>().value_known_statically(i) & 570 (IndexPairList<FirstType, OtherTypes...>().operator[](i).first == value); 571 } 572 }; 573 574 template <typename FirstType, typename... OtherTypes> 575 struct index_pair_first_statically_eq_impl<const IndexPairList<FirstType, OtherTypes...> > { 576 EIGEN_DEVICE_FUNC static constexpr bool run(const Index i, const Index value) { 577 return IndexPairList<FirstType, OtherTypes...>().value_known_statically(i) & 578 (IndexPairList<FirstType, OtherTypes...>().operator[](i).first == value); 579 } 580 }; 581 582 583 584 template <typename Tx> 585 struct index_pair_second_statically_eq_impl { 586 EIGEN_DEVICE_FUNC static constexpr bool run(Index, Index) { 587 return false; 588 } 589 }; 590 591 template <typename FirstType, typename... OtherTypes> 592 struct index_pair_second_statically_eq_impl<IndexPairList<FirstType, OtherTypes...> > { 593 EIGEN_DEVICE_FUNC static constexpr bool run(const Index i, const Index value) { 594 return IndexPairList<FirstType, OtherTypes...>().value_known_statically(i) & 595 (IndexPairList<FirstType, OtherTypes...>().operator[](i).second == value); 596 } 597 }; 598 599 template <typename FirstType, typename... OtherTypes> 600 struct index_pair_second_statically_eq_impl<const IndexPairList<FirstType, OtherTypes...> > { 601 EIGEN_DEVICE_FUNC static constexpr bool run(const Index i, const Index value) { 602 return IndexPairList<FirstType, OtherTypes...>().value_known_statically(i) & 603 (IndexPairList<FirstType, OtherTypes...>().operator[](i).second == value); 604 } 605 }; 606 607 608 } // end namespace internal 609 } // end namespace Eigen 610 611 #else 612 613 namespace Eigen { 614 namespace internal { 615 616 template <typename T> 617 struct index_known_statically_impl { 618 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(const Index) { 619 return false; 620 } 621 }; 622 623 template <typename T> 624 struct all_indices_known_statically_impl { 625 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run() { 626 return false; 627 } 628 }; 629 630 template <typename T> 631 struct indices_statically_known_to_increase_impl { 632 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run() { 633 return false; 634 } 635 }; 636 637 template <typename T> 638 struct index_statically_eq_impl { 639 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(Index, Index) { 640 return false; 641 } 642 }; 643 644 template <typename T> 645 struct index_statically_ne_impl { 646 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(Index, Index) { 647 return false; 648 } 649 }; 650 651 template <typename T> 652 struct index_statically_gt_impl { 653 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(Index, Index) { 654 return false; 655 } 656 }; 657 658 template <typename T> 659 struct index_statically_lt_impl { 660 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(Index, Index) { 661 return false; 662 } 663 }; 664 665 template <typename Tx> 666 struct index_pair_first_statically_eq_impl { 667 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(Index, Index) { 668 return false; 669 } 670 }; 671 672 template <typename Tx> 673 struct index_pair_second_statically_eq_impl { 674 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(Index, Index) { 675 return false; 676 } 677 }; 678 679 680 681 } // end namespace internal 682 } // end namespace Eigen 683 684 #endif 685 686 687 namespace Eigen { 688 namespace internal { 689 template <typename T> 690 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_known_statically(Index i) { 691 return index_known_statically_impl<T>::run(i); 692 } 693 694 template <typename T> 695 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool all_indices_known_statically() { 696 return all_indices_known_statically_impl<T>::run(); 697 } 698 699 template <typename T> 700 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool indices_statically_known_to_increase() { 701 return indices_statically_known_to_increase_impl<T>::run(); 702 } 703 704 template <typename T> 705 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_statically_eq(Index i, Index value) { 706 return index_statically_eq_impl<T>::run(i, value); 707 } 708 709 template <typename T> 710 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_statically_ne(Index i, Index value) { 711 return index_statically_ne_impl<T>::run(i, value); 712 } 713 714 template <typename T> 715 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_statically_gt(Index i, Index value) { 716 return index_statically_gt_impl<T>::run(i, value); 717 } 718 719 template <typename T> 720 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_statically_lt(Index i, Index value) { 721 return index_statically_lt_impl<T>::run(i, value); 722 } 723 724 template <typename T> 725 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_pair_first_statically_eq(Index i, Index value) { 726 return index_pair_first_statically_eq_impl<T>::run(i, value); 727 } 728 729 template <typename T> 730 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_pair_second_statically_eq(Index i, Index value) { 731 return index_pair_second_statically_eq_impl<T>::run(i, value); 732 } 733 734 } // end namespace internal 735 } // end namespace Eigen 736 737 738 #endif // EIGEN_CXX11_TENSOR_TENSOR_INDEX_LIST_H 739