Clarify single index API for data access.

This commit is contained in:
Joel Falcou 2025-09-18 14:31:33 +02:00
parent a50098f761
commit d89da18709
13 changed files with 249 additions and 128 deletions

View file

@ -26,10 +26,14 @@ namespace rotgen
using rotgen_tag = void; using rotgen_tag = void;
static constexpr int storage_order = T::storage_order; static constexpr int storage_order = T::storage_order;
static constexpr int RowsAtCompileTime = T::RowsAtCompileTime;
static constexpr int ColsAtCompileTime = T::ColsAtCompileTime;
static constexpr bool IsVectorAtCompileTime = T::IsVectorAtCompileTime;
using parent::evaluate; using parent::evaluate;
using parent::noalias; using parent::noalias;
using parent::operator(); using parent::operator();
using parent::operator[];
using parent::rows; using parent::rows;
using parent::cols; using parent::cols;
using parent::size; using parent::size;
@ -100,10 +104,14 @@ namespace rotgen
using rotgen_tag = void; using rotgen_tag = void;
static constexpr int storage_order = T::storage_order; static constexpr int storage_order = T::storage_order;
static constexpr int RowsAtCompileTime = T::RowsAtCompileTime;
static constexpr int ColsAtCompileTime = T::ColsAtCompileTime;
static constexpr bool IsVectorAtCompileTime = T::IsVectorAtCompileTime;
using parent::evaluate; using parent::evaluate;
using parent::noalias; using parent::noalias;
using parent::operator(); using parent::operator();
using parent::operator[];
using parent::rows; using parent::rows;
using parent::cols; using parent::cols;
using parent::size; using parent::size;

View file

@ -38,6 +38,12 @@ namespace rotgen
inline constexpr int Aligned = default_alignment; inline constexpr int Aligned = default_alignment;
} }
namespace rotgen::detail
{
template<Index R, Index C>
inline constexpr int force_order = AutoAlign | ((R==1 && C!=1) ? RowMajor : ColMajor);
}
#if !defined(ROTGEN_MAX_SIZE) && defined(ROTGEN_ENABLE_EXPRESSION_TEMPLATES) #if !defined(ROTGEN_MAX_SIZE) && defined(ROTGEN_ENABLE_EXPRESSION_TEMPLATES)
#define ROTGEN_MAX_SIZE 0 #define ROTGEN_MAX_SIZE 0
#endif #endif

View file

@ -35,6 +35,7 @@ namespace rotgen
static constexpr int RowsAtCompileTime = Rows; static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols; static constexpr int ColsAtCompileTime = Cols;
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
static constexpr int Options = Ref::Options; static constexpr int Options = Ref::Options;
static constexpr bool IsRowMajor = (storage_order & RowMajor) == RowMajor; static constexpr bool IsRowMajor = (storage_order & RowMajor) == RowMajor;
@ -103,20 +104,30 @@ namespace rotgen
value_type& operator()(Index i, Index j) requires(!is_immutable) { return parent::operator()(i,j); } value_type& operator()(Index i, Index j) requires(!is_immutable) { return parent::operator()(i,j); }
value_type& operator()(Index i) requires(!is_immutable) value_type& operator()(Index i) requires(!is_immutable && IsVectorAtCompileTime)
{ {
assert(is_contiguous_linear()); assert(is_contiguous_linear());
return parent::operator()(i); return parent::operator()(i);
} }
value_type& operator[](Index i) requires(!is_immutable && IsVectorAtCompileTime)
{
return (*this)(i);
}
value_type operator()(Index i, Index j) const { return parent::operator()(i,j); } value_type operator()(Index i, Index j) const { return parent::operator()(i,j); }
value_type operator()(Index i) const value_type operator()(Index i) const requires(IsVectorAtCompileTime)
{ {
assert(is_contiguous_linear()); assert(is_contiguous_linear());
return parent::operator()(i); return parent::operator()(i);
} }
value_type operator[](Index i) const requires(IsVectorAtCompileTime)
{
return (*this)(i);
}
auto evaluate() const { return *this; } auto evaluate() const { return *this; }
decltype(auto) noalias() const { return *this; } decltype(auto) noalias() const { return *this; }
decltype(auto) noalias() { return *this; } decltype(auto) noalias() { return *this; }

View file

