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

@ -25,11 +25,15 @@ namespace rotgen
using value_type = typename T::value_type;
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::noalias;
using parent::operator();
using parent::operator[];
using parent::rows;
using parent::cols;
using parent::size;
@ -99,11 +103,15 @@ namespace rotgen
using value_type = typename T::value_type;
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::noalias;
using parent::operator();
using parent::operator[];
using parent::rows;
using parent::cols;
using parent::size;

View file

@ -38,6 +38,12 @@ namespace rotgen
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)
#define ROTGEN_MAX_SIZE 0
#endif

View file

@ -33,10 +33,11 @@ namespace rotgen
using concrete_type = matrix<value_type,Rows,Cols,storage_order>;
using concrete_dynamic_type = matrix<value_type,Dynamic,Dynamic,storage_order>;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
static constexpr int Options = Ref::Options;
static constexpr bool IsRowMajor = (storage_order & RowMajor) == RowMajor;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
static constexpr int Options = Ref::Options;
static constexpr bool IsRowMajor = (storage_order & RowMajor) == RowMajor;
static constexpr bool is_defined_static = false;
static constexpr bool has_static_storage = false;
@ -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) requires(!is_immutable)
value_type& operator()(Index i) requires(!is_immutable && IsVectorAtCompileTime)
{
assert(is_contiguous_linear());
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) const
value_type operator()(Index i) const requires(IsVectorAtCompileTime)
{
assert(is_contiguous_linear());
return parent::operator()(i);
}
value_type operator[](Index i) const requires(IsVectorAtCompileTime)
{
return (*this)(i);
}
auto evaluate() const { return *this; }
decltype(auto) noalias() const { 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 stride_type = Stride;
static constexpr Index RowsAtCompileTime = Ref::RowsAtCompileTime;
static constexpr Index ColsAtCompileTime = Ref::ColsAtCompileTime;
static constexpr int RowsAtCompileTime = Ref::RowsAtCompileTime;
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)
@ -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) requires(!is_immutable)
value_type& operator()(Index i) requires(!is_immutable && IsVectorAtCompileTime)
{
assert( parent::innerStride() == 1
&& parent::outerStride() ==(storage_order == RowMajor ? parent::cols() : parent::rows())
@ -99,8 +100,13 @@ namespace rotgen
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) const
value_type operator()(Index i) const requires(IsVectorAtCompileTime)
{
assert( parent::innerStride() == 1
&& parent::outerStride() ==(storage_order == RowMajor ? parent::cols() : parent::rows())
@ -108,6 +114,11 @@ namespace rotgen
return parent::operator()(i);
}
value_type operator[](Index i) const requires(IsVectorAtCompileTime)
{
return (*this)(i);
}
auto evaluate() const { return *this; }
decltype(auto) noalias() const { return *this; }
decltype(auto) noalias() { return *this; }

View file

@ -15,7 +15,7 @@ namespace rotgen
{
template< typename Scalar
, int Rows = Dynamic , int Cols = Dynamic
, int Opts = ColMajor
, int Opts = detail::force_order<Rows,Cols>
, int MaxRows = Rows , int MaxCols = Cols
>
class matrix : public find_matrix<Scalar,Opts>
@ -26,25 +26,32 @@ namespace rotgen
using concrete_type = matrix;
using value_type = Scalar;
static constexpr auto storage_order = Opts & 1;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
static constexpr int Options = Opts;
static constexpr bool IsRowMajor = (Opts & RowMajor) == RowMajor;
static constexpr bool is_defined_static = false;
static constexpr bool has_static_storage = false;
static constexpr auto storage_order = Opts & 1;
static constexpr Index RowsAtCompileTime = Rows;
static constexpr Index ColsAtCompileTime = Cols;
static constexpr bool IsVectorAtCompileTime = (RowsAtCompileTime == 1) || (ColsAtCompileTime == 1);
static constexpr int Options = Opts;
static constexpr bool IsRowMajor = (Opts & RowMajor) == RowMajor;
static constexpr bool is_defined_static = false;
static constexpr bool has_static_storage = false;
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(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) {}
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(Cols != -1)
@ -55,10 +62,8 @@ namespace rotgen
}
}
template<std::convertible_to<Scalar>... S>
explicit matrix(Scalar s0,S... init)
requires((Rows == 1 && Cols == (1+sizeof...(S))) || (Cols == 1 && Rows == (1+sizeof...(S))))
: parent(Rows, Cols, {s0,static_cast<Scalar>(init)...})
matrix(std::initializer_list<Scalar> init)
requires(IsVectorAtCompileTime) : parent(Rows, Cols, init)
{}
matrix(concepts::entity auto const& e) : parent(e.rows(),e.cols())
@ -83,6 +88,16 @@ namespace rotgen
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; }
decltype(auto) noalias() const { return *this; }
decltype(auto) noalias() { return *this; }

