rotgen/include/rotgen/dynamic/map.hpp
2025-09-02 19:52:22 +02:00

282 lines
No EOL
8.4 KiB
C++

//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <rotgen/concepts.hpp>
#include <rotgen/impl/map.hpp>
#include <cassert>
namespace rotgen
{
template<typename Ref, int Options = Unaligned, typename Stride = rotgen::stride>
class map : public find_map<Ref>
{
public:
static_assert ( concepts::entity<Ref>
, "[ROTGEN][CRITICAL] - Map of non-rotgen type instanciated"
);
using parent = find_map<Ref>;
using rotgen_tag = void;
using value_type = typename std::remove_const_t<Ref>::value_type;
using concrete_type = typename std::remove_const_t<Ref>::concrete_type;
static constexpr bool IsRowMajor = Ref::IsRowMajor;
static constexpr int storage_order = Ref::storage_order;
static constexpr bool has_static_storage = false;
static constexpr bool is_immutable = std::is_const_v<Ref>;
static constexpr bool is_defined_static = false;
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;
map(ptr_type ptr, Index r, Index c, stride_type s) : parent(ptr, r, c, strides<storage_order>(s)) {}
map(ptr_type ptr, Index r, Index c) : parent(ptr, r, c, strides<storage_order>(r,c)) {}
map(ptr_type ptr, stride_type s) requires(RowsAtCompileTime!=-1 && ColsAtCompileTime!=-1)
: parent(ptr,RowsAtCompileTime,ColsAtCompileTime, strides<storage_order>(s))
{}
map(ptr_type ptr, Index size) requires(RowsAtCompileTime==1 || ColsAtCompileTime==1)
: map( ptr, RowsAtCompileTime==1?1:size, ColsAtCompileTime==1?1:size)
{}
map(ptr_type ptr) requires(RowsAtCompileTime!=-1 && ColsAtCompileTime!=-1)
: map( ptr, RowsAtCompileTime, ColsAtCompileTime )
{}
template<typename R2, int O2, typename S2>
map(map<R2,O2,S2> const& other) : map ( other.data(), other.rows(), other.cols()
, stride{other.outerStride(),other.innerStride()}
)
{}
map(parent const& base) : parent(base) {}
map(map const& other) : parent(other)
{}
map& operator=(map const& other) requires(!is_immutable)
{
base() = static_cast<parent const &>(*other);
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)
{
assert( parent::innerStride() == 1
&& parent::outerStride() ==(storage_order == RowMajor ? parent::cols() : parent::rows())
);
return parent::operator()(i);
}
value_type operator()(Index i, Index j) const { return parent::operator()(i,j); }
value_type operator()(Index i) const
{
assert( parent::innerStride() == 1
&& parent::outerStride() ==(storage_order == RowMajor ? parent::cols() : parent::rows())
);
return parent::operator()(i);
}
concrete_type transpose() const
{
return concrete_type(static_cast<parent const &>(*this).transpose());
}
concrete_type conjugate() const
{
return concrete_type(static_cast<parent const &>(*this).conjugate());
}
concrete_type adjoint() const
{
return concrete_type(static_cast<parent const &>(*this).adjoint());
}
void transposeInPlace() requires(!is_immutable) { parent::transposeInPlace(); }
void adjointInPlace() requires(!is_immutable) { parent::adjointInPlace(); }
map& operator+=(map const& rhs) requires(!is_immutable)
{
base() += static_cast<parent const&>(rhs);
return *this;
}
map& operator-=(map const& rhs) requires(!is_immutable)
{
base() -= static_cast<parent const&>(rhs);
return *this;
}
concrete_type operator-() const
{
return concrete_type(base().operator-());
}
map& operator*=(map const& rhs) requires(!is_immutable)
{
base() *= static_cast<parent const&>(rhs);
return *this;
}
map& operator*=(value_type rhs) requires(!is_immutable)
{
base() *= rhs;
return *this;
}
map& operator/=(value_type rhs) requires(!is_immutable)
{
base() /= rhs;
return *this;
}
static auto Zero() requires( requires {Ref::Zero();} )
{
return Ref::Zero();
}
static auto Zero(int rows, int cols)
{
return Ref::Zero(rows,cols);
}
static auto Constant(value_type value) requires( requires {Ref::Constant(value);} )
{
return Ref::Constant(value);
}
static auto Constant(int rows, int cols, value_type value)
{
return Ref::Constant(rows, cols, value);
}
static auto Random() requires( requires {Ref::Random();} )
{
return Ref::Random();
}
static auto Random(int rows, int cols)
{
return Ref::Random(rows, cols);
}
static auto Identity() requires( requires {Ref::Identity();} )
{
return Ref::Identity();
}
static auto Identity(int rows, int cols)
{
return Ref::Identity(rows, cols);
}
map& setZero() requires(!is_immutable)
{
parent::setZero();
return *this;
}
map& setOnes() requires(!is_immutable)
{
parent::setOnes();
return *this;
}
map& setIdentity() requires(!is_immutable)
{
parent::setIdentity();
return *this;
}
map& setRandom() requires(!is_immutable)
{
parent::setRandom();
return *this;
}
map& setConstant(value_type s) requires(!is_immutable)
{
parent::setConstant(s);
return *this;
}
template<int P>
double lpNorm() const
{
assert(P == 1 || P == 2 || P == Infinity);
return parent::lpNorm(P);
}
parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<parent const&>(*this); }
};
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
typename map<R1,O1,S1>::concrete_type operator+(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
{
using concrete_type = typename map<R1,O1,S1>::concrete_type;
return concrete_type(lhs.base().add(map<R1,O1,S1>(rhs)));
}
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
typename map<R1,O1,S1>::concrete_type operator-(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
{
using concrete_type = typename map<R1,O1,S1>::concrete_type;
return concrete_type(lhs.base().sub(map<R1,O1,S1>(rhs)));
}
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
typename map<R1,O1,S1>::concrete_type operator*(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
{
using concrete_type = typename map<R1,O1,S1>::concrete_type;
return concrete_type(lhs.base().mul(map<R1,O1,S1>(rhs)));
}
template<typename R, int O, typename S>
typename map<R,O,S>::concrete_type
operator*(map<R,O,S> const& lhs, std::convertible_to<typename R::value_type> auto s)
{
using concrete_type = typename map<R,O,S>::concrete_type;
return concrete_type(lhs.base().mul(s));
}
template<typename R, int O, typename S>
typename map<R,O,S>::concrete_type
operator*(std::convertible_to<typename R::value_type> auto s, map<R,O,S> const& rhs)
{
using concrete_type = typename map<R,O,S>::concrete_type;
return concrete_type(rhs.base().mul(s));
}
template<typename R, int O, typename S>
typename map<R,O,S>::concrete_type
operator/(map<R,O,S> const& lhs, std::convertible_to<typename R::value_type> auto s)
{
using concrete_type = typename map<R,O,S>::concrete_type;
return concrete_type(lhs.base().div(s));
}
template<typename R1, int O1, typename S1, typename R2, int O2, typename S2>
bool operator==(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
{
return lhs.base() == rhs.base();
}
template<typename R1, int O1, typename S1, typename R2, int O2, typename S2>
bool operator!=(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
{
return lhs.base() != rhs.base();
}
}