@ -37,8 +37,9 @@ namespace rotgen
using ptr_type = std::conditional_t<is_immutable, value_type const*, value_type*>; using ptr_type = std::conditional_t<is_immutable, value_type const*, value_type*>;
using stride_type = Stride; using stride_type = Stride;
static constexpr Index RowsAtCompileTime = Ref::RowsAtCompileTime; static constexpr int RowsAtCompileTime = Ref::RowsAtCompileTime;
static constexpr Index ColsAtCompileTime = Ref::ColsAtCompileTime; static constexpr int ColsAtCompileTime = Ref::ColsAtCompileTime;
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
map(ptr_type ptr, Index r, Index c, stride_type s) : parent(ptr, r, c, strides<storage_order>(s,r,c)) {} map(ptr_type ptr, Index r, Index c, stride_type s) : parent(ptr, r, c, strides<storage_order>(s,r,c)) {}
map(ptr_type ptr, Index r, Index c) map(ptr_type ptr, Index r, Index c)
@ -91,7 +92,7 @@ namespace rotgen
} }
value_type& operator()(Index i, Index j) requires(!is_immutable) { return parent::operator()(i,j); } value_type& operator()(Index i, Index j) requires(!is_immutable) { return parent::operator()(i,j); }
value_type& operator()(Index i) requires(!is_immutable) value_type& operator()(Index i) requires(!is_immutable && IsVectorAtCompileTime)
{ {
assert( parent::innerStride() == 1 assert( parent::innerStride() == 1
&& parent::outerStride() ==(storage_order == RowMajor ? parent::cols() : parent::rows()) && parent::outerStride() ==(storage_order == RowMajor ? parent::cols() : parent::rows())
@ -99,8 +100,13 @@ namespace rotgen
return parent::operator()(i); return parent::operator()(i);
} }
value_type& operator[](Index i) requires(!is_immutable && IsVectorAtCompileTime)
{
return (*this)(i);
}
value_type operator()(Index i, Index j) const { return parent::operator()(i,j); } value_type operator()(Index i, Index j) const { return parent::operator()(i,j); }
value_type operator()(Index i) const value_type operator()(Index i) const requires(IsVectorAtCompileTime)
{ {
assert( parent::innerStride() == 1 assert( parent::innerStride() == 1
&& parent::outerStride() ==(storage_order == RowMajor ? parent::cols() : parent::rows()) && parent::outerStride() ==(storage_order == RowMajor ? parent::cols() : parent::rows())
@ -108,6 +114,11 @@ namespace rotgen
return parent::operator()(i); return parent::operator()(i);
} }
value_type operator[](Index i) const requires(IsVectorAtCompileTime)
{
return (*this)(i);
}
auto evaluate() const { return *this; } auto evaluate() const { return *this; }
decltype(auto) noalias() const { return *this; } decltype(auto) noalias() const { return *this; }
decltype(auto) noalias() { return *this; } decltype(auto) noalias() { return *this; }

View file

@ -15,7 +15,7 @@ namespace rotgen
{ {
template< typename Scalar template< typename Scalar
, int Rows = Dynamic , int Cols = Dynamic , int Rows = Dynamic , int Cols = Dynamic
, int Opts = ColMajor , int Opts = detail::force_order<Rows,Cols>
, int MaxRows = Rows , int MaxCols = Cols , int MaxRows = Rows , int MaxCols = Cols
> >
class matrix : public find_matrix<Scalar,Opts> class matrix : public find_matrix<Scalar,Opts>
@ -27,8 +27,9 @@ namespace rotgen
using value_type = Scalar; using value_type = Scalar;
static constexpr auto storage_order = Opts & 1; static constexpr auto storage_order = Opts & 1;
static constexpr int RowsAtCompileTime = Rows; static constexpr Index RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols; static constexpr Index ColsAtCompileTime = Cols;
static constexpr bool IsVectorAtCompileTime = (RowsAtCompileTime == 1) || (ColsAtCompileTime == 1);
static constexpr int Options = Opts; static constexpr int Options = Opts;
static constexpr bool IsRowMajor = (Opts & RowMajor) == RowMajor; static constexpr bool IsRowMajor = (Opts & RowMajor) == RowMajor;
static constexpr bool is_defined_static = false; static constexpr bool is_defined_static = false;
@ -36,15 +37,21 @@ namespace rotgen
matrix() : parent(Rows==-1?0:Rows,Cols==-1?0:Cols) {} matrix() : parent(Rows==-1?0:Rows,Cols==-1?0:Cols) {}
matrix(int r, int c) : parent(r, c) matrix(Index r, Index c) : parent(r, c)
{ {
if constexpr(Rows != -1) assert(r == Rows && "Mismatched between dynamic and static row size"); if constexpr(Rows != -1) assert(r == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(c == Cols && "Mismatched between dynamic and static column size"); if constexpr(Cols != -1) assert(c == Cols && "Mismatched between dynamic and static column size");
} }
matrix(Index n) requires(IsVectorAtCompileTime && (Rows != 1 || Cols != 1))
: parent(Rows != -1 ? 1 : n, Cols != -1 ? 1 : n)
{}
matrix(Scalar v) requires(Rows == 1 && Cols == 1) : parent(1,1,{v}) {}
matrix(parent const& base) : parent(base) {} matrix(parent const& base) : parent(base) {}
explicit matrix(std::initializer_list<std::initializer_list<Scalar>> init) : parent(init) matrix(std::initializer_list<std::initializer_list<Scalar>> init) : parent(init)
{ {
if constexpr(Rows != -1) assert(init.size() == Rows && "Mismatched between dynamic and static row size"); if constexpr(Rows != -1) assert(init.size() == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) if constexpr(Cols != -1)
@ -55,10 +62,8 @@ namespace rotgen
} }
} }
template<std::convertible_to<Scalar>... S> matrix(std::initializer_list<Scalar> init)
explicit matrix(Scalar s0,S... init) requires(IsVectorAtCompileTime) : parent(Rows, Cols, init)
requires((Rows == 1 && Cols == (1+sizeof...(S))) || (Cols == 1 && Rows == (1+sizeof...(S))))
: parent(Rows, Cols, {s0,static_cast<Scalar>(init)...})
{} {}
matrix(concepts::entity auto const& e) : parent(e.rows(),e.cols()) matrix(concepts::entity auto const& e) : parent(e.rows(),e.cols())
@ -83,6 +88,16 @@ namespace rotgen
return *this; return *this;
} }
value_type& operator[](Index i) requires(IsVectorAtCompileTime)
{
return (*this)(i);
}
value_type operator[](Index i) const requires(IsVectorAtCompileTime)
{
return (*this)(i);
}
auto evaluate() const { return *this; } auto evaluate() const { return *this; }
decltype(auto) noalias() const { return *this; } decltype(auto) noalias() const { return *this; }
decltype(auto) noalias() { return *this; } decltype(auto) noalias() { return *this; }

View file

@ -61,6 +61,7 @@ namespace rotgen
static constexpr int Options = Ref::Options; static constexpr int Options = Ref::Options;
static constexpr int RowsAtCompileTime = Rows; static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols; static constexpr int ColsAtCompileTime = Cols;
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
static constexpr bool is_defined_static = Rows!=-1 && Cols!=-1; static constexpr bool is_defined_static = Rows!=-1 && Cols!=-1;
static constexpr bool has_static_storage = storage_status<Rows,Cols,Rows,Cols>; static constexpr bool has_static_storage = storage_status<Rows,Cols,Rows,Cols>;
@ -91,7 +92,7 @@ namespace rotgen
: parent(r.base(),i0,j0,Rows,Cols) : parent(r.base(),i0,j0,Rows,Cols)
{} {}
template<typename B, int R, int C, bool I, int FS> template<typename B, Index R, Index C, bool I, int FS>
block(block<B,R,C,I,FS> const& other) : parent(other.base()) block(block<B,R,C,I,FS> const& other) : parent(other.base())
{} {}
@ -317,28 +318,24 @@ namespace rotgen
return parent::template lpNorm<P>(); return parent::template lpNorm<P>();
} }
bool is_contiguous_linear() const value_type& operator()(Index i, Index j) requires(!is_immutable)
{ {
if(parent::innerStride() != 1) return false; return base()(i,j);
// outerstride must equal the “innerdimension length” }
if constexpr(storage_order) return parent::outerStride() == parent::cols();
else return parent::outerStride() == parent::rows(); value_type& operator()(Index i) requires(!is_immutable && IsVectorAtCompileTime)
{
return base().data()[i];
}
value_type& operator[](Index i) requires(!is_immutable && IsVectorAtCompileTime)
{
return (*this)(i);
} }
value_type& operator()(Index i, Index j) requires(!is_immutable) { return base()(i,j); }
value_type operator()(Index i, Index j) const { return base()(i,j); } value_type operator()(Index i, Index j) const { return base()(i,j); }
value_type operator()(Index i) const requires(IsVectorAtCompileTime) { return base().data()[i]; }
value_type& operator()(Index i) requires(!is_immutable) value_type operator[](Index i) const requires(IsVectorAtCompileTime) { return (*this)(i); }
{
assert(is_contiguous_linear());
return base().data()[i];
}
value_type operator()(Index i) const
{
assert(is_contiguous_linear());
return base().data()[i];
}
using parent::innerStride; using parent::innerStride;
using parent::outerStride; using parent::outerStride;

View file

@ -42,6 +42,7 @@ namespace rotgen
static constexpr auto Flags = Ref::Flags; static constexpr auto Flags = Ref::Flags;
static constexpr Index RowsAtCompileTime = Ref::RowsAtCompileTime; static constexpr Index RowsAtCompileTime = Ref::RowsAtCompileTime;
static constexpr Index ColsAtCompileTime = Ref::ColsAtCompileTime; static constexpr Index ColsAtCompileTime = Ref::ColsAtCompileTime;
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
static constexpr bool has_static_storage = Ref::has_static_storage; static constexpr bool has_static_storage = Ref::has_static_storage;
static constexpr int storage_order = Ref::storage_order; static constexpr int storage_order = Ref::storage_order;
static constexpr bool is_immutable = std::is_const_v<Ref>; static constexpr bool is_immutable = std::is_const_v<Ref>;
@ -111,20 +112,24 @@ namespace rotgen
else return *this; else return *this;
} }
value_type& operator()(Index i, Index j) { return base()(i, j); } value_type& operator()(Index i, Index j) requires(!is_immutable)
{
return base()(i,j);
}
value_type& operator()(Index i) requires(!is_immutable && IsVectorAtCompileTime)
{
return base().data()[i];
}
value_type& operator[](Index i) requires(!is_immutable && IsVectorAtCompileTime)
{
return (*this)(i);
}
value_type operator()(Index i, Index j) const { return base()(i,j); } value_type operator()(Index i, Index j) const { return base()(i,j); }
value_type operator()(Index i) const requires(IsVectorAtCompileTime) { return base().data()[i]; }
value_type& operator()(Index i) requires(!is_immutable) value_type operator[](Index i) const requires(IsVectorAtCompileTime) { return (*this)(i); }
{
assert(is_contiguous_linear());
return base().data()[i];
}
value_type operator()(Index i) const
{
assert(is_contiguous_linear());
return base().data()[i];
}
map& operator+=(map const& rhs) map& operator+=(map const& rhs)
{ {
@ -253,13 +258,6 @@ namespace rotgen
return *this; return *this;
} }
bool is_contiguous_linear() const
{
if(base().innerStride() != 1) return false;
if constexpr(storage_order == rotgen::RowMajor) return base().outerStride() == base().cols();
else return base().outerStride() == base().rows();
}
using parent::innerStride; using parent::innerStride;
using parent::outerStride; using parent::outerStride;
using parent::rows; using parent::rows;