View file

@ -57,12 +57,13 @@ namespace rotgen
template<typename ET>
using as_concrete_type = as_concrete_t<ET, matrix>;
static constexpr auto Flags = Ref::Flags;
static constexpr int Options = Ref::Options;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
static constexpr bool is_defined_static = Rows!=-1 && Cols!=-1;
static constexpr bool has_static_storage = storage_status<Rows,Cols,Rows,Cols>;
static constexpr auto Flags = Ref::Flags;
static constexpr int Options = Ref::Options;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
static constexpr bool is_defined_static = Rows!=-1 && Cols!=-1;
static constexpr bool has_static_storage = storage_status<Rows,Cols,Rows,Cols>;
public:
@ -91,7 +92,7 @@ namespace rotgen
: 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())
{}
@ -317,29 +318,25 @@ namespace rotgen
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;
// outerstride must equal the “innerdimension length”
if constexpr(storage_order) return parent::outerStride() == parent::cols();
else return parent::outerStride() == parent::rows();
return base()(i,j);
}
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) requires(!is_immutable)
value_type& operator()(Index i) requires(!is_immutable && IsVectorAtCompileTime)
{
assert(is_contiguous_linear());
return base().data()[i];
}
value_type operator()(Index i) const
value_type& operator[](Index i) requires(!is_immutable && IsVectorAtCompileTime)
{
assert(is_contiguous_linear());
return base().data()[i];
return (*this)(i);
}
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) const requires(IsVectorAtCompileTime) { return (*this)(i); }
using parent::innerStride;
using parent::outerStride;
using parent::rows;

View file

