mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-12 03:39:01 +08:00
Use "fix" for compile-time values, propagate compile-time sizes for span, clean some cleanup.
This commit is contained in:
parent
60e99ad8d7
commit
3730e3ca9e
@ -12,6 +12,9 @@
|
|||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
// Pseudo keywords: all, last, end
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
|
||||||
struct all_t { all_t() {} };
|
struct all_t { all_t() {} };
|
||||||
static const all_t all;
|
static const all_t all;
|
||||||
@ -51,32 +54,55 @@ struct end_t {
|
|||||||
};
|
};
|
||||||
static const end_t end;
|
static const end_t end;
|
||||||
|
|
||||||
template<int N> struct Index_c {
|
//--------------------------------------------------------------------------------
|
||||||
|
// integral constant
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<int N> struct fix_t {
|
||||||
static const int value = N;
|
static const int value = N;
|
||||||
operator int() const { return value; }
|
operator int() const { return value; }
|
||||||
Index_c (Index_c<N> (*)() ) {}
|
fix_t (fix_t<N> (*)() ) {}
|
||||||
Index_c() {}
|
fix_t() {}
|
||||||
// Needed in C++14 to allow c<N>():
|
// Needed in C++14 to allow fix<N>():
|
||||||
Index_c operator() () const { return *this; }
|
fix_t operator() () const { return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T, int Default=Dynamic> struct get_compile_time {
|
||||||
|
enum { value = Default };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int N,int Default> struct get_compile_time<fix_t<N>,Default> {
|
||||||
|
enum { value = N };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T> struct is_compile_time { enum { value = false }; };
|
||||||
|
template<int N> struct is_compile_time<fix_t<N> > { enum { value = true }; };
|
||||||
|
|
||||||
|
#if __cplusplus > 201103L
|
||||||
|
template<int N>
|
||||||
|
static const fix_t<N> fix{};
|
||||||
|
#else
|
||||||
|
template<int N>
|
||||||
|
inline fix_t<N> fix() { return fix_t<N>(); }
|
||||||
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
// Range(first,last) and Slice(first,step,last)
|
// range(first,last,incr) and span(first,size,incr)
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<typename FirstType=Index,typename LastType=Index,typename StepType=Index_c<1> >
|
template<typename FirstType=Index,typename LastType=Index,typename IncrType=fix_t<1> >
|
||||||
struct Range_t {
|
struct Range_t {
|
||||||
Range_t(FirstType f, LastType l) : m_first(f), m_last(l) {}
|
Range_t(FirstType f, LastType l) : m_first(f), m_last(l) {}
|
||||||
Range_t(FirstType f, LastType l, StepType s) : m_first(f), m_last(l), m_step(s) {}
|
Range_t(FirstType f, LastType l, IncrType s) : m_first(f), m_last(l), m_incr(s) {}
|
||||||
|
|
||||||
FirstType m_first;
|
FirstType m_first;
|
||||||
LastType m_last;
|
LastType m_last;
|
||||||
StepType m_step;
|
IncrType m_incr;
|
||||||
|
|
||||||
enum { SizeAtCompileTime = -1 };
|
enum { SizeAtCompileTime = -1 };
|
||||||
|
|
||||||
Index size() const { return (m_last-m_first+m_step)/m_step; }
|
Index size() const { return (m_last-m_first+m_incr)/m_incr; }
|
||||||
Index operator[] (Index k) const { return m_first + k*m_step; }
|
Index operator[] (Index k) const { return m_first + k*m_incr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> struct cleanup_slice_type { typedef Index type; };
|
template<typename T> struct cleanup_slice_type { typedef Index type; };
|
||||||
@ -84,8 +110,8 @@ template<> struct cleanup_slice_type<last_t> { typedef last_t type; };
|
|||||||
template<> struct cleanup_slice_type<shifted_last> { typedef shifted_last type; };
|
template<> struct cleanup_slice_type<shifted_last> { typedef shifted_last type; };
|
||||||
template<> struct cleanup_slice_type<end_t> { typedef end_t type; };
|
template<> struct cleanup_slice_type<end_t> { typedef end_t type; };
|
||||||
template<> struct cleanup_slice_type<shifted_end> { typedef shifted_end type; };
|
template<> struct cleanup_slice_type<shifted_end> { typedef shifted_end type; };
|
||||||
template<int N> struct cleanup_slice_type<Index_c<N> > { typedef Index_c<N> type; };
|
template<int N> struct cleanup_slice_type<fix_t<N> > { typedef fix_t<N> type; };
|
||||||
template<int N> struct cleanup_slice_type<Index_c<N> (*)() > { typedef Index_c<N> type; };
|
template<int N> struct cleanup_slice_type<fix_t<N> (*)() > { typedef fix_t<N> type; };
|
||||||
|
|
||||||
template<typename FirstType,typename LastType>
|
template<typename FirstType,typename LastType>
|
||||||
Range_t<typename cleanup_slice_type<FirstType>::type,typename cleanup_slice_type<LastType>::type >
|
Range_t<typename cleanup_slice_type<FirstType>::type,typename cleanup_slice_type<LastType>::type >
|
||||||
@ -93,43 +119,34 @@ range(FirstType f, LastType l) {
|
|||||||
return Range_t<typename cleanup_slice_type<FirstType>::type,typename cleanup_slice_type<LastType>::type>(f,l);
|
return Range_t<typename cleanup_slice_type<FirstType>::type,typename cleanup_slice_type<LastType>::type>(f,l);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FirstType,typename LastType,typename StepType>
|
template<typename FirstType,typename LastType,typename IncrType>
|
||||||
Range_t<typename cleanup_slice_type<FirstType>::type,typename cleanup_slice_type<LastType>::type,typename cleanup_slice_type<StepType>::type >
|
Range_t<typename cleanup_slice_type<FirstType>::type,typename cleanup_slice_type<LastType>::type,typename cleanup_slice_type<IncrType>::type >
|
||||||
range(FirstType f, LastType l, StepType s) {
|
range(FirstType f, LastType l, IncrType s) {
|
||||||
return Range_t<typename cleanup_slice_type<FirstType>::type,typename cleanup_slice_type<LastType>::type,typename cleanup_slice_type<StepType>::type>(f,l,typename cleanup_slice_type<StepType>::type(s));
|
return Range_t<typename cleanup_slice_type<FirstType>::type,typename cleanup_slice_type<LastType>::type,typename cleanup_slice_type<IncrType>::type>(f,l,typename cleanup_slice_type<IncrType>::type(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T, int Default=-1> struct get_compile_time {
|
|
||||||
enum { value = Default };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int N,int Default> struct get_compile_time<Index_c<N>,Default> {
|
|
||||||
enum { value = N };
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T> struct is_compile_time { enum { value = false }; };
|
template<typename FirstType=Index,typename SizeType=Index,typename IncrType=fix_t<1> >
|
||||||
template<int N> struct is_compile_time<Index_c<N> > { enum { value = true }; };
|
|
||||||
|
|
||||||
template<typename FirstType=Index,typename SizeType=Index,typename StepType=Index_c<1> >
|
|
||||||
struct Span_t {
|
struct Span_t {
|
||||||
Span_t(FirstType first, SizeType size) : m_first(first), m_size(size) {}
|
Span_t(FirstType first, SizeType size) : m_first(first), m_size(size) {}
|
||||||
Span_t(FirstType first, SizeType size, StepType step) : m_first(first), m_size(size), m_step(step) {}
|
Span_t(FirstType first, SizeType size, IncrType incr) : m_first(first), m_size(size), m_incr(incr) {}
|
||||||
|
|
||||||
FirstType m_first;
|
FirstType m_first;
|
||||||
SizeType m_size;
|
SizeType m_size;
|
||||||
StepType m_step;
|
IncrType m_incr;
|
||||||
|
|
||||||
enum { SizeAtCompileTime = get_compile_time<SizeType>::value };
|
enum { SizeAtCompileTime = get_compile_time<SizeType>::value };
|
||||||
|
|
||||||
Index size() const { return m_size; }
|
Index size() const { return m_size; }
|
||||||
Index operator[] (Index k) const { return m_first + k*m_step; }
|
Index operator[] (Index k) const { return m_first + k*m_incr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType,typename StepType>
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
Span_t<typename cleanup_slice_type<FirstType>::type,typename cleanup_slice_type<SizeType>::type,typename cleanup_slice_type<StepType>::type >
|
Span_t<typename cleanup_slice_type<FirstType>::type,typename cleanup_slice_type<SizeType>::type,typename cleanup_slice_type<IncrType>::type >
|
||||||
span(FirstType first, SizeType size, StepType step) {
|
span(FirstType first, SizeType size, IncrType incr) {
|
||||||
return Span_t<typename cleanup_slice_type<FirstType>::type,typename cleanup_slice_type<SizeType>::type,typename cleanup_slice_type<StepType>::type>(first,size,step);
|
return Span_t<typename cleanup_slice_type<FirstType>::type,typename cleanup_slice_type<SizeType>::type,typename cleanup_slice_type<IncrType>::type>(first,size,incr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType>
|
template<typename FirstType,typename SizeType>
|
||||||
@ -138,16 +155,24 @@ span(FirstType first, SizeType size) {
|
|||||||
return Span_t<typename cleanup_slice_type<FirstType>::type,typename cleanup_slice_type<SizeType>::type>(first,size);
|
return Span_t<typename cleanup_slice_type<FirstType>::type,typename cleanup_slice_type<SizeType>::type>(first,size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __cplusplus > 201103L
|
|
||||||
template<int N>
|
|
||||||
static const Index_c<N> c{};
|
|
||||||
#else
|
|
||||||
template<int N>
|
|
||||||
inline Index_c<N> c() { return Index_c<N>(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
template<typename T, typename EnableIf = void> struct get_compile_time_size {
|
||||||
|
enum { value = -1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T> struct get_compile_time_size<T,typename internal::enable_if<((T::SizeAtCompileTime&0)==0)>::type> {
|
||||||
|
enum { value = T::SizeAtCompileTime };
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef EIGEN_HAS_CXX11
|
||||||
|
template<typename T,int N> struct get_compile_time_size<std::array<T,N> > {
|
||||||
|
enum { value = N };
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
// MakeIndexing/make_indexing turn an arbitrary object of type T into something usable by MatrixSlice
|
// MakeIndexing/make_indexing turn an arbitrary object of type T into something usable by MatrixSlice
|
||||||
template<typename T,typename EnableIf=void>
|
template<typename T,typename EnableIf=void>
|
||||||
struct MakeIndexing {
|
struct MakeIndexing {
|
||||||
@ -158,6 +183,9 @@ template<typename T>
|
|||||||
const T& make_indexing(const T& x, Index size) { return x; }
|
const T& make_indexing(const T& x, Index size) { return x; }
|
||||||
|
|
||||||
struct IntAsArray {
|
struct IntAsArray {
|
||||||
|
enum {
|
||||||
|
SizeAtCompileTime = 1
|
||||||
|
};
|
||||||
IntAsArray(Index val) : m_value(val) {}
|
IntAsArray(Index val) : m_value(val) {}
|
||||||
Index operator[](Index) const { return m_value; }
|
Index operator[](Index) const { return m_value; }
|
||||||
Index size() const { return 1; }
|
Index size() const { return 1; }
|
||||||
@ -181,25 +209,25 @@ Index symbolic2value(end_t, Index size) { return size; }
|
|||||||
Index symbolic2value(shifted_end x, Index size) { return size+x.offset; }
|
Index symbolic2value(shifted_end x, Index size) { return size+x.offset; }
|
||||||
|
|
||||||
// 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 StepType>
|
template<typename FirstType,typename LastType,typename IncrType>
|
||||||
struct MakeIndexing<Range_t<FirstType,LastType,StepType> > {
|
struct MakeIndexing<Range_t<FirstType,LastType,IncrType> > {
|
||||||
typedef Range_t<Index,Index,StepType> type;
|
typedef Range_t<Index,Index,IncrType> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FirstType,typename LastType,typename StepType>
|
template<typename FirstType,typename LastType,typename IncrType>
|
||||||
Range_t<Index,Index,StepType> make_indexing(const Range_t<FirstType,LastType,StepType>& ids, Index size) {
|
Range_t<Index,Index,IncrType> make_indexing(const Range_t<FirstType,LastType,IncrType>& ids, Index size) {
|
||||||
return Range_t<Index,Index,StepType>(symbolic2value(ids.m_first,size),symbolic2value(ids.m_last,size),ids.m_step);
|
return Range_t<Index,Index,IncrType>(symbolic2value(ids.m_first,size),symbolic2value(ids.m_last,size),ids.m_incr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a symbolic span into a usable one (i.e., remove last/end "keywords")
|
// Convert a symbolic span into a usable one (i.e., remove last/end "keywords")
|
||||||
template<typename FirstType,typename SizeType,typename StepType>
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
struct MakeIndexing<Span_t<FirstType,SizeType,StepType> > {
|
struct MakeIndexing<Span_t<FirstType,SizeType,IncrType> > {
|
||||||
typedef Span_t<Index,SizeType,StepType> type;
|
typedef Span_t<Index,SizeType,IncrType> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FirstType,typename SizeType,typename StepType>
|
template<typename FirstType,typename SizeType,typename IncrType>
|
||||||
Span_t<Index,SizeType,StepType> make_indexing(const Span_t<FirstType,SizeType,StepType>& ids, Index size) {
|
Span_t<Index,SizeType,IncrType> make_indexing(const Span_t<FirstType,SizeType,IncrType>& ids, Index size) {
|
||||||
return Span_t<Index,SizeType,StepType>(symbolic2value(ids.m_first,size),ids.m_size,ids.m_step);
|
return Span_t<Index,SizeType,IncrType>(symbolic2value(ids.m_first,size),ids.m_size,ids.m_incr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a symbolic 'all' into a usable range
|
// Convert a symbolic 'all' into a usable range
|
||||||
|
@ -19,8 +19,19 @@ struct traits<IndexedView<XprType, RowIndices, ColIndices> >
|
|||||||
: traits<XprType>
|
: traits<XprType>
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
|
RowsAtCompileTime = get_compile_time_size<RowIndices>::value,
|
||||||
|
ColsAtCompileTime = get_compile_time_size<ColIndices>::value,
|
||||||
|
MaxRowsAtCompileTime = RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) : int(traits<XprType>::MaxRowsAtCompileTime),
|
||||||
|
MaxColsAtCompileTime = ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) : int(traits<XprType>::MaxColsAtCompileTime),
|
||||||
|
|
||||||
|
XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
|
||||||
|
IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
|
||||||
|
: (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
||||||
|
: XprTypeIsRowMajor,
|
||||||
|
|
||||||
|
FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
|
||||||
FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
|
FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
|
||||||
Flags = traits<XprType>::Flags & (RowMajorBit | FlagsLvalueBit /*| DirectAccessBit*/),
|
Flags = (traits<XprType>::Flags & HereditaryBits) | FlagsLvalueBit | FlagsRowMajorBit,
|
||||||
//MatrixTypeInnerStride = inner_stride_at_compile_time<XprType>::ret,
|
//MatrixTypeInnerStride = inner_stride_at_compile_time<XprType>::ret,
|
||||||
InnerStrideAtCompileTime = int(Dynamic),
|
InnerStrideAtCompileTime = int(Dynamic),
|
||||||
OuterStrideAtCompileTime = int(Dynamic)
|
OuterStrideAtCompileTime = int(Dynamic)
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
|
|
||||||
typedef std::pair<Index,Index> IndexPair;
|
typedef std::pair<Index,Index> IndexPair;
|
||||||
|
|
||||||
Index encode(Index i, Index j) {
|
int encode(Index i, Index j) {
|
||||||
return i*100 + j;
|
return int(i*100 + j);
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexPair decode(Index ij) {
|
IndexPair decode(Index ij) {
|
||||||
@ -97,6 +97,17 @@ void check_indexed_view()
|
|||||||
"300 301 302 303 304 305 306 307 308 309")
|
"300 301 302 303 304 305 306 307 308 309")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Array44i B;
|
||||||
|
VERIFY( (A(span(2,5), 5)).ColsAtCompileTime == 1);
|
||||||
|
VERIFY( (A(span(2,5), 5)).RowsAtCompileTime == Dynamic);
|
||||||
|
VERIFY( (A(span(2,fix<5>), 5)).RowsAtCompileTime == 5);
|
||||||
|
VERIFY( (A(4, all)).ColsAtCompileTime == Dynamic);
|
||||||
|
VERIFY( (A(4, all)).RowsAtCompileTime == 1);
|
||||||
|
VERIFY( (B(1, all)).ColsAtCompileTime == 4);
|
||||||
|
VERIFY( (B(1, all)).RowsAtCompileTime == 1);
|
||||||
|
VERIFY( (B(all,1)).ColsAtCompileTime == 1);
|
||||||
|
VERIFY( (B(all,1)).RowsAtCompileTime == 4);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_indexed_view()
|
void test_indexed_view()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user