View file

@ -23,7 +23,7 @@ namespace rotgen
template< typename Scalar template< typename Scalar
, int Rows = Dynamic , int Cols = Dynamic , int Rows = Dynamic , int Cols = Dynamic
, int Opts = ColMajor , int Opts = detail::force_order<Rows,Cols>
, int MaxRows = Rows, int MaxCols = Cols , int MaxRows = Rows, int MaxCols = Cols
> >
class matrix : private detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols> class matrix : private detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>
@ -41,6 +41,7 @@ namespace rotgen
static constexpr auto Flags = parent::Flags; static constexpr auto Flags = parent::Flags;
static constexpr int RowsAtCompileTime = Rows; static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols; static constexpr int ColsAtCompileTime = Cols;
static constexpr bool IsVectorAtCompileTime = (RowsAtCompileTime == 1) || (ColsAtCompileTime == 1);
static constexpr int Options = parent::Options; static constexpr int Options = parent::Options;
static constexpr bool IsRowMajor = parent::IsRowMajor; static constexpr bool IsRowMajor = parent::IsRowMajor;
@ -64,25 +65,34 @@ namespace rotgen
matrix(std::initializer_list<std::initializer_list<Scalar>> init) : parent(init) matrix(std::initializer_list<std::initializer_list<Scalar>> init) : parent(init)
{} {}
template<std::convertible_to<Scalar>... S> matrix(Index n) requires(IsVectorAtCompileTime && (Rows != 1 || Cols != 1))
requires((Rows == 1 && Cols == (1+sizeof...(S))) || (Cols == 1 && Rows == (1+sizeof...(S)))) : matrix(Rows != -1 ? 1 : n, Cols != -1 ? 1 : n)
matrix(Scalar s0,S... init) {}
matrix(Scalar v) requires(Rows == 1 && Cols == 1) : parent
( [&]()
{
if constexpr(has_static_storage) return parent(v);
else return parent{1,1};
}()
)
{
if constexpr(!has_static_storage) (*this)(0) = v;
}
explicit matrix(std::initializer_list<Scalar> init)
requires(IsVectorAtCompileTime)
: parent( [&]() : parent( [&]()
{ {
if constexpr(has_static_storage) if constexpr(has_static_storage) return parent{};
return parent{static_cast<Scalar>(s0),static_cast<Scalar>(init)...};
else return parent{Rows,Cols}; else return parent{Rows,Cols};
}() }()
) )
{ {
if constexpr(!has_static_storage) auto first = init.begin();
{
auto raw = {static_cast<Scalar>(s0),static_cast<Scalar>(init)...};
auto first = raw.begin();
for(rotgen::Index i=0; i < parent::size(); i++) for(rotgen::Index i=0; i < parent::size(); i++)
(*this)(i) = first[i]; (*this)(i) = first[i];
} }
}
matrix(concepts::entity auto const& other) : parent(other.base()) matrix(concepts::entity auto const& other) : parent(other.base())
{} {}
@ -262,6 +272,16 @@ namespace rotgen
return parent::template lpNorm<P>(); return parent::template lpNorm<P>();
} }
value_type& operator[](Index i) requires(IsVectorAtCompileTime)
{
return (*this)(i);
}
value_type operator[](Index i) const requires(IsVectorAtCompileTime)
{
return (*this)(i);
}
using parent::operator(); using parent::operator();
using parent::rows; using parent::rows;
using parent::cols; using parent::cols;

