![]() |
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_CXX11_META_H 00011 #define EIGEN_EMULATE_CXX11_META_H 00012 00013 00014 00015 namespace Eigen { 00016 00017 namespace internal { 00018 00025 struct empty_list { static const std::size_t count = 0; }; 00026 00027 template<typename T, typename Tail=empty_list> struct type_list { 00028 typedef T HeadType; 00029 typedef Tail TailType; 00030 static const T head; 00031 static const Tail tail; 00032 static const std::size_t count = 1 + Tail::count; 00033 }; 00034 00035 struct null_type { }; 00036 00037 template<typename T1 = null_type, typename T2 = null_type, typename T3 = null_type, 00038 typename T4 = null_type, typename T5 = null_type, typename T6 = null_type, 00039 typename T7 = null_type, typename T8 = null_type> 00040 struct make_type_list { 00041 typedef typename make_type_list<T2, T3, T4, T5, T6, T7, T8>::type tailresult; 00042 00043 typedef type_list<T1, tailresult> type; 00044 }; 00045 00046 template<> struct make_type_list<> { 00047 typedef empty_list type; 00048 }; 00049 00050 00051 template <std::size_t index, class TList> struct get_type; 00052 00053 template <class Head, class Tail> 00054 struct get_type<0, type_list<Head, Tail> > 00055 { 00056 typedef Head type; 00057 }; 00058 00059 template <std::size_t i, class Head, class Tail> 00060 struct get_type<i, type_list<Head, Tail> > 00061 { 00062 typedef typename get_type<i-1, Tail>::type type; 00063 }; 00064 00065 00066 /* numeric list */ 00067 template <typename T, T n> 00068 struct type2val { 00069 typedef T type; 00070 static const T value = n; 00071 }; 00072 00073 00074 template<typename T, size_t n, T V> struct gen_numeric_list_repeated; 00075 00076 template<typename T, T V> struct gen_numeric_list_repeated<T, 1, V> { 00077 typedef typename make_type_list<type2val<T, V> >::type type; 00078 }; 00079 00080 template<typename T, T V> struct gen_numeric_list_repeated<T, 2, V> { 00081 typedef typename make_type_list<type2val<T, V>, type2val<T, V> >::type type; 00082 }; 00083 00084 template<typename T, T V> struct gen_numeric_list_repeated<T, 3, V> { 00085 typedef typename make_type_list<type2val<T, V>, type2val<T, V>, type2val<T, V> >::type type; 00086 }; 00087 00088 template<typename T, T V> struct gen_numeric_list_repeated<T, 4, V> { 00089 typedef typename make_type_list<type2val<T, V>, type2val<T, V>, type2val<T, V>, type2val<T, V> >::type type; 00090 }; 00091 00092 template<typename T, T V> struct gen_numeric_list_repeated<T, 5, V> { 00093 typedef typename make_type_list<type2val<T, V>, type2val<T, V>, type2val<T, V>, type2val<T, V>, type2val<T, V> >::type type; 00094 }; 00095 00096 template<typename T, T V> struct gen_numeric_list_repeated<T, 6, V> { 00097 typedef typename make_type_list<type2val<T, V>, type2val<T, V>, type2val<T, V>, 00098 type2val<T, V>, type2val<T, V>, type2val<T, V> >::type type; 00099 }; 00100 00101 template<typename T, T V> struct gen_numeric_list_repeated<T, 7, V> { 00102 typedef typename make_type_list<type2val<T, V>, type2val<T, V>, type2val<T, V>, 00103 type2val<T, V>, type2val<T, V>, type2val<T, V>, 00104 type2val<T, V> >::type type; 00105 }; 00106 00107 template<typename T, T V> struct gen_numeric_list_repeated<T, 8, V> { 00108 typedef typename make_type_list<type2val<T, V>, type2val<T, V>, type2val<T, V>, 00109 type2val<T, V>, type2val<T, V>, type2val<T, V>, 00110 type2val<T, V>, type2val<T, V> >::type type; 00111 }; 00112 00113 00114 template <std::size_t index, class NList> struct get; 00115 00116 template <std::size_t i> 00117 struct get<i, empty_list> 00118 { 00119 get() { eigen_assert(false && "index overflow"); } 00120 typedef void type; 00121 static const char value = '\0'; 00122 }; 00123 00124 template <std::size_t i, class Head> 00125 struct get<i, type_list<Head, empty_list> > 00126 { 00127 get() { eigen_assert(false && "index overflow"); } 00128 typedef void type; 00129 static const char value = '\0'; 00130 }; 00131 00132 template <class Head> 00133 struct get<0, type_list<Head, empty_list> > 00134 { 00135 typedef typename Head::type type; 00136 static const type value = Head::value; 00137 }; 00138 00139 template <class Head, class Tail> 00140 struct get<0, type_list<Head, Tail> > 00141 { 00142 typedef typename Head::type type; 00143 static const type value = Head::value; 00144 }; 00145 00146 template <std::size_t i, class Head, class Tail> 00147 struct get<i, type_list<Head, Tail> > 00148 { 00149 typedef typename Tail::HeadType::type type; 00150 static const type value = get<i-1, Tail>::value; 00151 }; 00152 00153 00154 template <class NList> struct arg_prod { 00155 static const typename NList::HeadType::type value = get<0, NList>::value * arg_prod<typename NList::TailType>::value; 00156 }; 00157 template <> struct arg_prod<empty_list> { 00158 static const int value = 1; 00159 }; 00160 00161 00162 template<int n, typename t> 00163 array<t, n> repeat(t v) { 00164 array<t, n> array; 00165 array.fill(v); 00166 return array; 00167 } 00168 00169 template<std::size_t I, class Head, class Tail> 00170 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename Head::type array_get(type_list<Head, Tail>&) { 00171 return get<I, type_list<Head, Tail> >::value; 00172 } 00173 template<std::size_t I, class Head, class Tail> 00174 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename Head::type array_get(const type_list<Head, Tail>&) { 00175 return get<I, type_list<Head, Tail> >::value; 00176 } 00177 00178 template <class NList> 00179 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NList::HeadType::type array_prod(const NList&) { 00180 return arg_prod<NList>::value; 00181 } 00182 00183 template<typename t, std::size_t n> 00184 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const array<t, n>& a) { 00185 t prod = 1; 00186 for (size_t i = 0; i < n; ++i) { prod *= a[i]; } 00187 return prod; 00188 } 00189 template<typename t> 00190 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const array<t, 0>& /*a*/) { 00191 return 0; 00192 } 00193 00194 template<typename t> 00195 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const std::vector<t>& a) { 00196 eigen_assert(a.size() > 0); 00197 t prod = 1; 00198 for (size_t i = 0; i < a.size(); ++i) { prod *= a[i]; } 00199 return prod; 00200 } 00201 00202 00203 template<std::size_t I, class T> 00204 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& array_get(std::vector<T>& a) { 00205 return a[I]; 00206 } 00207 template<std::size_t I, class T> 00208 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const std::vector<T>& a) { 00209 return a[I]; 00210 } 00211 00212 struct sum_op { 00213 template<typename A, typename B> static inline bool run(A a, B b) { return a + b; } 00214 }; 00215 struct product_op { 00216 template<typename A, typename B> static inline bool run(A a, B b) { return a * b; } 00217 }; 00218 00219 struct logical_and_op { 00220 template<typename A, typename B> static inline bool run(A a, B b) { return a && b; } 00221 }; 00222 struct logical_or_op { 00223 template<typename A, typename B> static inline bool run(A a, B b) { return a || b; } 00224 }; 00225 00226 struct equal_op { 00227 template<typename A, typename B> static inline bool run(A a, B b) { return a == b; } 00228 }; 00229 struct not_equal_op { 00230 template<typename A, typename B> static inline bool run(A a, B b) { return a != b; } 00231 }; 00232 struct lesser_op { 00233 template<typename A, typename B> static inline bool run(A a, B b) { return a < b; } 00234 }; 00235 struct lesser_equal_op { 00236 template<typename A, typename B> static inline bool run(A a, B b) { return a <= b; } 00237 }; 00238 00239 struct greater_op { 00240 template<typename A, typename B> static inline bool run(A a, B b) { return a > b; } 00241 }; 00242 struct greater_equal_op { 00243 template<typename A, typename B> static inline bool run(A a, B b) { return a >= b; } 00244 }; 00245 00246 struct not_op { 00247 template<typename A> static inline bool run(A a) { return !a; } 00248 }; 00249 struct negation_op { 00250 template<typename A> static inline bool run(A a) { return -a; } 00251 }; 00252 struct greater_equal_zero_op { 00253 template<typename A> static inline bool run(A a) { return a >= 0; } 00254 }; 00255 00256 00257 template<typename Reducer, typename Op, typename A, std::size_t N> 00258 struct ArrayApplyAndReduce { 00259 static inline bool run(const array<A, N>& a) { 00260 EIGEN_STATIC_ASSERT(N >= 2, YOU_MADE_A_PROGRAMMING_MISTAKE); 00261 bool result = Reducer::run(Op::run(a[0]), Op::run(a[1])); 00262 for (size_t i = 2; i < N; ++i) { 00263 result = Reducer::run(result, Op::run(a[i])); 00264 } 00265 return result; 00266 } 00267 }; 00268 00269 template<typename Reducer, typename Op, typename A> 00270 struct ArrayApplyAndReduce<Reducer, Op, A, 1> { 00271 static inline bool run(const array<A, 1>& a) { 00272 return Op::run(a[0]); 00273 } 00274 }; 00275 00276 template<typename Reducer, typename Op, typename A, std::size_t N> 00277 inline bool array_apply_and_reduce(const array<A, N>& a) { 00278 return ArrayApplyAndReduce<Reducer, Op, A, N>::run(a); 00279 } 00280 00281 template<typename Reducer, typename Op, typename A, typename B, std::size_t N> 00282 struct ArrayZipAndReduce { 00283 static inline bool run(const array<A, N>& a, const array<B, N>& b) { 00284 EIGEN_STATIC_ASSERT(N >= 2, YOU_MADE_A_PROGRAMMING_MISTAKE); 00285 bool result = Reducer::run(Op::run(a[0], b[0]), Op::run(a[1], b[1])); 00286 for (size_t i = 2; i < N; ++i) { 00287 result = Reducer::run(result, Op::run(a[i], b[i])); 00288 } 00289 return result; 00290 } 00291 }; 00292 00293 template<typename Reducer, typename Op, typename A, typename B> 00294 struct ArrayZipAndReduce<Reducer, Op, A, B, 1> { 00295 static inline bool run(const array<A, 1>& a, const array<B, 1>& b) { 00296 return Op::run(a[0], b[0]); 00297 } 00298 }; 00299 00300 template<typename Reducer, typename Op, typename A, typename B, std::size_t N> 00301 inline bool array_zip_and_reduce(const array<A, N>& a, const array<B, N>& b) { 00302 return ArrayZipAndReduce<Reducer, Op, A, B, N>::run(a, b); 00303 } 00304 00305 } // end namespace internal 00306 00307 } // end namespace Eigen 00308 00309 00310 00311 #endif // EIGEN_EMULATE_CXX11_META_H