aboutsummaryrefslogtreecommitdiffhomepage
path: root/unsupported/Eigen
diff options
context:
space:
mode:
authorGravatar Benoit Steiner <benoit.steiner.goog@gmail.com>2015-10-23 10:20:51 -0700
committerGravatar Benoit Steiner <benoit.steiner.goog@gmail.com>2015-10-23 10:20:51 -0700
commit57857775b461b020c16f2bbeb130d6b1863d951c (patch)
tree28d42daaeca3ffb40e2593b9d2872873d9c629e2 /unsupported/Eigen
parentc40c2ceb27d8a9dabadcbf46a4e3161f3189992f (diff)
Added support for arrays of size 0
Diffstat (limited to 'unsupported/Eigen')
-rw-r--r--unsupported/Eigen/CXX11/src/Core/util/CXX11Meta.h30
-rw-r--r--unsupported/Eigen/CXX11/src/Core/util/EmulateCXX11Meta.h31
2 files changed, 50 insertions, 11 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<typename a, typename... as> struct get<0, type_lis
template<int n EIGEN_TPL_PP_SPEC_HACK_DEFC(typename, as)> struct get<n, type_list<EIGEN_TPL_PP_SPEC_HACK_USE(as)>> { 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<typename T, int n, T a, T... as> struct get<n, numeric_list<T, a, as...>> : get<n-1, numeric_list<T, as...>> {};
-template<typename T, T a, T... as> struct get<0, numeric_list<T, a, as...>> { constexpr static int value = a; };
+template<typename T, T a, T... as> struct get<0, numeric_list<T, a, as...>> { constexpr static T value = a; };
template<typename T, int n EIGEN_TPL_PP_SPEC_HACK_DEFC(T, as)> struct get<n, numeric_list<T EIGEN_TPL_PP_SPEC_HACK_USEC(as)>> { 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<T, N> array_reverse(std::array<T, N> arr)
return h_array_reverse(arr, typename gen_numeric_list<int, N>::type());
}
+
/* generic array reductions */
// can't reuse standard reduce() interface above because Intel's Compiler
@@ -335,39 +336,48 @@ constexpr inline std::array<T, N> array_reverse(std::array<T, N> arr)
// an infinite loop)
template<typename Reducer, typename T, std::size_t N, std::size_t n = N - 1>
struct h_array_reduce {
- constexpr static inline auto run(std::array<T, N> arr) -> decltype(Reducer::run(h_array_reduce<Reducer, T, N, n - 1>::run(arr), array_get<n>(arr)))
+ constexpr static inline auto run(std::array<T, N> arr, T identity) -> decltype(Reducer::run(h_array_reduce<Reducer, T, N, n - 1>::run(arr, identity), array_get<n>(arr)))
{
- return Reducer::run(h_array_reduce<Reducer, T, N, n - 1>::run(arr), array_get<n>(arr));
+ return Reducer::run(h_array_reduce<Reducer, T, N, n - 1>::run(arr, identity), array_get<n>(arr));
}
};
template<typename Reducer, typename T, std::size_t N>
struct h_array_reduce<Reducer, T, N, 0>
{
- constexpr static inline T run(std::array<T, N> arr)
+ constexpr static inline T run(const std::array<T, N>& arr, T identity)
{
return array_get<0>(arr);
}
};
+template<typename Reducer, typename T>
+struct h_array_reduce<Reducer, T, 0>
+{
+ constexpr static inline T run(const std::array<T, 0>& arr, T identity)
+ {
+ return identity;
+ }
+};
+
template<typename Reducer, typename T, std::size_t N>
-constexpr inline auto array_reduce(std::array<T, N> arr) -> decltype(h_array_reduce<Reducer, T, N>::run(arr))
+constexpr inline auto array_reduce(const std::array<T, N>& arr, T identity) -> decltype(h_array_reduce<Reducer, T, N>::run(arr, identity))
{
- return h_array_reduce<Reducer, T, N>::run(arr);
+ return h_array_reduce<Reducer, T, N>::run(arr, identity);
}
/* standard array reductions */
template<typename T, std::size_t N>
-constexpr inline auto array_sum(std::array<T, N> arr) -> decltype(array_reduce<sum_op, T, N>(arr))
+constexpr inline auto array_sum(const std::array<T, N>& arr) -> decltype(array_reduce<sum_op, T, N>(arr, static_cast<T>(0)))
{
- return array_reduce<sum_op, T, N>(arr);
+ return array_reduce<sum_op, T, N>(arr, static_cast<T>(0));
}
template<typename T, std::size_t N>
-constexpr inline auto array_prod(std::array<T, N> arr) -> decltype(array_reduce<product_op, T, N>(arr))
+constexpr inline auto array_prod(const std::array<T, N>& arr) -> decltype(array_reduce<product_op, T, N>(arr, static_cast<T>(1)))
{
- return array_reduce<product_op, T, N>(arr);
+ return array_reduce<product_op, T, N>(arr, static_cast<T>(1));
}
template<typename t>
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 <typename T, size_t n> class array {
};
+// Specialize array for zero size
+template <typename T> class array<T, 0> {
+ public:
+ EIGEN_DEVICE_FUNC
+ EIGEN_STRONG_INLINE T& operator[] (size_t) {
+ eigen_assert(false && "Can't index a zero size array");
+ return *static_cast<T*>(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<const T*>(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<T> 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<NList>::value;
}
-template<std::size_t n, typename t>
+template<typename t, std::size_t n>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE t array_prod(const array<t, n>& a) {
t prod = 1;
for (size_t i = 0; i < n; ++i) { prod *= a[i]; }