From 57857775b461b020c16f2bbeb130d6b1863d951c Mon Sep 17 00:00:00 2001 From: Benoit Steiner Date: Fri, 23 Oct 2015 10:20:51 -0700 Subject: [PATCH] Added support for arrays of size 0 --- .../Eigen/CXX11/src/Core/util/CXX11Meta.h | 32 ++++++++++++------- .../CXX11/src/Core/util/EmulateCXX11Meta.h | 31 +++++++++++++++++- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/unsupported/Eigen/CXX11/src/Core/util/CXX11Meta.h b/unsupported/Eigen/CXX11/src/Core/util/CXX11Meta.h index 3a08628be..c44496865 100644 --- a/unsupported/Eigen/CXX11/src/Core/util/CXX11Meta.h +++ b/unsupported/Eigen/CXX11/src/Core/util/CXX11Meta.h @@ -112,7 +112,7 @@ template struct get<0, type_lis template struct get> { static_assert((n - n) < 0, "meta-template get: The element to extract from a list must be smaller than the size of the list."); }; template struct get> : get> {}; -template struct get<0, numeric_list> { constexpr static int value = a; }; +template struct get<0, numeric_list> { constexpr static T value = a; }; template struct get> { static_assert((n - n) < 0, "meta-template get: The element to extract from a list must be smaller than the size of the list."); }; /* always get type, regardless of dummy; good for parameter pack expansion */ @@ -326,6 +326,7 @@ constexpr inline std::array array_reverse(std::array arr) return h_array_reverse(arr, typename gen_numeric_list::type()); } + /* generic array reductions */ // can't reuse standard reduce() interface above because Intel's Compiler @@ -335,39 +336,48 @@ constexpr inline std::array array_reverse(std::array arr) // an infinite loop) template struct h_array_reduce { - constexpr static inline auto run(std::array arr) -> decltype(Reducer::run(h_array_reduce::run(arr), array_get(arr))) + constexpr static inline auto run(std::array arr, T identity) -> decltype(Reducer::run(h_array_reduce::run(arr, identity), array_get(arr))) { - return Reducer::run(h_array_reduce::run(arr), array_get(arr)); + return Reducer::run(h_array_reduce::run(arr, identity), array_get(arr)); } }; template struct h_array_reduce { - constexpr static inline T run(std::array arr) + constexpr static inline T run(const std::array& arr, T identity) { return array_get<0>(arr); } }; -template -constexpr inline auto array_reduce(std::array arr) -> decltype(h_array_reduce::run(arr)) +template +struct h_array_reduce { - return h_array_reduce::run(arr); + constexpr static inline T run(const std::array& arr, T identity) + { + return identity; + } +}; + +template +constexpr inline auto array_reduce(const std::array& arr, T identity) -> decltype(h_array_reduce::run(arr, identity)) +{ + return h_array_reduce::run(arr, identity); } /* standard array reductions */ template -constexpr inline auto array_sum(std::array arr) -> decltype(array_reduce(arr)) +constexpr inline auto array_sum(const std::array& arr) -> decltype(array_reduce(arr, static_cast(0))) { - return array_reduce(arr); + return array_reduce(arr, static_cast(0)); } template -constexpr inline auto array_prod(std::array arr) -> decltype(array_reduce(arr)) +constexpr inline auto array_prod(const std::array& arr) -> decltype(array_reduce(arr, static_cast(1))) { - return array_reduce(arr); + return array_reduce(arr, static_cast(1)); } template diff --git a/unsupported/Eigen/CXX11/src/Core/util/EmulateCXX11Meta.h b/unsupported/Eigen/CXX11/src/Core/util/EmulateCXX11Meta.h index 0ae638fb9..ecd1bddf1 100644 --- a/unsupported/Eigen/CXX11/src/Core/util/EmulateCXX11Meta.h +++ b/unsupported/Eigen/CXX11/src/Core/util/EmulateCXX11Meta.h @@ -113,6 +113,35 @@ template class array { }; +// Specialize array for zero size +template class array { + public: + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE T& operator[] (size_t) { + eigen_assert(false && "Can't index a zero size array"); + return *static_cast(NULL); + } + + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE const T& operator[] (size_t) const { + eigen_assert(false && "Can't index a zero size array"); + return *static_cast(NULL); + } + + static EIGEN_ALWAYS_INLINE std::size_t size() { return 0; } + + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE array() { } + +#ifdef EIGEN_HAS_VARIADIC_TEMPLATES + array(std::initializer_list l) { + eigen_assert(l.size() == 0); + } +#endif +}; + + + namespace internal { /** \internal @@ -279,7 +308,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NList::HeadType::type array_prod( return arg_prod::value; } -template +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]; }