View file

@ -14,7 +14,8 @@
class ROTGEN_EXPORT CLASSNAME class ROTGEN_EXPORT CLASSNAME
{ {
public: public:
CLASSNAME(std::size_t rows = 0, std::size_t cols = 0); CLASSNAME();
CLASSNAME(std::size_t rows, std::size_t cols);
CLASSNAME(std::size_t rows, std::size_t cols,std::initializer_list<TYPE> init); CLASSNAME(std::size_t rows, std::size_t cols,std::initializer_list<TYPE> init);
CLASSNAME(std::initializer_list<std::initializer_list<TYPE>> init); CLASSNAME(std::initializer_list<std::initializer_list<TYPE>> init);

View file

@ -15,6 +15,7 @@
//================================================================================================== //==================================================================================================
// Constructors & Special Members // Constructors & Special Members
//================================================================================================== //==================================================================================================
CLASSNAME::CLASSNAME() : storage_(std::make_unique<payload>(0,0)) {}
CLASSNAME::CLASSNAME(std::size_t r, std::size_t c) : storage_(std::make_unique<payload>(r,c)) {} CLASSNAME::CLASSNAME(std::size_t r, std::size_t c) : storage_(std::make_unique<payload>(r,c)) {}
CLASSNAME::CLASSNAME(std::initializer_list<std::initializer_list<TYPE>> init) CLASSNAME::CLASSNAME(std::initializer_list<std::initializer_list<TYPE>> init)

View file

@ -85,20 +85,45 @@ TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types) TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> ) <typename T, typename O>( tts::type< tts::types<T,O>> )
{ {
using base = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>; auto vs = [&]()
{
if constexpr(O::value == rotgen::ColMajor)
{
using base = rotgen::matrix<T,1,rotgen::Dynamic>;
base m(12);
for(int k=0;k<12;++k) m(k) = k+1;
return std::tuple{m,rotgen::block<base,1,rotgen::Dynamic>(m, 0, 0, 1, 12)};
}
else
{
using base = rotgen::matrix<T,rotgen::Dynamic,1>;
base m(12);
for(int k=0;k<12;++k) m(k) = k+1;
return std::tuple{m,rotgen::block<base,rotgen::Dynamic,1>(m, 0, 0, 12, 1)};
}
}();
T data[] = {1,2,3,4,5,6,7,8,9,10,11,12}; auto mat = get<0>(vs);
base mat(4,3); auto b = get<1>(vs);
for(int k=0;k<12;++k) mat.data()[k] = data[k]; TTS_EXPECT(b.IsVectorAtCompileTime);
auto b = rotgen::block<base,rotgen::Dynamic,rotgen::Dynamic>(mat, 0, 0, 4, 3);
for(rotgen::Index i=0;i<b.size();i++) for(rotgen::Index i=0;i<b.size();i++)
TTS_EQUAL(b(i), data[i]) << "Index: " << i << "\n"; TTS_EQUAL(b(i), mat(i)) << "Index: " << i << "\n";
for(rotgen::Index i=0;i<b.size();i++)
TTS_EQUAL(b[i], mat(i)) << "Index: " << i << "\n";
b(1) = 42; b(1) = 42;
TTS_EQUAL(mat.data()[1], 42); TTS_EQUAL(mat(1), 42);
T& ref = b(2); T& ref = b(2);
ref = 17; ref = 17;
TTS_EQUAL(mat.data()[2], 17); TTS_EQUAL(mat(2), 17);
b[1] = 77;
TTS_EQUAL(mat(1), 77);
T& bref = b[3];
bref = 331;
TTS_EQUAL(mat(3), 331);
}; };

