![]() |
Eigen-unsupported
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com> 00005 // 00006 // This Source Code Form is subject to the terms of the Mozilla 00007 // Public License v. 2.0. If a copy of the MPL was not distributed 00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00009 00010 #ifndef EIGEN_EMULATE_ARRAY_H 00011 #define EIGEN_EMULATE_ARRAY_H 00012 00013 00014 00015 // The array class is only available starting with cxx11. Emulate our own here 00016 // if needed. Beware, msvc still doesn't advertise itself as a c++11 compiler! 00017 // Moreover, CUDA doesn't support the STL containers, so we use our own instead. 00018 #if (__cplusplus <= 199711L && EIGEN_COMP_MSVC < 1900) || defined(__CUDACC__) || defined(EIGEN_AVOID_STL_ARRAY) 00019 00020 namespace Eigen { 00021 template <typename T, size_t n> class array { 00022 public: 00023 EIGEN_DEVICE_FUNC 00024 EIGEN_STRONG_INLINE T& operator[] (size_t index) { return values[index]; } 00025 EIGEN_DEVICE_FUNC 00026 EIGEN_STRONG_INLINE const T& operator[] (size_t index) const { return values[index]; } 00027 00028 EIGEN_DEVICE_FUNC 00029 EIGEN_STRONG_INLINE T& front() { return values[0]; } 00030 EIGEN_DEVICE_FUNC 00031 EIGEN_STRONG_INLINE const T& front() const { return values[0]; } 00032 00033 EIGEN_DEVICE_FUNC 00034 EIGEN_STRONG_INLINE T& back() { return values[n-1]; } 00035 EIGEN_DEVICE_FUNC 00036 EIGEN_STRONG_INLINE const T& back() const { return values[n-1]; } 00037 00038 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE 00039 static std::size_t size() { return n; } 00040 00041 T values[n]; 00042 00043 EIGEN_DEVICE_FUNC 00044 EIGEN_STRONG_INLINE array() { } 00045 EIGEN_DEVICE_FUNC 00046 EIGEN_STRONG_INLINE array(const T& v) { 00047 EIGEN_STATIC_ASSERT(n==1, YOU_MADE_A_PROGRAMMING_MISTAKE) 00048 values[0] = v; 00049 } 00050 EIGEN_DEVICE_FUNC 00051 EIGEN_STRONG_INLINE array(const T& v1, const T& v2) { 00052 EIGEN_STATIC_ASSERT(n==2, YOU_MADE_A_PROGRAMMING_MISTAKE) 00053 values[0] = v1; 00054 values[1] = v2; 00055 } 00056 EIGEN_DEVICE_FUNC 00057 EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3) { 00058 EIGEN_STATIC_ASSERT(n==3, YOU_MADE_A_PROGRAMMING_MISTAKE) 00059 values[0] = v1; 00060 values[1] = v2; 00061 values[2] = v3; 00062 } 00063 EIGEN_DEVICE_FUNC 00064 EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, 00065 const T& v4) { 00066 EIGEN_STATIC_ASSERT(n==4, YOU_MADE_A_PROGRAMMING_MISTAKE) 00067 values[0] = v1; 00068 values[1] = v2; 00069 values[2] = v3; 00070 values[3] = v4; 00071 } 00072 EIGEN_DEVICE_FUNC 00073 EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, 00074 const T& v5) { 00075 EIGEN_STATIC_ASSERT(n==5, YOU_MADE_A_PROGRAMMING_MISTAKE) 00076 values[0] = v1; 00077 values[1] = v2; 00078 values[2] = v3; 00079 values[3] = v4; 00080 values[4] = v5; 00081 } 00082 EIGEN_DEVICE_FUNC 00083 EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, 00084 const T& v5, const T& v6) { 00085 EIGEN_STATIC_ASSERT(n==6, YOU_MADE_A_PROGRAMMING_MISTAKE) 00086 values[0] = v1; 00087 values[1] = v2; 00088 values[2] = v3; 00089 values[3] = v4; 00090 values[4] = v5; 00091 values[5] = v6; 00092 } 00093 EIGEN_DEVICE_FUNC 00094 EIGEN_STRONG_INLINE array(const T& v1, const T& v2, const T& v3, const T& v4, 00095 const T& v5, const T& v6, const T& v7) { 00096 EIGEN_STATIC_ASSERT(n==7, YOU_MADE_A_PROGRAMMING_MISTAKE) 00097 values[0] = v1; 00098 values[1] = v2; 00099 values[2] = v3; 00100 values[3] = v4; 00101 values[4] = v5; 00102 values[5] = v6; 00103 values[6] = v7; 00104 } 00105 EIGEN_DEVICE_FUNC 00106 EIGEN_STRONG_INLINE array( 00107 const T& v1, const T& v2, const T& v3, const T& v4, 00108 const T& v5, const T& v6, const T& v7, const T& v8) { 00109 EIGEN_STATIC_ASSERT(n==8, YOU_MADE_A_PROGRAMMING_MISTAKE) 00110 values[0] = v1; 00111 values[1] = v2; 00112 values[2] = v3; 00113 values[3] = v4; 00114 values[4] = v5; 00115 values[5] = v6; 00116 values[6] = v7; 00117 values[7] = v8; 00118 } 00119 00120 #if EIGEN_HAS_VARIADIC_TEMPLATES 00121 EIGEN_DEVICE_FUNC 00122 EIGEN_STRONG_INLINE array(std::initializer_list<T> l) { 00123 eigen_assert(l.size() == n); 00124 internal::smart_copy(l.begin(), l.end(), values); 00125 } 00126 #endif 00127 }; 00128 00129 00130 // Specialize array for zero size 00131 template <typename T> class array<T, 0> { 00132 public: 00133 EIGEN_DEVICE_FUNC 00134 EIGEN_STRONG_INLINE T& operator[] (size_t) { 00135 eigen_assert(false && "Can't index a zero size array"); 00136 return dummy; 00137 } 00138 EIGEN_DEVICE_FUNC 00139 EIGEN_STRONG_INLINE const T& operator[] (size_t) const { 00140 eigen_assert(false && "Can't index a zero size array"); 00141 return dummy; 00142 } 00143 00144 EIGEN_DEVICE_FUNC 00145 EIGEN_STRONG_INLINE T& front() { 00146 eigen_assert(false && "Can't index a zero size array"); 00147 return dummy; 00148 } 00149 EIGEN_DEVICE_FUNC 00150 EIGEN_STRONG_INLINE const T& front() const { 00151 eigen_assert(false && "Can't index a zero size array"); 00152 return dummy; 00153 } 00154 EIGEN_DEVICE_FUNC 00155 EIGEN_STRONG_INLINE T& back() { 00156 eigen_assert(false && "Can't index a zero size array"); 00157 return dummy; 00158 } 00159 EIGEN_DEVICE_FUNC 00160 EIGEN_STRONG_INLINE const T& back() const { 00161 eigen_assert(false && "Can't index a zero size array"); 00162 return dummy; 00163 } 00164 00165 static EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::size_t size() { return 0; } 00166 00167 EIGEN_DEVICE_FUNC 00168 EIGEN_STRONG_INLINE array() : dummy() { } 00169 00170 #if EIGEN_HAS_VARIADIC_TEMPLATES 00171 EIGEN_DEVICE_FUNC array(std::initializer_list<T> l) : dummy() { 00172 eigen_assert(l.size() == 0); 00173 } 00174 #endif 00175 00176 private: 00177 T dummy; 00178 }; 00179 00180 // Comparison operator 00181 // Todo: implement !=, <, <=, >, and >= 00182 template<class T, std::size_t N> 00183 EIGEN_DEVICE_FUNC bool operator==(const array<T,N>& lhs, const array<T,N>& rhs) { 00184 for (std::size_t i = 0; i < N; ++i) { 00185 if (lhs[i] != rhs[i]) { 00186 return false; 00187 } 00188 } 00189 return true; 00190 } 00191 00192 00193 namespace internal { 00194 template<std::size_t I, class T, std::size_t N> 00195 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& array_get(array<T,N>& a) { 00196 return a[I]; 00197 } 00198 template<std::size_t I, class T, std::size_t N> 00199 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const array<T,N>& a) { 00200 return a[I]; 00201 } 00202 00203 template <typename T> struct array_size; 00204 template<class T, std::size_t N> struct array_size<array<T,N> > { 00205 static const size_t value = N; 00206 }; 00207 template <typename T> struct array_size; 00208 template<class T, std::size_t N> struct array_size<array<T,N>& > { 00209 static const size_t value = N; 00210 }; 00211 template <typename T> struct array_size; 00212 template<class T, std::size_t N> struct array_size<const array<T,N> > { 00213 static const size_t value = N; 00214 }; 00215 template <typename T> struct array_size; 00216 template<class T, std::size_t N> struct array_size<const array<T,N>& > { 00217 static const size_t value = N; 00218 }; 00219 00220 } // end namespace internal 00221 } // end namespace Eigen 00222 00223 #else 00224 00225 // The compiler supports c++11, and we're not targetting cuda: use std::array as Eigen::array 00226 #include <array> 00227 namespace Eigen { 00228 00229 template <typename T, std::size_t N> using array = std::array<T, N>; 00230 00231 namespace internal { 00232 /* std::get is only constexpr in C++14, not yet in C++11 00233 * - libstdc++ from version 4.7 onwards has it nevertheless, 00234 * so use that 00235 * - libstdc++ older versions: use _M_instance directly 00236 * - libc++ all versions so far: use __elems_ directly 00237 * - all other libs: use std::get to be portable, but 00238 * this may not be constexpr 00239 */ 00240 #if defined(__GLIBCXX__) && __GLIBCXX__ < 20120322 00241 #define STD_GET_ARR_HACK a._M_instance[I] 00242 #elif defined(_LIBCPP_VERSION) 00243 #define STD_GET_ARR_HACK a.__elems_[I] 00244 #else 00245 #define STD_GET_ARR_HACK std::template get<I, T, N>(a) 00246 #endif 00247 00248 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; } 00249 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; } 00250 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; } 00251 00252 #undef STD_GET_ARR_HACK 00253 00254 template <typename T> struct array_size; 00255 template<class T, std::size_t N> struct array_size<const std::array<T,N> > { 00256 static const size_t value = N; 00257 }; 00258 template <typename T> struct array_size; 00259 template<class T, std::size_t N> struct array_size<std::array<T,N> > { 00260 static const size_t value = N; 00261 }; 00262 } // end namespace internal 00263 } // end namespace Eigen 00264 00265 #endif 00266 00267 #endif // EIGEN_EMULATE_ARRAY_H