EmulateCXX11Meta.h
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
 All Classes Functions Variables Typedefs Enumerator