// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2014 Benoit Steiner // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_EMULATE_CXX11_META_H #define EIGEN_EMULATE_CXX11_META_H namespace Eigen { namespace internal { /** \internal * \file CXX11/util/EmulateCXX11Meta.h * This file emulates a subset of the functionality provided by CXXMeta.h for * compilers that don't yet support cxx11 such as nvcc. */ struct empty_list { static const std::size_t count = 0; }; template struct type_list { typedef T HeadType; typedef Tail TailType; static const T head; static const Tail tail; static const std::size_t count = 1 + Tail::count; }; struct null_type { }; template struct make_type_list { typedef typename make_type_list::type tailresult; typedef type_list type; }; template<> struct make_type_list<> { typedef empty_list type; }; template struct get_type; template struct get_type<0, type_list > { typedef Head type; }; template struct get_type > { typedef typename get_type::type type; }; /* numeric list */ template struct type2val { typedef T type; static const T value = n; }; template struct gen_numeric_list_repeated; template struct gen_numeric_list_repeated { typedef typename make_type_list >::type type; }; template struct gen_numeric_list_repeated { typedef typename make_type_list, type2val >::type type; }; template struct gen_numeric_list_repeated { typedef typename make_type_list, type2val, type2val >::type type; }; template struct gen_numeric_list_repeated { typedef typename make_type_list, type2val, type2val, type2val >::type type; }; template struct gen_numeric_list_repeated { typedef typename make_type_list, type2val, type2val, type2val, type2val >::type type; }; template struct gen_numeric_list_repeated { typedef typename make_type_list, type2val, type2val, type2val, type2val, type2val >::type type; }; template struct gen_numeric_list_repeated { typedef typename make_type_list, type2val, type2val, type2val, type2val, type2val, type2val >::type type; }; template struct gen_numeric_list_repeated { typedef typename make_type_list, type2val, type2val, type2val, type2val, type2val, type2val, type2val >::type type; }; template struct get; template struct get { get() { eigen_assert(false && "index overflow"); } typedef void type; static const char value = '\0'; }; template struct get > { get() { eigen_assert(false && "index overflow"); } typedef void type; static const char value = '\0'; }; template struct get<0, type_list > { typedef typename Head::type type; static const type value = Head::value; }; template struct get<0, type_list > { typedef typename Head::type type; static const type value = Head::value; }; template struct get > { typedef typename Tail::HeadType::type type; static const type value = get::value; }; template struct arg_prod { static const typename NList::HeadType::type value = get<0, NList>::value * arg_prod::value; }; template <> struct arg_prod { static const int value = 1; }; template array repeat(t v) { array array; array.fill(v); return array; } template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename Head::type array_get(type_list&) { return get >::value; } template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename Head::type array_get(const type_list&) { return get >::value; } template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NList::HeadType::type array_prod(const NList&) { return arg_prod::value; } template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const array& a) { t prod = 1; for (size_t i = 0; i < n; ++i) { prod *= a[i]; } return prod; } template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const array& /*a*/) { return 0; } template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const std::vector& a) { eigen_assert(a.size() > 0); t prod = 1; for (size_t i = 0; i < a.size(); ++i) { prod *= a[i]; } return prod; } template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T& array_get(std::vector& a) { return a[I]; } template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T& array_get(const std::vector& a) { return a[I]; } struct sum_op { template static inline bool run(A a, B b) { return a + b; } }; struct product_op { template static inline bool run(A a, B b) { return a * b; } }; struct logical_and_op { template static inline bool run(A a, B b) { return a && b; } }; struct logical_or_op { template static inline bool run(A a, B b) { return a || b; } }; struct equal_op { template static inline bool run(A a, B b) { return a == b; } }; struct not_equal_op { template static inline bool run(A a, B b) { return a != b; } }; struct lesser_op { template static inline bool run(A a, B b) { return a < b; } }; struct lesser_equal_op { template static inline bool run(A a, B b) { return a <= b; } }; struct greater_op { template static inline bool run(A a, B b) { return a > b; } }; struct greater_equal_op { template static inline bool run(A a, B b) { return a >= b; } }; struct not_op { template static inline bool run(A a) { return !a; } }; struct negation_op { template static inline bool run(A a) { return -a; } }; struct greater_equal_zero_op { template static inline bool run(A a) { return a >= 0; } }; template struct ArrayApplyAndReduce { static inline bool run(const array& a) { EIGEN_STATIC_ASSERT(N >= 2, YOU_MADE_A_PROGRAMMING_MISTAKE); bool result = Reducer::run(Op::run(a[0]), Op::run(a[1])); for (size_t i = 2; i < N; ++i) { result = Reducer::run(result, Op::run(a[i])); } return result; } }; template struct ArrayApplyAndReduce { static inline bool run(const array& a) { return Op::run(a[0]); } }; template inline bool array_apply_and_reduce(const array& a) { return ArrayApplyAndReduce::run(a); } template struct ArrayZipAndReduce { static inline bool run(const array& a, const array& b) { EIGEN_STATIC_ASSERT(N >= 2, YOU_MADE_A_PROGRAMMING_MISTAKE); bool result = Reducer::run(Op::run(a[0], b[0]), Op::run(a[1], b[1])); for (size_t i = 2; i < N; ++i) { result = Reducer::run(result, Op::run(a[i], b[i])); } return result; } }; template struct ArrayZipAndReduce { static inline bool run(const array& a, const array& b) { return Op::run(a[0], b[0]); } }; template inline bool array_zip_and_reduce(const array& a, const array& b) { return ArrayZipAndReduce::run(a, b); } } // end namespace internal } // end namespace Eigen #endif // EIGEN_EMULATE_CXX11_META_H