View file

@ -66,18 +66,43 @@ TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types) TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> ) <typename T, typename O>( tts::type< tts::types<T,O>> )
{ {
using base = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>;
T data[] = {1,2,3,4,5,6,7,8,9,10,11,12}; T data[] = {1,2,3,4,5,6,7,8,9,10,11,12};
rotgen::map<base> a(data,4,3); auto m = [&]()
for(rotgen::Index i=0;i<a.size();i++) {
TTS_EQUAL(a(i), data[i]) << "Index: " << i << "\n"; if constexpr(O::value == rotgen::ColMajor)
{
using base = rotgen::matrix<T,1,rotgen::Dynamic>;
rotgen::map<base> a(data,12);
return a;
}
else
{
using base = rotgen::matrix<T,rotgen::Dynamic,1>;
rotgen::map<base> a(data,12);
return a;
}
}();
a(1) = 42; TTS_EXPECT(m.IsVectorAtCompileTime);
for(rotgen::Index i=0;i<m.size();i++)
TTS_EQUAL(m(i), data[i]) << "Index: " << i << "\n";
for(rotgen::Index i=0;i<m.size();i++)
TTS_EQUAL(m[i], data[i]) << "Index: " << i << "\n";
m(1) = 42;
TTS_EQUAL(data[1], 42); TTS_EQUAL(data[1], 42);
T& ref = a(2); T& ref = m(2);
ref = 17; ref = 17;
TTS_EQUAL(data[2], 17); TTS_EQUAL(data[2], 17);
m[1] = 77;
TTS_EQUAL(data[1], 77);
T& bref = m[3];
bref = 331;
TTS_EQUAL(data[3], 331);
}; };

