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 18namespace 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 40template <DenseIndex n> 41struct type2index { 42 static const DenseIndex value = n; 43 EIGEN_DEVICE_FUNC constexpr operator DenseIndex() const { return n; } 44 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>>(). 51template <DenseIndex f, DenseIndex s> 52struct 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 60 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 67template<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 84namespace internal { 85template <typename T> 86EIGEN_DEVICE_FUNC void update_value(T& val, DenseIndex new_val) { 87 val = new_val; 88} 89template <DenseIndex n> 90EIGEN_DEVICE_FUNC void update_value(type2index<n>& val, DenseIndex new_val) { 91 val.set(new_val); 92} 93 94template <typename T> 95EIGEN_DEVICE_FUNC void update_value(T& val, IndexPair<DenseIndex> new_val) { 96 val = new_val; 97} 98template <DenseIndex f, DenseIndex s> 99EIGEN_DEVICE_FUNC void update_value(type2indexpair<f, s>& val, IndexPair<DenseIndex> new_val) { 100 val.set(new_val); 101} 102 103 104template <typename T> 105struct is_compile_time_constant { 106 static constexpr bool value = false; 107}; 108 109template <DenseIndex idx> 110struct is_compile_time_constant<type2index<idx> > { 111 static constexpr bool value = true; 112}; 113template <DenseIndex idx> 114struct is_compile_time_constant<const type2index<idx> > { 115 static constexpr bool value = true; 116}; 117template <DenseIndex idx> 118struct is_compile_time_constant<type2index<idx>& > { 119 static constexpr bool value = true; 120}; 121template <DenseIndex idx> 122struct is_compile_time_constant<const type2index<idx>& > { 123 static constexpr bool value = true; 124}; 125 126template <DenseIndex f, DenseIndex s> 127struct is_compile_time_constant<type2indexpair<f, s> > { 128 static constexpr bool value = true; 129}; 130template <DenseIndex f, DenseIndex s> 131struct is_compile_time_constant<const type2indexpair<f, s> > { 132 static constexpr bool value = true; 133}; 134template <DenseIndex f, DenseIndex s> 135struct is_compile_time_constant<type2indexpair<f, s>& > { 136 static constexpr bool value = true; 137}; 138template <DenseIndex f, DenseIndex s> 139struct is_compile_time_constant<const type2indexpair<f, s>& > { 140 static constexpr bool value = true; 141}; 142 143 144template<typename... T> 145struct IndexTuple; 146 147template<typename T, typename... O> 148struct 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 159template<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 170template<int N, typename... T> 171struct IndexTupleExtractor; 172 173template<int N, typename T, typename... O> 174struct 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 192template<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 211template <int N, typename T, typename... O> 212EIGEN_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} 215template <int N, typename T, typename... O> 216EIGEN_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} 219template <typename T, typename... O> 220 struct array_size<IndexTuple<T, O...> > { 221 static const size_t value = IndexTuple<T, O...>::count; 222}; 223template <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 231template <DenseIndex Idx, typename ValueT> 232struct 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 268template <typename ValueT> 269struct 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 299template<typename FirstType, typename... OtherTypes> 300struct 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 328template<typename FirstType, typename... OtherTypes> 329constexpr IndexList<FirstType, OtherTypes...> make_index_list(FirstType val1, OtherTypes... other_vals) { 330 return IndexList<FirstType, OtherTypes...>(val1, other_vals...); 331} 332 333 334template<typename FirstType, typename... OtherTypes> 335struct 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 351namespace internal { 352 353template<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 361template<typename FirstType, typename... OtherTypes> struct array_size<IndexList<FirstType, OtherTypes...> > { 362 static const size_t value = array_size<IndexTuple<FirstType, OtherTypes...> >::value; 363}; 364template<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 368template<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}; 371template<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 375template<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} 378template<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 382template <typename T> 383struct index_known_statically_impl { 384 EIGEN_DEVICE_FUNC static constexpr bool run(const DenseIndex) { 385 return false; 386 } 387}; 388 389template <typename FirstType, typename... OtherTypes> 390struct 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 396template <typename FirstType, typename... OtherTypes> 397struct 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 404template <typename T> 405struct all_indices_known_statically_impl { 406 static constexpr bool run() { 407 return false; 408 } 409}; 410 411template <typename FirstType, typename... OtherTypes> 412struct 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 418template <typename FirstType, typename... OtherTypes> 419struct 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 426template <typename T> 427struct indices_statically_known_to_increase_impl { 428 EIGEN_DEVICE_FUNC static constexpr bool run() { 429 return false; 430 } 431}; 432 433template <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 440template <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 448template <typename Tx> 449struct index_statically_eq_impl { 450 EIGEN_DEVICE_FUNC static constexpr bool run(DenseIndex, DenseIndex) { 451 return false; 452 } 453}; 454 455template <typename FirstType, typename... OtherTypes> 456struct 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 463template <typename FirstType, typename... OtherTypes> 464struct 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 472template <typename T> 473struct index_statically_ne_impl { 474 EIGEN_DEVICE_FUNC static constexpr bool run(DenseIndex, DenseIndex) { 475 return false; 476 } 477}; 478 479template <typename FirstType, typename... OtherTypes> 480struct 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 487template <typename FirstType, typename... OtherTypes> 488struct 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 496template <typename T> 497struct index_statically_gt_impl { 498 EIGEN_DEVICE_FUNC static constexpr bool run(DenseIndex, DenseIndex) { 499 return false; 500 } 501}; 502 503template <typename FirstType, typename... OtherTypes> 504struct 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 511template <typename FirstType, typename... OtherTypes> 512struct 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 521template <typename T> 522struct index_statically_lt_impl { 523 EIGEN_DEVICE_FUNC static constexpr bool run(DenseIndex, DenseIndex) { 524 return false; 525 } 526}; 527 528template <typename FirstType, typename... OtherTypes> 529struct 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 536template <typename FirstType, typename... OtherTypes> 537struct 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 546template <typename Tx> 547struct index_pair_first_statically_eq_impl { 548 EIGEN_DEVICE_FUNC static constexpr bool run(DenseIndex, DenseIndex) { 549 return false; 550 } 551}; 552 553template <typename FirstType, typename... OtherTypes> 554struct 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 561template <typename FirstType, typename... OtherTypes> 562struct 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 571template <typename Tx> 572struct index_pair_second_statically_eq_impl { 573 EIGEN_DEVICE_FUNC static constexpr bool run(DenseIndex, DenseIndex) { 574 return false; 575 } 576}; 577 578template <typename FirstType, typename... OtherTypes> 579struct 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 586template <typename FirstType, typename... OtherTypes> 587struct 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 600namespace Eigen { 601namespace internal { 602 603template <typename T> 604struct index_known_statically_impl { 605 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(const DenseIndex) { 606 return false; 607 } 608}; 609 610template <typename T> 611struct all_indices_known_statically_impl { 612 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run() { 613 return false; 614 } 615}; 616 617template <typename T> 618struct indices_statically_known_to_increase_impl { 619 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run() { 620 return false; 621 } 622}; 623 624template <typename T> 625struct index_statically_eq_impl { 626 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(DenseIndex, DenseIndex) { 627 return false; 628 } 629}; 630 631template <typename T> 632struct index_statically_ne_impl { 633 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(DenseIndex, DenseIndex) { 634 return false; 635 } 636}; 637 638template <typename T> 639struct index_statically_gt_impl { 640 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(DenseIndex, DenseIndex) { 641 return false; 642 } 643}; 644 645template <typename T> 646struct index_statically_lt_impl { 647 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(DenseIndex, DenseIndex) { 648 return false; 649 } 650}; 651 652template <typename Tx> 653struct index_pair_first_statically_eq_impl { 654 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool run(DenseIndex, DenseIndex) { 655 return false; 656 } 657}; 658 659template <typename Tx> 660struct 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 674namespace Eigen { 675namespace internal { 676template <typename T> 677static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool index_known_statically(DenseIndex i) { 678 return index_known_statically_impl<T>::run(i); 679} 680 681template <typename T> 682static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool all_indices_known_statically() { 683 return all_indices_known_statically_impl<T>::run(); 684} 685 686template <typename T> 687static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR bool indices_statically_known_to_increase() { 688 return indices_statically_known_to_increase_impl<T>::run(); 689} 690 691template <typename T> 692static 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 696template <typename T> 697static 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 701template <typename T> 702static 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 706template <typename T> 707static 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 711template <typename T> 712static 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 716template <typename T> 717static 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