Implements noalias/evaluate

See merge request oss/rotgen!18
This commit is contained in:
Joel Falcou 2025-09-09 15:21:35 +02:00
parent 1f8663aad2
commit cc5ab775bc
9 changed files with 181 additions and 2 deletions

View file

@ -27,6 +27,8 @@ namespace rotgen
static constexpr int storage_order = T::storage_order;
using parent::evaluate;
using parent::noalias;
using parent::operator();
using parent::rows;
using parent::cols;
@ -99,6 +101,8 @@ namespace rotgen
static constexpr int storage_order = T::storage_order;
using parent::evaluate;
using parent::noalias;
using parent::operator();
using parent::rows;
using parent::cols;

View file

@ -117,6 +117,10 @@ namespace rotgen
return parent::operator()(i);
}
auto evaluate() const { return *this; }
decltype(auto) noalias() const { return *this; }
decltype(auto) noalias() { return *this; }
concrete_type transpose() const
{
return concrete_type(static_cast<parent const &>(*this).transpose());

View file

@ -72,6 +72,16 @@ namespace rotgen
return *this;
}
map& operator=(concepts::entity auto const& other) requires(!is_immutable)
{
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
for (rotgen::Index r = 0; r < parent::rows(); ++r)
for (rotgen::Index c = 0; c < parent::cols(); ++c)
(*this)(r, c) = other(r, c);
return *this;
}
value_type& operator()(Index i, Index j) requires(!is_immutable) { return parent::operator()(i,j); }
value_type& operator()(Index i) requires(!is_immutable)
{
@ -90,6 +100,10 @@ namespace rotgen
return parent::operator()(i);
}
auto evaluate() const { return *this; }
decltype(auto) noalias() const { return *this; }
decltype(auto) noalias() { return *this; }
concrete_type transpose() const
{
return concrete_type(static_cast<parent const &>(*this).transpose());

View file

@ -70,6 +70,23 @@ namespace rotgen
(*this)(r, c) = e(r, c);
}
matrix& operator=(concepts::entity auto const& e)
{
if constexpr(Rows != -1) assert(e.rows() == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(e.cols() == Cols && "Mismatched between dynamic and static col size");
resize(e.rows(), e.cols());
for (rotgen::Index r = 0; r < e.rows(); ++r)
for (rotgen::Index c = 0; c < e.cols(); ++c)
(*this)(r, c) = e(r, c);
return *this;
}
auto evaluate() const { return *this; }
decltype(auto) noalias() const { return *this; }
decltype(auto) noalias() { return *this; }
void resize(int new_rows, int new_cols) requires(Rows == -1 && Cols == -1)
{
parent::resize(new_rows, new_cols);

View file

@ -101,6 +101,15 @@ namespace rotgen
template<typename OtherDerived>
block(const Eigen::EigenBase<OtherDerived>& other) : parent(other) {}
block(concepts::entity auto const& other) : parent(other.base())
{}
block& operator=(concepts::entity auto const& other)
{
parent::operator=(other.base());
return *this;
}
template<typename OtherDerived>
block& operator=(const Eigen::MatrixBase<OtherDerived>& other)
{
@ -118,6 +127,23 @@ namespace rotgen
parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<const parent&>(*this); }
auto evaluate() const
{
auto res = static_cast<parent const &>(*this).eval();
return as_concrete_type<decltype(res)>(res);
}
decltype(auto) noalias() const
{
if constexpr(use_expression_templates) return base().noalias();
else return *this;
}
decltype(auto) noalias()
{
if constexpr(use_expression_templates) return base().noalias();
else return *this;
}
auto transpose() const
{

View file

@ -73,9 +73,36 @@ namespace rotgen
: map( ptr, RowsAtCompileTime, ColsAtCompileTime )
{}
map(concepts::entity auto const& other) : parent(other.base())
{}
map& operator=(concepts::entity auto const& other)
{
parent::operator=(other.base());
return *this;
}
parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<const parent&>(*this); }
auto evaluate() const
{
auto res = static_cast<parent const &>(*this).eval();
return as_concrete_type<decltype(res)>(res);
}
decltype(auto) noalias() const
{
if constexpr(use_expression_templates) return base().noalias();
else return *this;
}
decltype(auto) noalias()
{
if constexpr(use_expression_templates) return base().noalias();
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); }

View file

@ -118,10 +118,32 @@ namespace rotgen
parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<const parent&>(*this); }
auto evaluate() const
{
auto res = static_cast<parent const &>(*this).eval();
return as_concrete_type<decltype(res)>(res);
}
decltype(auto) noalias() const
{
if constexpr(use_expression_templates) return base().noalias();
else return *this;
}
decltype(auto) noalias()
{
if constexpr(use_expression_templates) return base().noalias();
else return *this;
}
auto transpose() const
{
auto res = static_cast<parent const &>(*this).transpose();
return as_concrete_type<decltype(res)>(res);
if constexpr(use_expression_templates) return base().transpose();
else
{
auto res = static_cast<parent const &>(*this).transpose();
return as_concrete_type<decltype(res)>(res);
}
}
auto conjugate() const

View file

@ -69,4 +69,22 @@ namespace rotgen
static_assert(P == 1 || P == 2 || P == Infinity);
return arg.template lpNorm<P>();
}
template<typename T>
decltype(auto) noalias(T&& t) requires( requires{std::forward<T>(t).noalias();} )
{
return std::forward<T>(t).noalias();
}
template<typename T>
auto evaluate(T&& t) requires( requires{std::forward<T>(t).evaluate();} )
{
return std::forward<T>(t).evaluate();
}
template<typename T>
auto evaluate(T&& t) requires( requires{std::forward<T>(t).eval();} )
{
return std::forward<T>(t).eval();
}
}