cart-elc

Source code for CART-ELC
git clone git://git.laack.co/cart-elc.git
Log | Files | Refs | README | LICENSE

EmulateArray.h (8155B)


      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_EMULATE_ARRAY_H
     11 #define EIGEN_EMULATE_ARRAY_H
     12 
     13 
     14 
     15 // The array class is only available starting with cxx11. Emulate our own here
     16 // if needed. Beware, msvc still doesn't advertise itself as a c++11 compiler!
     17 // Moreover, CUDA doesn't support the STL containers, so we use our own instead.
     18 #if (__cplusplus <= 199711L && EIGEN_COMP_MSVC < 1900) || defined(EIGEN_GPUCC) || defined(EIGEN_AVOID_STL_ARRAY)
     19 
     20 namespace Eigen {
     21 template <typename T, size_t n> class array {
     22  public:
     23   EIGEN_DEVICE_FUNC
     24   EIGEN_STRONG_INLINE T& operator[] (size_t index) { eigen_internal_assert(index < size()); return values[index]; }
     25   EIGEN_DEVICE_FUNC
     26   EIGEN_STRONG_INLINE const T& operator[] (size_t index) const { eigen_internal_assert(index < size()); return values[index]; }
     27 
     28   EIGEN_DEVICE_FUNC
     29   EIGEN_STRONG_INLINE T& at(size_t index) { eigen_assert(index < size()); return values[index]; }
     30   EIGEN_DEVICE_FUNC
     31   EIGEN_STRONG_INLINE const T& at(size_t index) const { eigen_assert(index < size()); return values[index]; }
     32 
     33   EIGEN_DEVICE_FUNC
     34   EIGEN_STRONG_INLINE T& front() { return values[0]; }
     35   EIGEN_DEVICE_FUNC
     36   EIGEN_STRONG_INLINE const T& front() const { return values[0]; }
     37 
     38   EIGEN_DEVICE_FUNC
     39   EIGEN_STRONG_INLINE T& back() { return values[n-1]; }
     40   EIGEN_DEVICE_FUNC
     41   EIGEN_STRONG_INLINE const T& back() const { return values[n-1]; }
     42 
     43   EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
     44   static std::size_t size() { return n; }
     45 
     46   T values[n];
     47 
     48   EIGEN_DEVICE_FUNC
     49   EIGEN_STRONG_INLINE array() { }
     50   EIGEN_DEVICE_FUNC
     51   EIGEN_STRONG_INLINE array(const T& v) {
     52     EIGEN_STATIC_ASSERT(n==1, YOU_MADE_A_PROGRAMMING_MISTAKE)
     53     values[0] = v;
     54   }
     55   EIGEN_DEVICE_FUNC
     56   EIGEN_STRONG_INLINE array(const T& v1, const T& v2) {
     57     EIGEN_STATIC_ASSERT(n==2, YOU_MADE_A_PROGRAMMING_MISTAKE)
     58     values[0] = v1;
     59     values[1] = v2;
     60   }
     61   EIGEN_DEVICE_FUNC
     62   EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3) {
     63     EIGEN_STATIC_ASSERT(n==3, YOU_MADE_A_PROGRAMMING_MISTAKE)
     64     values[0] = v1;
     65     values[1] = v2;
     66     values[2] = v3;
     67   }
     68   EIGEN_DEVICE_FUNC
     69   EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3,
     70                             const T& v4) {
     71     EIGEN_STATIC_ASSERT(n==4, YOU_MADE_A_PROGRAMMING_MISTAKE)
     72     values[0] = v1;
     73     values[1] = v2;
     74     values[2] = v3;
     75     values[3] = v4;
     76   }
     77   EIGEN_DEVICE_FUNC
     78   EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
     79                             const T& v5) {
     80     EIGEN_STATIC_ASSERT(n==5, YOU_MADE_A_PROGRAMMING_MISTAKE)
     81     values[0] = v1;
     82     values[1] = v2;
     83     values[2] = v3;
     84     values[3] = v4;
     85     values[4] = v5;
     86   }
     87   EIGEN_DEVICE_FUNC
     88   EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
     89                             const T& v5, const T& v6) {
     90     EIGEN_STATIC_ASSERT(n==6, YOU_MADE_A_PROGRAMMING_MISTAKE)
     91     values[0] = v1;
     92     values[1] = v2;
     93     values[2] = v3;
     94     values[3] = v4;
     95     values[4] = v5;
     96     values[5] = v6;
     97   }
     98   EIGEN_DEVICE_FUNC
     99   EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4,
    100                             const T& v5, const T& v6, const T& v7) {
    101     EIGEN_STATIC_ASSERT(n==7, YOU_MADE_A_PROGRAMMING_MISTAKE)
    102     values[0] = v1;
    103     values[1] = v2;
    104     values[2] = v3;
    105     values[3] = v4;
    106     values[4] = v5;
    107     values[5] = v6;
    108     values[6] = v7;
    109   }
    110   EIGEN_DEVICE_FUNC
    111   EIGEN_STRONG_INLINE array(
    112       const T& v1, const T& v2, const T& v3, const T& v4,
    113       const T& v5, const T& v6, const T& v7, const T& v8) {
    114     EIGEN_STATIC_ASSERT(n==8, YOU_MADE_A_PROGRAMMING_MISTAKE)
    115     values[0] = v1;
    116     values[1] = v2;
    117     values[2] = v3;
    118     values[3] = v4;
    119     values[4] = v5;
    120     values[5] = v6;
    121     values[6] = v7;
    122     values[7] = v8;
    123   }
    124 
    125 #if EIGEN_HAS_VARIADIC_TEMPLATES
    126   EIGEN_DEVICE_FUNC
    127   EIGEN_STRONG_INLINE array(std::initializer_list<T> l) {
    128     eigen_assert(l.size() == n);
    129     internal::smart_copy(l.begin(), l.end(), values);
    130   }
    131 #endif
    132 };
    133 
    134 
    135 // Specialize array for zero size
    136 template <typename T> class array<T, 0> {
    137  public:
    138   EIGEN_DEVICE_FUNC
    139   EIGEN_STRONG_INLINE T& operator[] (size_t) {
    140     eigen_assert(false && "Can't index a zero size array");
    141     return dummy;
    142   }
    143   EIGEN_DEVICE_FUNC
    144   EIGEN_STRONG_INLINE const T& operator[] (size_t) const {
    145     eigen_assert(false && "Can't index a zero size array");
    146     return dummy;
    147   }
    148 
    149   EIGEN_DEVICE_FUNC
    150   EIGEN_STRONG_INLINE T& front() {
    151     eigen_assert(false && "Can't index a zero size array");
    152     return dummy;
    153   }
    154   EIGEN_DEVICE_FUNC
    155   EIGEN_STRONG_INLINE const T& front() const {
    156     eigen_assert(false && "Can't index a zero size array");
    157     return dummy;
    158   }
    159   EIGEN_DEVICE_FUNC
    160   EIGEN_STRONG_INLINE T& back() {
    161     eigen_assert(false && "Can't index a zero size array");
    162     return dummy;
    163   }
    164   EIGEN_DEVICE_FUNC
    165   EIGEN_STRONG_INLINE const T& back() const {
    166     eigen_assert(false && "Can't index a zero size array");
    167     return dummy;
    168   }
    169 
    170   static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::size_t size() { return 0; }
    171 
    172   EIGEN_DEVICE_FUNC
    173   EIGEN_STRONG_INLINE array() : dummy() { }
    174 
    175 #if EIGEN_HAS_VARIADIC_TEMPLATES
    176   EIGEN_DEVICE_FUNC array(std::initializer_list<T> l) : dummy() {
    177     EIGEN_UNUSED_VARIABLE(l);
    178     eigen_assert(l.size() == 0);
    179   }
    180 #endif
    181 
    182  private:
    183   T dummy;
    184 };
    185 
    186 // Comparison operator
    187 // Todo: implement !=, <, <=, >,  and >=
    188 template<class T, std::size_t N>
    189 EIGEN_DEVICE_FUNC bool operator==(const array<T,N>& lhs, const array<T,N>& rhs) {
    190   for (std::size_t i = 0; i < N; ++i) {
    191     if (lhs[i] != rhs[i]) {
    192       return false;
    193     }
    194   }
    195   return true;
    196 }
    197 
    198 
    199 namespace internal {
    200 template<std::size_t I_, class T, std::size_t N>
    201 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& array_get(array<T,N>& a) {
    202   return a[I_];
    203 }
    204 template<std::size_t I_, class T, std::size_t N>
    205 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const array<T,N>& a) {
    206   return a[I_];
    207 }
    208 
    209 template<class T, std::size_t N> struct array_size<array<T,N> > {
    210   enum { value = N };
    211 };
    212 template<class T, std::size_t N> struct array_size<array<T,N>& > {
    213   enum { value = N };
    214 };
    215 template<class T, std::size_t N> struct array_size<const array<T,N> > {
    216   enum { value = N };
    217 };
    218 template<class T, std::size_t N> struct array_size<const array<T,N>& > {
    219   enum { value = N };
    220 };
    221 
    222 }  // end namespace internal
    223 }  // end namespace Eigen
    224 
    225 #else
    226 
    227 // The compiler supports c++11, and we're not targeting cuda: use std::array as Eigen::array
    228 #include <array>
    229 namespace Eigen {
    230 
    231 template <typename T, std::size_t N> using array = std::array<T, N>;
    232 
    233 namespace internal {
    234 /* std::get is only constexpr in C++14, not yet in C++11
    235  *     - libstdc++ from version 4.7 onwards has it nevertheless,
    236  *                                          so use that
    237  *     - libstdc++ older versions: use _M_instance directly
    238  *     - libc++ all versions so far: use __elems_ directly
    239  *     - all other libs: use std::get to be portable, but
    240  *                       this may not be constexpr
    241  */
    242 #if defined(__GLIBCXX__) && __GLIBCXX__ < 20120322
    243 #define STD_GET_ARR_HACK             a._M_instance[I_]
    244 #elif defined(_LIBCPP_VERSION)
    245 #define STD_GET_ARR_HACK             a.__elems_[I_]
    246 #else
    247 #define STD_GET_ARR_HACK             std::template get<I_, T, N>(a)
    248 #endif
    249 
    250 template<std::size_t I_, class T, std::size_t N> constexpr inline T&       array_get(std::array<T,N>&       a) { return (T&)       STD_GET_ARR_HACK; }
    251 template<std::size_t I_, class T, std::size_t N> constexpr inline T&&      array_get(std::array<T,N>&&      a) { return (T&&)      STD_GET_ARR_HACK; }
    252 template<std::size_t I_, class T, std::size_t N> constexpr inline T const& array_get(std::array<T,N> const& a) { return (T const&) STD_GET_ARR_HACK; }
    253 
    254 #undef STD_GET_ARR_HACK
    255 
    256 }  // end namespace internal
    257 }  // end namespace Eigen
    258 
    259 #endif
    260 
    261 #endif  // EIGEN_EMULATE_ARRAY_H