mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-05-22 04:27:36 +08:00
Misc improvements
This commit is contained in:
parent
4cdf3fe427
commit
703c526355
@ -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>
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user