mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-08 09:49:03 +08:00
Large code refactoring:
- generalize some utilities and move them to Meta (size(), array_size()) - move handling of all and single indices to IndexedViewHelper.h - several cleanup changes
This commit is contained in:
parent
f93d1c58e0
commit
752bd92ba5
@ -420,6 +420,7 @@ using std::ptrdiff_t;
|
|||||||
// on CUDA devices
|
// on CUDA devices
|
||||||
#include "src/Core/arch/CUDA/Complex.h"
|
#include "src/Core/arch/CUDA/Complex.h"
|
||||||
|
|
||||||
|
#include "src/Core/util/IndexedViewHelper.h"
|
||||||
#include "src/Core/ArithmeticSequence.h"
|
#include "src/Core/ArithmeticSequence.h"
|
||||||
#include "src/Core/DenseCoeffsBase.h"
|
#include "src/Core/DenseCoeffsBase.h"
|
||||||
#include "src/Core/DenseBase.h"
|
#include "src/Core/DenseBase.h"
|
||||||
|
@ -12,26 +12,10 @@
|
|||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
|
||||||
// Pseudo keywords: all, last, end
|
|
||||||
//--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
struct all_t { all_t() {} };
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \var all
|
|
||||||
* \ingroup Core_Module
|
|
||||||
* Can be used as a parameter to DenseBase::operator()(const RowIndices&, const ColIndices&) to index all rows or columns
|
|
||||||
*/
|
|
||||||
static const internal::all_t all;
|
|
||||||
|
|
||||||
/** \namespace Eigen::placeholders
|
/** \namespace Eigen::placeholders
|
||||||
* \ingroup Core_Module
|
* \ingroup Core_Module
|
||||||
*
|
*
|
||||||
* Namespace containing symbolic placeholders
|
* Namespace containing symbolic placeholder and identifiers
|
||||||
*/
|
*/
|
||||||
namespace placeholders {
|
namespace placeholders {
|
||||||
|
|
||||||
@ -268,7 +252,7 @@ typename internal::enable_if<!Symbolic::is_symbolic<FirstType>::value,
|
|||||||
Symbolic::QuotientExpr<Symbolic::AddExpr<Symbolic::AddExpr<LastTypeDerived,Symbolic::ValueExpr>,
|
Symbolic::QuotientExpr<Symbolic::AddExpr<Symbolic::AddExpr<LastTypeDerived,Symbolic::ValueExpr>,
|
||||||
Symbolic::ValueExpr>,
|
Symbolic::ValueExpr>,
|
||||||
Symbolic::ValueExpr>,
|
Symbolic::ValueExpr>,
|
||||||
typename internal::cleanup_seq_type<IncrType>::type> >::type
|
typename internal::cleanup_seq_type<IncrType>::type> >::type
|
||||||
seq(FirstType f, const Symbolic::BaseExpr<LastTypeDerived> &l, IncrType incr)
|
seq(FirstType f, const Symbolic::BaseExpr<LastTypeDerived> &l, IncrType incr)
|
||||||
{
|
{
|
||||||
typedef typename internal::cleanup_seq_type<IncrType>::type CleanedIncrType;
|
typedef typename internal::cleanup_seq_type<IncrType>::type CleanedIncrType;
|
||||||
@ -281,7 +265,7 @@ ArithemeticSequence<FirstTypeDerived,
|
|||||||
Symbolic::NegateExpr<FirstTypeDerived> >,
|
Symbolic::NegateExpr<FirstTypeDerived> >,
|
||||||
Symbolic::ValueExpr>,
|
Symbolic::ValueExpr>,
|
||||||
Symbolic::ValueExpr>,
|
Symbolic::ValueExpr>,
|
||||||
typename internal::cleanup_seq_type<IncrType>::type>
|
typename internal::cleanup_seq_type<IncrType>::type>
|
||||||
seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, const Symbolic::BaseExpr<LastTypeDerived> &l, IncrType incr)
|
seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, const Symbolic::BaseExpr<LastTypeDerived> &l, IncrType incr)
|
||||||
{
|
{
|
||||||
typedef typename internal::cleanup_seq_type<IncrType>::type CleanedIncrType;
|
typedef typename internal::cleanup_seq_type<IncrType>::type CleanedIncrType;
|
||||||
@ -293,76 +277,6 @@ seq(const Symbolic::BaseExpr<FirstTypeDerived> &f, const Symbolic::BaseExpr<Last
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
Index size(const T& x) { return x.size(); }
|
|
||||||
|
|
||||||
template<typename T,std::size_t N>
|
|
||||||
Index size(const T (&) [N]) { return N; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
Index first(const T& x) { return x.first(); }
|
|
||||||
|
|
||||||
template<typename T, int XprSize, typename EnableIf = void> struct get_compile_time_size {
|
|
||||||
enum { value = Dynamic };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, int XprSize> struct get_compile_time_size<T,XprSize,typename internal::enable_if<((T::SizeAtCompileTime&0)==0)>::type> {
|
|
||||||
enum { value = T::SizeAtCompileTime };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, int XprSize, int N> struct get_compile_time_size<const T (&)[N],XprSize> {
|
|
||||||
enum { value = N };
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef EIGEN_HAS_CXX11
|
|
||||||
template<typename T, int XprSize, std::size_t N> struct get_compile_time_size<std::array<T,N>,XprSize> {
|
|
||||||
enum { value = N };
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename T, typename EnableIf = void> struct get_compile_time_incr {
|
|
||||||
enum { value = UndefinedIncr };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType,typename IncrType>
|
|
||||||
struct get_compile_time_incr<ArithemeticSequence<FirstType,SizeType,IncrType> > {
|
|
||||||
enum { value = get_compile_time<IncrType,DynamicIndex>::value };
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// MakeIndexing/make_indexing turn an arbitrary object of type T into something usable by MatrixSlice
|
|
||||||
template<typename T,typename EnableIf=void>
|
|
||||||
struct MakeIndexing {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
const T& make_indexing(const T& x, Index /*size*/) { return x; }
|
|
||||||
|
|
||||||
struct IntAsArray {
|
|
||||||
enum {
|
|
||||||
SizeAtCompileTime = 1
|
|
||||||
};
|
|
||||||
IntAsArray(Index val) : m_value(val) {}
|
|
||||||
Index operator[](Index) const { return m_value; }
|
|
||||||
Index size() const { return 1; }
|
|
||||||
Index first() const { return m_value; }
|
|
||||||
Index m_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct get_compile_time_incr<IntAsArray> {
|
|
||||||
enum { value = 1 }; // 1 or 0 ??
|
|
||||||
};
|
|
||||||
|
|
||||||
// Turn a single index into something that looks like an array (i.e., that exposes a .size(), and operatro[](int) methods)
|
|
||||||
template<typename T>
|
|
||||||
struct MakeIndexing<T,typename internal::enable_if<internal::is_integral<T>::value>::type> {
|
|
||||||
// Here we could simply use Array, but maybe it's less work for the compiler to use
|
|
||||||
// a simpler wrapper as IntAsArray
|
|
||||||
//typedef Eigen::Array<Index,1,1> type;
|
|
||||||
typedef IntAsArray type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Replace symbolic last/end "keywords" by their true runtime value
|
// Replace symbolic last/end "keywords" by their true runtime value
|
||||||
inline Index eval_expr_given_size(Index x, Index /* size */) { return x; }
|
inline Index eval_expr_given_size(Index x, Index /* size */) { return x; }
|
||||||
|
|
||||||
@ -381,45 +295,21 @@ struct make_size_type {
|
|||||||
typedef typename internal::conditional<Symbolic::is_symbolic<T>::value, Index, T>::type type;
|
typedef typename internal::conditional<Symbolic::is_symbolic<T>::value, Index, T>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType,typename IncrType>
|
template<typename FirstType,typename SizeType,typename IncrType,int XprSize>
|
||||||
struct MakeIndexing<ArithemeticSequence<FirstType,SizeType,IncrType> > {
|
struct IndexedViewCompatibleType<ArithemeticSequence<FirstType,SizeType,IncrType>, XprSize> {
|
||||||
typedef ArithemeticSequence<Index,typename make_size_type<SizeType>::type,IncrType> type;
|
typedef ArithemeticSequence<Index,typename make_size_type<SizeType>::type,IncrType> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType,typename IncrType>
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
ArithemeticSequence<Index,typename make_size_type<SizeType>::type,IncrType>
|
ArithemeticSequence<Index,typename make_size_type<SizeType>::type,IncrType>
|
||||||
make_indexing(const ArithemeticSequence<FirstType,SizeType,IncrType>& ids, Index size) {
|
makeIndexedViewCompatible(const ArithemeticSequence<FirstType,SizeType,IncrType>& ids, Index size) {
|
||||||
return ArithemeticSequence<Index,typename make_size_type<SizeType>::type,IncrType>(
|
return ArithemeticSequence<Index,typename make_size_type<SizeType>::type,IncrType>(
|
||||||
eval_expr_given_size(ids.firstObject(),size),eval_expr_given_size(ids.sizeObject(),size),ids.incrObject());
|
eval_expr_given_size(ids.firstObject(),size),eval_expr_given_size(ids.sizeObject(),size),ids.incrObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a symbolic 'all' into a usable range
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
// Implementation-wise, it would be more efficient to not having to store m_size since
|
struct get_compile_time_incr<ArithemeticSequence<FirstType,SizeType,IncrType> > {
|
||||||
// this information is already in the nested expression. To this end, we would need a
|
enum { value = get_compile_time<IncrType,DynamicIndex>::value };
|
||||||
// get_size(indices, underlying_size); function returning indices.size() by default.
|
|
||||||
struct AllRange {
|
|
||||||
AllRange(Index size) : m_size(size) {}
|
|
||||||
Index operator[](Index i) const { return i; }
|
|
||||||
Index size() const { return m_size; }
|
|
||||||
Index first() const { return 0; }
|
|
||||||
Index m_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct MakeIndexing<all_t> {
|
|
||||||
typedef AllRange type;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline AllRange make_indexing(all_t , Index size) {
|
|
||||||
return AllRange(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int XprSize> struct get_compile_time_size<AllRange,XprSize> {
|
|
||||||
enum { value = XprSize };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct get_compile_time_incr<AllRange> {
|
|
||||||
enum { value = 1 };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace internal
|
} // end namespace internal
|
||||||
@ -428,6 +318,7 @@ template<> struct get_compile_time_incr<AllRange> {
|
|||||||
|
|
||||||
namespace legacy {
|
namespace legacy {
|
||||||
// Here are some initial code that I keep here for now to compare the quality of the code generated by the compilers
|
// Here are some initial code that I keep here for now to compare the quality of the code generated by the compilers
|
||||||
|
// This part will be removed once we have checked everything is right.
|
||||||
|
|
||||||
struct shifted_last {
|
struct shifted_last {
|
||||||
explicit shifted_last(int o) : offset(o) {}
|
explicit shifted_last(int o) : offset(o) {}
|
||||||
@ -522,14 +413,14 @@ struct get_compile_time_incr<legacy::ArithemeticSequenceProxyWithBounds<FirstTyp
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Convert a symbolic range into a usable one (i.e., remove last/end "keywords")
|
// Convert a symbolic range into a usable one (i.e., remove last/end "keywords")
|
||||||
template<typename FirstType,typename LastType,typename IncrType>
|
template<typename FirstType,typename LastType,typename IncrType,int XprSize>
|
||||||
struct MakeIndexing<legacy::ArithemeticSequenceProxyWithBounds<FirstType,LastType,IncrType> > {
|
struct IndexedViewCompatibleType<legacy::ArithemeticSequenceProxyWithBounds<FirstType,LastType,IncrType>,XprSize> {
|
||||||
typedef legacy::ArithemeticSequenceProxyWithBounds<Index,Index,IncrType> type;
|
typedef legacy::ArithemeticSequenceProxyWithBounds<Index,Index,IncrType> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FirstType,typename LastType,typename IncrType>
|
template<typename FirstType,typename LastType,typename IncrType>
|
||||||
legacy::ArithemeticSequenceProxyWithBounds<Index,Index,IncrType>
|
legacy::ArithemeticSequenceProxyWithBounds<Index,Index,IncrType>
|
||||||
make_indexing(const legacy::ArithemeticSequenceProxyWithBounds<FirstType,LastType,IncrType>& ids, Index size) {
|
makeIndexedViewCompatible(const legacy::ArithemeticSequenceProxyWithBounds<FirstType,LastType,IncrType>& ids, Index size) {
|
||||||
return legacy::ArithemeticSequenceProxyWithBounds<Index,Index,IncrType>(
|
return legacy::ArithemeticSequenceProxyWithBounds<Index,Index,IncrType>(
|
||||||
eval_expr_given_size(ids.firstObject(),size),eval_expr_given_size(ids.lastObject(),size),ids.incrObject());
|
eval_expr_given_size(ids.firstObject(),size),eval_expr_given_size(ids.lastObject(),size),ids.incrObject());
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ struct traits<IndexedView<XprType, RowIndices, ColIndices> >
|
|||||||
: traits<XprType>
|
: traits<XprType>
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
RowsAtCompileTime = get_compile_time_size<RowIndices,traits<XprType>::RowsAtCompileTime>::value,
|
RowsAtCompileTime = array_size<RowIndices>::value,
|
||||||
ColsAtCompileTime = get_compile_time_size<ColIndices,traits<XprType>::ColsAtCompileTime>::value,
|
ColsAtCompileTime = array_size<ColIndices>::value,
|
||||||
MaxRowsAtCompileTime = RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) : int(traits<XprType>::MaxRowsAtCompileTime),
|
MaxRowsAtCompileTime = RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) : int(traits<XprType>::MaxRowsAtCompileTime),
|
||||||
MaxColsAtCompileTime = ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) : int(traits<XprType>::MaxColsAtCompileTime),
|
MaxColsAtCompileTime = ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) : int(traits<XprType>::MaxColsAtCompileTime),
|
||||||
|
|
||||||
@ -38,8 +38,9 @@ struct traits<IndexedView<XprType, RowIndices, ColIndices> >
|
|||||||
XprInnerStride = HasSameStorageOrderAsXprType ? int(inner_stride_at_compile_time<XprType>::ret) : int(outer_stride_at_compile_time<XprType>::ret),
|
XprInnerStride = HasSameStorageOrderAsXprType ? int(inner_stride_at_compile_time<XprType>::ret) : int(outer_stride_at_compile_time<XprType>::ret),
|
||||||
XprOuterstride = HasSameStorageOrderAsXprType ? int(outer_stride_at_compile_time<XprType>::ret) : int(inner_stride_at_compile_time<XprType>::ret),
|
XprOuterstride = HasSameStorageOrderAsXprType ? int(outer_stride_at_compile_time<XprType>::ret) : int(inner_stride_at_compile_time<XprType>::ret),
|
||||||
|
|
||||||
|
InnerSize = XprTypeIsRowMajor ? ColsAtCompileTime : RowsAtCompileTime,
|
||||||
IsBlockAlike = InnerIncr==1 && OuterIncr==1,
|
IsBlockAlike = InnerIncr==1 && OuterIncr==1,
|
||||||
IsInnerPannel = HasSameStorageOrderAsXprType && is_same<AllRange,typename conditional<XprTypeIsRowMajor,ColIndices,RowIndices>::type>::value,
|
IsInnerPannel = HasSameStorageOrderAsXprType && is_same<AllRange<InnerSize>,typename conditional<XprTypeIsRowMajor,ColIndices,RowIndices>::type>::value,
|
||||||
|
|
||||||
InnerStrideAtCompileTime = InnerIncr<0 || InnerIncr==DynamicIndex || XprInnerStride==Dynamic ? Dynamic : XprInnerStride * InnerIncr,
|
InnerStrideAtCompileTime = InnerIncr<0 || InnerIncr==DynamicIndex || XprInnerStride==Dynamic ? Dynamic : XprInnerStride * InnerIncr,
|
||||||
OuterStrideAtCompileTime = OuterIncr<0 || OuterIncr==DynamicIndex || XprOuterstride==Dynamic ? Dynamic : XprOuterstride * OuterIncr,
|
OuterStrideAtCompileTime = OuterIncr<0 || OuterIncr==DynamicIndex || XprOuterstride==Dynamic ? Dynamic : XprOuterstride * OuterIncr,
|
||||||
|
111
Eigen/src/Core/util/IndexedViewHelper.h
Normal file
111
Eigen/src/Core/util/IndexedViewHelper.h
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||||
|
//
|
||||||
|
// 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_INDEXED_VIEW_HELPER_H
|
||||||
|
#define EIGEN_INDEXED_VIEW_HELPER_H
|
||||||
|
|
||||||
|
namespace Eigen {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Extract increment/step at compile time
|
||||||
|
template<typename T, typename EnableIf = void> struct get_compile_time_incr {
|
||||||
|
enum { value = UndefinedIncr };
|
||||||
|
};
|
||||||
|
|
||||||
|
// Analogue of std::get<0>(x), but tailored for our needs.
|
||||||
|
template<typename T>
|
||||||
|
Index first(const T& x) { return x.first(); }
|
||||||
|
|
||||||
|
// IndexedViewCompatibleType/makeIndexedViewCompatible turn an arbitrary object of type T into something usable by MatrixSlice
|
||||||
|
// The generic implementation is a no-op
|
||||||
|
template<typename T,int XprSize,typename EnableIf=void>
|
||||||
|
struct IndexedViewCompatibleType {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
const T& makeIndexedViewCompatible(const T& x, Index /*size*/) { return x; }
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
// Handling of a single Index
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct SingleRange {
|
||||||
|
enum {
|
||||||
|
SizeAtCompileTime = 1
|
||||||
|
};
|
||||||
|
SingleRange(Index val) : m_value(val) {}
|
||||||
|
Index operator[](Index) const { return m_value; }
|
||||||
|
Index size() const { return 1; }
|
||||||
|
Index first() const { return m_value; }
|
||||||
|
Index m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct get_compile_time_incr<SingleRange> {
|
||||||
|
enum { value = 1 }; // 1 or 0 ??
|
||||||
|
};
|
||||||
|
|
||||||
|
// Turn a single index into something that looks like an array (i.e., that exposes a .size(), and operatro[](int) methods)
|
||||||
|
template<typename T, int XprSize>
|
||||||
|
struct IndexedViewCompatibleType<T,XprSize,typename internal::enable_if<internal::is_integral<T>::value>::type> {
|
||||||
|
// Here we could simply use Array, but maybe it's less work for the compiler to use
|
||||||
|
// a simpler wrapper as SingleRange
|
||||||
|
//typedef Eigen::Array<Index,1,1> type;
|
||||||
|
typedef SingleRange type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
// Handling of all
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct all_t { all_t() {} };
|
||||||
|
|
||||||
|
// Convert a symbolic 'all' into a usable range type
|
||||||
|
template<int XprSize>
|
||||||
|
struct AllRange {
|
||||||
|
enum { SizeAtCompileTime = XprSize };
|
||||||
|
AllRange(Index size = XprSize) : m_size(size) {}
|
||||||
|
Index operator[](Index i) const { return i; }
|
||||||
|
Index size() const { return m_size.value(); }
|
||||||
|
Index first() const { return 0; }
|
||||||
|
variable_if_dynamic<Index,XprSize> m_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int XprSize>
|
||||||
|
struct IndexedViewCompatibleType<all_t,XprSize> {
|
||||||
|
typedef AllRange<XprSize> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename XprSizeType>
|
||||||
|
inline AllRange<get_compile_time<XprSizeType>::value> makeIndexedViewCompatible(all_t , XprSizeType size) {
|
||||||
|
return AllRange<get_compile_time<XprSizeType>::value>(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int Size> struct get_compile_time_incr<AllRange<Size> > {
|
||||||
|
enum { value = 1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace internal
|
||||||
|
|
||||||
|
|
||||||
|
namespace placeholders {
|
||||||
|
|
||||||
|
/** \var all
|
||||||
|
* \ingroup Core_Module
|
||||||
|
* Can be used as a parameter to DenseBase::operator()(const RowIndices&, const ColIndices&) to index all rows or columns
|
||||||
|
*/
|
||||||
|
static const Eigen::internal::all_t all;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace Eigen
|
||||||
|
|
||||||
|
#endif // EIGEN_INDEXED_VIEW_HELPER_H
|
@ -278,6 +278,53 @@ protected:
|
|||||||
EIGEN_DEVICE_FUNC ~noncopyable() {}
|
EIGEN_DEVICE_FUNC ~noncopyable() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \internal
|
||||||
|
* Provides access to the number of elements in the object of as a compile-time constant expression.
|
||||||
|
* It "returns" Eigen::Dynamic if the size cannot be resolved at compile-time (default).
|
||||||
|
*
|
||||||
|
* Similar to std::tuple_size, but more general.
|
||||||
|
*
|
||||||
|
* It currently supports:
|
||||||
|
* - any types T defining T::SizeAtCompileTime
|
||||||
|
* - plain C arrays as T[N]
|
||||||
|
* - std::array (c++11)
|
||||||
|
* - some internal types such as SingleRange and AllRange
|
||||||
|
*
|
||||||
|
* The second template parameter ease SFINAE-based specializations.
|
||||||
|
*/
|
||||||
|
template<typename T, typename EnableIf = void> struct array_size {
|
||||||
|
enum { value = Dynamic };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T> struct array_size<T,typename internal::enable_if<((T::SizeAtCompileTime&0)==0)>::type> {
|
||||||
|
enum { value = T::SizeAtCompileTime };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, int N> struct array_size<const T (&)[N]> {
|
||||||
|
enum { value = N };
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef EIGEN_HAS_CXX11
|
||||||
|
template<typename T, std::size_t N> struct array_size<std::array<T,N> > {
|
||||||
|
enum { value = N };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \internal
|
||||||
|
* Analogue of the std::size free function.
|
||||||
|
* It returns the size of the container or view \a x of type \c T
|
||||||
|
*
|
||||||
|
* It currently supports:
|
||||||
|
* - any types T defining a member T::size() const
|
||||||
|
* - plain C arrays as T[N]
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
Index size(const T& x) { return x.size(); }
|
||||||
|
|
||||||
|
template<typename T,std::size_t N>
|
||||||
|
Index size(const T (&) [N]) { return N; }
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* Convenient struct to get the result type of a unary or binary functor.
|
* Convenient struct to get the result type of a unary or binary functor.
|
||||||
*
|
*
|
||||||
|
@ -19,11 +19,49 @@
|
|||||||
#define EIGEN_INDEXED_VIEW_METHOD_TYPE IndexedViewType
|
#define EIGEN_INDEXED_VIEW_METHOD_TYPE IndexedViewType
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef EIGEN_INDEXED_VIEW_METHOD_2ND_PASS
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// define some aliases to ease readability
|
||||||
|
|
||||||
|
template<typename Indices>
|
||||||
|
struct IvcRowType : public internal::IndexedViewCompatibleType<Indices,RowsAtCompileTime> {};
|
||||||
|
|
||||||
|
template<typename Indices>
|
||||||
|
struct IvcColType : public internal::IndexedViewCompatibleType<Indices,ColsAtCompileTime> {};
|
||||||
|
|
||||||
|
template<typename Indices>
|
||||||
|
struct IvcType : public internal::IndexedViewCompatibleType<Indices,SizeAtCompileTime> {};
|
||||||
|
|
||||||
|
typedef typename internal::IndexedViewCompatibleType<Index,1>::type IvcIndex;
|
||||||
|
|
||||||
|
template<typename Indices>
|
||||||
|
typename IvcRowType<Indices>::type
|
||||||
|
ivcRow(const Indices& indices) const {
|
||||||
|
return internal::makeIndexedViewCompatible(indices, internal::variable_if_dynamic<Index,RowsAtCompileTime>(derived().rows()));
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Indices>
|
||||||
|
typename IvcColType<Indices>::type
|
||||||
|
ivcCol(const Indices& indices) const {
|
||||||
|
return internal::makeIndexedViewCompatible(indices, internal::variable_if_dynamic<Index,ColsAtCompileTime>(derived().cols()));
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Indices>
|
||||||
|
typename IvcColType<Indices>::type
|
||||||
|
ivcSize(const Indices& indices) const {
|
||||||
|
return internal::makeIndexedViewCompatible(indices, internal::variable_if_dynamic<Index,SizeAtCompileTime>(derived().size()));
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename RowIndices, typename ColIndices>
|
template<typename RowIndices, typename ColIndices>
|
||||||
struct EIGEN_INDEXED_VIEW_METHOD_TYPE {
|
struct EIGEN_INDEXED_VIEW_METHOD_TYPE {
|
||||||
typedef IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,
|
typedef IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,
|
||||||
typename internal::MakeIndexing<RowIndices>::type,
|
typename IvcRowType<RowIndices>::type,
|
||||||
typename internal::MakeIndexing<ColIndices>::type> type;
|
typename IvcColType<ColIndices>::type> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is the generic version
|
// This is the generic version
|
||||||
@ -36,7 +74,7 @@ typename internal::enable_if<
|
|||||||
operator()(const RowIndices& rowIndices, const ColIndices& colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST
|
operator()(const RowIndices& rowIndices, const ColIndices& colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST
|
||||||
{
|
{
|
||||||
return typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type
|
return typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type
|
||||||
(derived(), internal::make_indexing(rowIndices,derived().rows()), internal::make_indexing(colIndices,derived().cols()));
|
(derived(), ivcRow(rowIndices), ivcCol(colIndices));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The folowing overload returns a Block<> object
|
// The folowing overload returns a Block<> object
|
||||||
@ -49,8 +87,8 @@ typename internal::enable_if<
|
|||||||
operator()(const RowIndices& rowIndices, const ColIndices& colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST
|
operator()(const RowIndices& rowIndices, const ColIndices& colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST
|
||||||
{
|
{
|
||||||
typedef typename internal::traits<typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type>::BlockType BlockType;
|
typedef typename internal::traits<typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type>::BlockType BlockType;
|
||||||
typename internal::MakeIndexing<RowIndices>::type actualRowIndices = internal::make_indexing(rowIndices,derived().rows());
|
typename IvcRowType<RowIndices>::type actualRowIndices = ivcRow(rowIndices);
|
||||||
typename internal::MakeIndexing<ColIndices>::type actualColIndices = internal::make_indexing(colIndices,derived().cols());
|
typename IvcColType<ColIndices>::type actualColIndices = ivcCol(colIndices);
|
||||||
return BlockType(derived(),
|
return BlockType(derived(),
|
||||||
internal::first(actualRowIndices),
|
internal::first(actualRowIndices),
|
||||||
internal::first(actualColIndices),
|
internal::first(actualColIndices),
|
||||||
@ -61,19 +99,19 @@ operator()(const RowIndices& rowIndices, const ColIndices& colIndices) EIGEN_IND
|
|||||||
// The folowing three overloads are needed to handle raw Index[N] arrays.
|
// The folowing three overloads are needed to handle raw Index[N] arrays.
|
||||||
|
|
||||||
template<typename RowIndicesT, std::size_t RowIndicesN, typename ColIndices>
|
template<typename RowIndicesT, std::size_t RowIndicesN, typename ColIndices>
|
||||||
IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const RowIndicesT (&)[RowIndicesN],typename internal::MakeIndexing<ColIndices>::type>
|
IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const RowIndicesT (&)[RowIndicesN],typename IvcColType<ColIndices>::type>
|
||||||
operator()(const RowIndicesT (&rowIndices)[RowIndicesN], const ColIndices& colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST
|
operator()(const RowIndicesT (&rowIndices)[RowIndicesN], const ColIndices& colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST
|
||||||
{
|
{
|
||||||
return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const RowIndicesT (&)[RowIndicesN],typename internal::MakeIndexing<ColIndices>::type>
|
return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const RowIndicesT (&)[RowIndicesN],typename IvcColType<ColIndices>::type>
|
||||||
(derived(), rowIndices, internal::make_indexing(colIndices,derived().cols()));
|
(derived(), rowIndices, ivcCol(colIndices));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RowIndices, typename ColIndicesT, std::size_t ColIndicesN>
|
template<typename RowIndices, typename ColIndicesT, std::size_t ColIndicesN>
|
||||||
IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename internal::MakeIndexing<RowIndices>::type, const ColIndicesT (&)[ColIndicesN]>
|
IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename IvcRowType<RowIndices>::type, const ColIndicesT (&)[ColIndicesN]>
|
||||||
operator()(const RowIndices& rowIndices, const ColIndicesT (&colIndices)[ColIndicesN]) EIGEN_INDEXED_VIEW_METHOD_CONST
|
operator()(const RowIndices& rowIndices, const ColIndicesT (&colIndices)[ColIndicesN]) EIGEN_INDEXED_VIEW_METHOD_CONST
|
||||||
{
|
{
|
||||||
return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename internal::MakeIndexing<RowIndices>::type,const ColIndicesT (&)[ColIndicesN]>
|
return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename IvcRowType<RowIndices>::type,const ColIndicesT (&)[ColIndicesN]>
|
||||||
(derived(), internal::make_indexing(rowIndices,derived().rows()), colIndices);
|
(derived(), ivcRow(rowIndices), colIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename RowIndicesT, std::size_t RowIndicesN, typename ColIndicesT, std::size_t ColIndicesN>
|
template<typename RowIndicesT, std::size_t RowIndicesN, typename ColIndicesT, std::size_t ColIndicesN>
|
||||||
@ -88,56 +126,56 @@ operator()(const RowIndicesT (&rowIndices)[RowIndicesN], const ColIndicesT (&col
|
|||||||
|
|
||||||
template<typename Indices>
|
template<typename Indices>
|
||||||
typename internal::enable_if<
|
typename internal::enable_if<
|
||||||
IsRowMajor && (!(internal::get_compile_time_incr<typename internal::MakeIndexing<Indices>::type>::value==1 || internal::is_integral<Indices>::value)),
|
IsRowMajor && (!(internal::get_compile_time_incr<typename IvcType<Indices>::type>::value==1 || internal::is_integral<Indices>::value)),
|
||||||
IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename internal::MakeIndexing<Index>::type,typename internal::MakeIndexing<Indices>::type> >::type
|
IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,IvcIndex,typename IvcType<Indices>::type> >::type
|
||||||
operator()(const Indices& indices) EIGEN_INDEXED_VIEW_METHOD_CONST
|
operator()(const Indices& indices) EIGEN_INDEXED_VIEW_METHOD_CONST
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename internal::MakeIndexing<Index>::type,typename internal::MakeIndexing<Indices>::type>
|
return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,IvcIndex,typename IvcType<Indices>::type>
|
||||||
(derived(), internal::make_indexing(0,derived().rows()), internal::make_indexing(indices,derived().cols()));
|
(derived(), IvcIndex(0), ivcCol(indices));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Indices>
|
template<typename Indices>
|
||||||
typename internal::enable_if<
|
typename internal::enable_if<
|
||||||
(!IsRowMajor) && (!(internal::get_compile_time_incr<typename internal::MakeIndexing<Indices>::type>::value==1 || internal::is_integral<Indices>::value)),
|
(!IsRowMajor) && (!(internal::get_compile_time_incr<typename IvcType<Indices>::type>::value==1 || internal::is_integral<Indices>::value)),
|
||||||
IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename internal::MakeIndexing<Indices>::type,typename internal::MakeIndexing<Index>::type> >::type
|
IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename IvcType<Indices>::type,IvcIndex> >::type
|
||||||
operator()(const Indices& indices) EIGEN_INDEXED_VIEW_METHOD_CONST
|
operator()(const Indices& indices) EIGEN_INDEXED_VIEW_METHOD_CONST
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename internal::MakeIndexing<Indices>::type,typename internal::MakeIndexing<Index>::type>
|
return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename IvcType<Indices>::type,IvcIndex>
|
||||||
(derived(), internal::make_indexing(indices,derived().rows()), internal::make_indexing(Index(0),derived().cols()));
|
(derived(), ivcRow(indices), IvcIndex(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Indices>
|
template<typename Indices>
|
||||||
typename internal::enable_if<
|
typename internal::enable_if<
|
||||||
(internal::get_compile_time_incr<typename internal::MakeIndexing<Indices>::type>::value==1) && (!internal::is_integral<Indices>::value),
|
(internal::get_compile_time_incr<typename IvcType<Indices>::type>::value==1) && (!internal::is_integral<Indices>::value),
|
||||||
VectorBlock<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,internal::get_compile_time_size<Indices,SizeAtCompileTime>::value> >::type
|
VectorBlock<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,internal::array_size<Indices>::value> >::type
|
||||||
operator()(const Indices& indices) EIGEN_INDEXED_VIEW_METHOD_CONST
|
operator()(const Indices& indices) EIGEN_INDEXED_VIEW_METHOD_CONST
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
typename internal::MakeIndexing<Indices>::type actualIndices = internal::make_indexing(indices,derived().size());
|
typename IvcType<Indices>::type actualIndices = ivcSize(indices);
|
||||||
return VectorBlock<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,internal::get_compile_time_size<Indices,SizeAtCompileTime>::value>
|
return VectorBlock<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,internal::array_size<Indices>::value>
|
||||||
(derived(), internal::first(actualIndices), internal::size(actualIndices));
|
(derived(), internal::first(actualIndices), internal::size(actualIndices));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename IndicesT, std::size_t IndicesN>
|
template<typename IndicesT, std::size_t IndicesN>
|
||||||
typename internal::enable_if<IsRowMajor,
|
typename internal::enable_if<IsRowMajor,
|
||||||
IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename internal::MakeIndexing<Index>::type,const IndicesT (&)[IndicesN]> >::type
|
IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,IvcIndex,const IndicesT (&)[IndicesN]> >::type
|
||||||
operator()(const IndicesT (&indices)[IndicesN]) EIGEN_INDEXED_VIEW_METHOD_CONST
|
operator()(const IndicesT (&indices)[IndicesN]) EIGEN_INDEXED_VIEW_METHOD_CONST
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename internal::MakeIndexing<Index>::type,const IndicesT (&)[IndicesN]>
|
return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,IvcIndex,const IndicesT (&)[IndicesN]>
|
||||||
(derived(), internal::make_indexing(0,derived().rows()), indices);
|
(derived(), IvcIndex(0), indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename IndicesT, std::size_t IndicesN>
|
template<typename IndicesT, std::size_t IndicesN>
|
||||||
typename internal::enable_if<!IsRowMajor,
|
typename internal::enable_if<!IsRowMajor,
|
||||||
IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const IndicesT (&)[IndicesN],typename internal::MakeIndexing<Index>::type> >::type
|
IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const IndicesT (&)[IndicesN],IvcIndex> >::type
|
||||||
operator()(const IndicesT (&indices)[IndicesN]) EIGEN_INDEXED_VIEW_METHOD_CONST
|
operator()(const IndicesT (&indices)[IndicesN]) EIGEN_INDEXED_VIEW_METHOD_CONST
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const IndicesT (&)[IndicesN],typename internal::MakeIndexing<Index>::type>
|
return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const IndicesT (&)[IndicesN],IvcIndex>
|
||||||
(derived(), indices, internal::make_indexing(0,derived().rows()));
|
(derived(), indices, IvcIndex(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef EIGEN_INDEXED_VIEW_METHOD_CONST
|
#undef EIGEN_INDEXED_VIEW_METHOD_CONST
|
||||||
|
@ -51,6 +51,7 @@ is_same_type(const T1& a, const T2& b)
|
|||||||
|
|
||||||
void check_indexed_view()
|
void check_indexed_view()
|
||||||
{
|
{
|
||||||
|
using Eigen::placeholders::all;
|
||||||
using Eigen::placeholders::last;
|
using Eigen::placeholders::last;
|
||||||
using Eigen::placeholders::end;
|
using Eigen::placeholders::end;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user