@ -39,13 +39,14 @@ namespace rotgen
using value_type = typename std::remove_const_t<Ref>::value_type;
using concrete_type = typename std::remove_const_t<Ref>::concrete_type;
static constexpr auto Flags = Ref::Flags;
static constexpr Index RowsAtCompileTime = Ref::RowsAtCompileTime;
static constexpr Index ColsAtCompileTime = Ref::ColsAtCompileTime;
static constexpr bool has_static_storage = Ref::has_static_storage;
static constexpr int storage_order = Ref::storage_order;
static constexpr bool is_immutable = std::is_const_v<Ref>;
static constexpr bool is_defined_static = Ref::is_defined_static;
static constexpr auto Flags = Ref::Flags;
static constexpr Index RowsAtCompileTime = Ref::RowsAtCompileTime;
static constexpr Index ColsAtCompileTime = Ref::ColsAtCompileTime;
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
static constexpr bool has_static_storage = Ref::has_static_storage;
static constexpr int storage_order = Ref::storage_order;
static constexpr bool is_immutable = std::is_const_v<Ref>;
static constexpr bool is_defined_static = Ref::is_defined_static;
template<typename ET>
using as_concrete_type = as_concrete_t<ET, matrix>;
@ -111,21 +112,25 @@ namespace rotgen
else return *this;
}
value_type& operator()(Index i, Index j) { return base()(i, j); }
value_type operator()(Index i, Index j) const { return base()(i, j); }
value_type& operator()(Index i) requires(!is_immutable)
value_type& operator()(Index i, Index j) requires(!is_immutable)
{
return base()(i,j);
}
value_type& operator()(Index i) requires(!is_immutable && IsVectorAtCompileTime)
{
assert(is_contiguous_linear());
return base().data()[i];
}
value_type operator()(Index i) const
value_type& operator[](Index i) requires(!is_immutable && IsVectorAtCompileTime)
{
assert(is_contiguous_linear());
return base().data()[i];
return (*this)(i);
}
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) const requires(IsVectorAtCompileTime) { return (*this)(i); }
map& operator+=(map const& rhs)
{
base() += rhs.base();
@ -253,13 +258,6 @@ namespace rotgen
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::outerStride;
using parent::rows;

View file

@ -14,7 +14,7 @@ namespace rotgen
{
namespace detail
{
template<typename Scalar, int Rows, int Cols, int Opts,int MaxRows, int MaxCols>
template<typename Scalar, int Rows, int Cols, int Opts, int MaxRows, int MaxCols>
using storage_type = std::conditional_t < storage_status<Rows,Cols,MaxRows,MaxCols>
, Eigen::Matrix<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>
, Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Opts>
@ -22,9 +22,9 @@ namespace rotgen
}
template< typename Scalar
, int Rows = Dynamic , int Cols = Dynamic
, int Opts = ColMajor
, int MaxRows = Rows , int MaxCols = Cols
, int Rows = Dynamic , int Cols = Dynamic
, int Opts = detail::force_order<Rows,Cols>
, int MaxRows = Rows, int MaxCols = Cols
>
class matrix : private detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>
{
@ -38,17 +38,18 @@ namespace rotgen
using concrete_type = matrix;
using concrete_dynamic_type = matrix<value_type>;
static constexpr auto Flags = parent::Flags;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
static constexpr int Options = parent::Options;
static constexpr bool IsRowMajor = parent::IsRowMajor;
static constexpr auto Flags = parent::Flags;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
static constexpr bool IsVectorAtCompileTime = (RowsAtCompileTime == 1) || (ColsAtCompileTime == 1);
static constexpr int Options = parent::Options;
static constexpr bool IsRowMajor = parent::IsRowMajor;
template<typename ET>
using as_concrete_type = as_concrete_t<ET, matrix>;
static constexpr bool is_defined_static = Rows!=-1 && Cols!=-1;
static constexpr bool has_static_storage = storage_status<Rows,Cols,MaxRows,MaxCols>;
static constexpr bool is_defined_static = Rows!=-1 && Cols!=-1;
static constexpr bool has_static_storage = storage_status<Rows,Cols,MaxRows,MaxCols>;
public:
@ -64,24 +65,33 @@ namespace rotgen
matrix(std::initializer_list<std::initializer_list<Scalar>> init) : parent(init)
{}
template<std::convertible_to<Scalar>... S>
requires((Rows == 1 && Cols == (1+sizeof...(S))) || (Cols == 1 && Rows == (1+sizeof...(S))))
matrix(Scalar s0,S... init)
: parent ( [&]()
{
if constexpr(has_static_storage)
return parent{static_cast<Scalar>(s0),static_cast<Scalar>(init)...};
else return parent{Rows,Cols};
}()
)
{
if constexpr(!has_static_storage)
matrix(Index n) requires(IsVectorAtCompileTime && (Rows != 1 || Cols != 1))
: matrix(Rows != -1 ? 1 : n, Cols != -1 ? 1 : n)
{}
matrix(Scalar v) requires(Rows == 1 && Cols == 1) : parent
( [&]()
{
auto raw = {static_cast<Scalar>(s0),static_cast<Scalar>(init)...};
auto first = raw.begin();
for(rotgen::Index i=0; i < parent::size(); i++)
(*this)(i) = first[i];
}
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( [&]()
{
if constexpr(has_static_storage) return parent{};
else return parent{Rows,Cols};
}()
)
{
auto first = init.begin();
for(rotgen::Index i=0; i < parent::size(); i++)
(*this)(i) = first[i];
}
matrix(concepts::entity auto const& other) : parent(other.base())
@ -262,6 +272,16 @@ namespace rotgen
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::rows;
using parent::cols;

View file

@ -14,7 +14,8 @@
class ROTGEN_EXPORT CLASSNAME
{
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::initializer_list<std::initializer_list<TYPE>> init);