View file

@ -138,27 +138,30 @@ TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types) TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> ) <typename T, typename O>( tts::type< tts::types<T,O>> )
{ {
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> a(2, 4); auto a = [&]()
{
if constexpr(O::value == rotgen::ColMajor) return rotgen::matrix<T,1,rotgen::Dynamic>(1,8);
else return rotgen::matrix<T,rotgen::Dynamic,1>(8,1);
}();
TTS_EXPECT(a.IsVectorAtCompileTime);
for(rotgen::Index s=0;s<a.size();++s)
a(s) = s+1;
int i = 1; int i = 1;
if constexpr(!O::value) for(rotgen::Index s=0;s<a.size();++s)
{ TTS_EQUAL(a(s), i++) << a;
for(rotgen::Index c=0;c<a.cols();++c)
for(rotgen::Index r=0;r<a.rows();++r)
a(r, c) = i++;
}
else
{
for(rotgen::Index r=0;r<a.rows();++r)
for(rotgen::Index c=0;c<a.cols();++c)
a(r, c) = i++;
}
i = 1; i = 1;
for(rotgen::Index r=0;r<a.rows()*a.cols();++r) for(rotgen::Index s=0;s<a.size();++s)
TTS_EQUAL(a(r), i++) << a; TTS_EQUAL(a[s], i++) << a;
T& ref = a(2); T& ref = a(2);
ref = 999.5; ref = 999.5;
TTS_EQUAL(a(2), 999.5); TTS_EQUAL(a(2), 999.5);
T& bref = a[3];
bref = 42.5;
TTS_EQUAL(a[3], 42.5);
}; };