diff options
author | 2015-01-14 15:31:52 -0800 | |
---|---|---|
committer | 2015-01-14 15:31:52 -0800 | |
commit | 703c526355c929cc6c422b7599ecfed57642e988 (patch) | |
tree | 439f28155c3a89b1bb5ba2202f073aba85d2059f | |
parent | 4cdf3fe427b4fdc271733d0404a66e2d5613cb16 (diff) |
Misc improvements
-rw-r--r-- | unsupported/Eigen/CXX11/src/Core/util/CXX11Meta.h | 20 | ||||
-rw-r--r-- | unsupported/Eigen/CXX11/src/Core/util/CXX11Workarounds.h | 12 | ||||
-rw-r--r-- | unsupported/Eigen/CXX11/src/Core/util/EmulateCXX11Meta.h | 81 |
3 files changed, 86 insertions, 27 deletions
diff --git a/unsupported/Eigen/CXX11/src/Core/util/CXX11Meta.h b/unsupported/Eigen/CXX11/src/Core/util/CXX11Meta.h index 1e6b97ce4..36d91e780 100644 --- a/unsupported/Eigen/CXX11/src/Core/util/CXX11Meta.h +++ b/unsupported/Eigen/CXX11/src/Core/util/CXX11Meta.h @@ -42,14 +42,14 @@ struct numeric_list<T, n, nn...> { constexpr static std::size_t count = sizeof.. * typename gen_numeric_list_repeated<int, 0, 5>::type numeric_list<int, 0,0,0,0,0> */ -template<typename T, std::size_t n, T start = 0, T... ii> struct gen_numeric_list : gen_numeric_list<T, n-1, start, start + n-1, ii...> {}; -template<typename T, T start, T... ii> struct gen_numeric_list<T, 0, start, ii...> { typedef numeric_list<T, ii...> type; }; +template<typename T, std::size_t n, T... ii> struct gen_numeric_list : gen_numeric_list<T, n-1, n-1, ii...> {}; +template<typename T, T... ii> struct gen_numeric_list<T, 0, ii...> { typedef numeric_list<T, ii...> type; }; -template<typename T, std::size_t n, T start = 0, T... ii> struct gen_numeric_list_reversed : gen_numeric_list_reversed<T, n-1, start, ii..., start + n-1> {}; -template<typename T, T start, T... ii> struct gen_numeric_list_reversed<T, 0, start, ii...> { typedef numeric_list<T, ii...> type; }; +template<typename T, std::size_t n, T... ii> struct gen_numeric_list_reversed : gen_numeric_list_reversed<T, n-1, ii..., n-1> {}; +template<typename T, T... ii> struct gen_numeric_list_reversed<T, 0, ii...> { typedef numeric_list<T, ii...> type; }; -template<typename T, std::size_t n, T a, T b, T start = 0, T... ii> struct gen_numeric_list_swapped_pair : gen_numeric_list_swapped_pair<T, n-1, a, b, start, (start + n-1) == a ? b : ((start + n-1) == b ? a : (start + n-1)), ii...> {}; -template<typename T, T a, T b, T start, T... ii> struct gen_numeric_list_swapped_pair<T, 0, a, b, start, ii...> { typedef numeric_list<T, ii...> type; }; +template<typename T, std::size_t n, T a, T b, T... ii> struct gen_numeric_list_swapped_pair : gen_numeric_list_swapped_pair<T, n-1, a, b, (n-1) == a ? b : ((n-1) == b ? a : (n-1)), ii...> {}; +template<typename T, T a, T b, T... ii> struct gen_numeric_list_swapped_pair<T, 0, a, b, ii...> { typedef numeric_list<T, ii...> type; }; template<typename T, std::size_t n, T V, T... nn> struct gen_numeric_list_repeated : gen_numeric_list_repeated<T, n-1, V, V, nn...> {}; template<typename T, T V, T... nn> struct gen_numeric_list_repeated<T, 0, V, nn...> { typedef numeric_list<T, nn...> type; }; @@ -370,6 +370,14 @@ constexpr inline auto array_prod(std::array<T, N> arr) -> decltype(array_reduce< return array_reduce<product_op, T, N>(arr); } +template<typename t> +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const std::vector<t>& a) { + eigen_assert(a.size() > 0); + t prod = 1; + for (size_t i = 0; i < a.size(); ++i) { prod *= a[i]; } + return prod; +} + /* zip an array */ template<typename Op, typename A, typename B, std::size_t N, int... n> diff --git a/unsupported/Eigen/CXX11/src/Core/util/CXX11Workarounds.h b/unsupported/Eigen/CXX11/src/Core/util/CXX11Workarounds.h index e30eb6ad8..a590cf4e1 100644 --- a/unsupported/Eigen/CXX11/src/Core/util/CXX11Workarounds.h +++ b/unsupported/Eigen/CXX11/src/Core/util/CXX11Workarounds.h @@ -48,15 +48,13 @@ namespace internal { * - libstdc++ from version 4.7 onwards has it nevertheless, * so use that * - libstdc++ older versions: use _M_instance directly - * - libc++ from version 3.4 onwards has it IF compiled with - * -std=c++1y - * - libc++ older versions or -std=c++11: use __elems_ directly + * - libc++ all versions so far: use __elems_ directly * - all other libs: use std::get to be portable, but * this may not be constexpr */ #if defined(__GLIBCXX__) && __GLIBCXX__ < 20120322 #define STD_GET_ARR_HACK a._M_instance[I] -#elif defined(_LIBCPP_VERSION) && (!defined(_LIBCPP_STD_VER) || _LIBCPP_STD_VER <= 11) +#elif defined(_LIBCPP_VERSION) #define STD_GET_ARR_HACK a.__elems_[I] #else #define STD_GET_ARR_HACK std::template get<I, T, N>(a) @@ -70,14 +68,14 @@ template<std::size_t I, class T> constexpr inline T& array_get(std::vector template<std::size_t I, class T> constexpr inline T&& array_get(std::vector<T>&& a) { return a[I]; } template<std::size_t I, class T> constexpr inline T const& array_get(std::vector<T> const& a) { return a[I]; } - #undef STD_GET_ARR_HACK template <typename T> struct array_size; -template<class T, std::size_t N> struct array_size<std::array<T,N> > { +template<class T, std::size_t N> struct array_size<const std::array<T,N> > { static const size_t value = N; }; -template<class T, std::size_t N> struct array_size<const std::array<T,N> > { +template <typename T> struct array_size; +template<class T, std::size_t N> struct array_size<std::array<T,N> > { static const size_t value = N; }; diff --git a/unsupported/Eigen/CXX11/src/Core/util/EmulateCXX11Meta.h b/unsupported/Eigen/CXX11/src/Core/util/EmulateCXX11Meta.h index e45d0a3b1..494f95690 100644 --- a/unsupported/Eigen/CXX11/src/Core/util/EmulateCXX11Meta.h +++ b/unsupported/Eigen/CXX11/src/Core/util/EmulateCXX11Meta.h @@ -29,7 +29,7 @@ template <typename T, size_t n> class array { EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array() { } - EIGEN_DEVICE_FUNC + explicit EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE array(const T& v) { EIGEN_STATIC_ASSERT(n==1, YOU_MADE_A_PROGRAMMING_MISTAKE) values[0] = v; @@ -106,6 +106,7 @@ template <typename T, size_t n> class array { #ifdef EIGEN_HAS_VARIADIC_TEMPLATES array(std::initializer_list<T> l) { + eigen_assert(l.size() == n); std::copy(l.begin(), l.end(), values); } #endif @@ -211,6 +212,29 @@ template<typename T, T V> struct gen_numeric_list_repeated<T, 8, V> { template <std::size_t index, class NList> struct get; +template <std::size_t i> +struct get<i, empty_list> +{ + get() { eigen_assert(false && "index overflow"); } + typedef void type; + static const char value = '\0'; +}; + +template <std::size_t i, class Head> +struct get<i, type_list<Head, empty_list> > +{ + get() { eigen_assert(false && "index overflow"); } + typedef void type; + static const char value = '\0'; +}; + +template <class Head> +struct get<0, type_list<Head, empty_list> > +{ + typedef typename Head::type type; + static const type value = Head::value; +}; + template <class Head, class Tail> struct get<0, type_list<Head, Tail> > { @@ -221,10 +245,11 @@ struct get<0, type_list<Head, Tail> > template <std::size_t i, class Head, class Tail> struct get<i, type_list<Head, Tail> > { - typedef typename get<i-1, Tail>::type type; + typedef typename Tail::HeadType::type type; static const type value = get<i-1, Tail>::value; }; + template <class NList> struct arg_prod { static const typename NList::HeadType::type value = get<0, NList>::value * arg_prod<typename NList::TailType>::value; }; @@ -354,23 +379,51 @@ struct greater_equal_zero_op { template<typename Reducer, typename Op, typename A, std::size_t N> -inline bool array_apply_and_reduce(const array<A, N>& 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])); +struct ArrayApplyAndReduce { + static inline bool run(const array<A, N>& 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; } - return result; +}; + +template<typename Reducer, typename Op, typename A> +struct ArrayApplyAndReduce<Reducer, Op, A, 1> { + static inline bool run(const array<A, 1>& a) { + return Op::run(a[0]); + } +}; + +template<typename Reducer, typename Op, typename A, std::size_t N> +inline bool array_apply_and_reduce(const array<A, N>& a) { + return ArrayApplyAndReduce<Reducer, Op, A, N>::run(a); } template<typename Reducer, typename Op, typename A, typename B, std::size_t N> -inline bool array_zip_and_reduce(const array<A, N>& a, const array<B, N>& 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])); +struct ArrayZipAndReduce { + static inline bool run(const array<A, N>& a, const array<B, N>& 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; } - return result; +}; + +template<typename Reducer, typename Op, typename A, typename B> +struct ArrayZipAndReduce<Reducer, Op, A, B, 1> { + static inline bool run(const array<A, 1>& a, const array<B, 1>& b) { + return Op::run(a[0], b[0]); + } +}; + +template<typename Reducer, typename Op, typename A, typename B, std::size_t N> +inline bool array_zip_and_reduce(const array<A, N>& a, const array<B, N>& b) { + return ArrayZipAndReduce<Reducer, Op, A, B, N>::run(a, b); } } // end namespace internal |