smooth
A C++ library for Lie theory
Loading...
Searching...
No Matches
any.hpp
1// Copyright (C) 2023 Petter Nilsson. MIT License.
2
3#pragma once
4
5#include <memory>
6#include <utility>
7
9
10SMOOTH_BEGIN_NAMESPACE
11
16{
17public:
19 AnyManifold() { throw std::runtime_error("Can not default-construct"); }
20
22 template<typename M>
23 explicit AnyManifold(const M & m) : m_val(std::make_unique<wrapper<std::decay_t<M>>>(m))
24 {}
25
27 AnyManifold(const AnyManifold & m) : m_val(m.m_val->clone()) {}
28
30 AnyManifold(AnyManifold && m) : m_val(std::move(m.m_val)) {}
31
34 {
35 m_val = m.m_val->clone();
36 return *this;
37 }
38
41 {
42 m_val = std::move(m.m_val);
43 return *this;
44 }
45
47 template<Manifold M>
48 M & get()
49 {
50 return static_cast<wrapper<M> *>(m_val.get())->get();
51 }
52
54 template<Manifold M>
55 const M & get() const
56 {
57 return static_cast<const wrapper<M> *>(m_val.get())->get();
58 }
59
61 Eigen::Index dof() const { return m_val->dof(); }
62
64 AnyManifold rplus(Eigen::Ref<const Eigen::VectorXd> a) const { return AnyManifold(m_val->rplus(a)); }
65
67 Eigen::VectorXd rminus(const AnyManifold & m2) const { return m_val->rminus(m2.m_val); }
68
69private:
70 class wrapper_base
71 {
72 public:
73 virtual ~wrapper_base() = default;
74 virtual Eigen::Index dof() const = 0;
75 virtual std::unique_ptr<wrapper_base> rplus(Eigen::Ref<const Eigen::VectorXd>) const = 0;
76 virtual Eigen::VectorXd rminus(const std::unique_ptr<wrapper_base> & o) const = 0;
77 virtual std::unique_ptr<wrapper_base> clone() const = 0;
78 };
79
80 template<Manifold M>
81 class wrapper : public wrapper_base
82 {
83 public:
84 explicit wrapper(const M & val) : m_val(val) {}
85 explicit wrapper(M && val) : m_val(std::move(val)) {}
86 Eigen::Index dof() const override { return ::smooth::dof(m_val); }
87 std::unique_ptr<wrapper_base> rplus(Eigen::Ref<const Eigen::VectorXd> a) const override
88 {
89 return std::make_unique<wrapper<M>>(::smooth::rplus(m_val, a));
90 }
91 Eigen::VectorXd rminus(const std::unique_ptr<wrapper_base> & o) const override
92 {
93 return ::smooth::rminus(m_val, static_cast<const wrapper<M> *>(o.get())->m_val);
94 }
95 std::unique_ptr<wrapper_base> clone() const override { return std::make_unique<wrapper<M>>(m_val); }
96 M & get() { return m_val; }
97 const M & get() const { return m_val; }
98
99 private:
100 M m_val;
101 };
102
103private:
104 explicit AnyManifold(std::unique_ptr<wrapper_base> val) : m_val(std::move(val)) {}
105 std::unique_ptr<wrapper_base> m_val;
106};
107
108namespace traits {
109
110template<>
111struct man<AnyManifold>
112{
113 using Scalar = double;
114 using PlainObject = AnyManifold;
115 template<typename NewScalar>
116 using CastT = PlainObject;
117
118 static constexpr int Dof = -1;
119
120 static inline Eigen::Index dof(const PlainObject & m) { return m.dof(); }
121
122 static inline PlainObject Default(Eigen::Index) { throw std::runtime_error("AnyManifold: default not supported"); }
123
124 template<typename NewScalar>
125 static inline CastT<NewScalar> cast(const PlainObject &)
126 {
127 throw std::runtime_error("AnyManifold: cast not supported");
128 }
129
130 template<typename Derived>
131 static inline PlainObject rplus(const PlainObject & m, const Eigen::MatrixBase<Derived> & a)
132 {
133 return m.rplus(a);
134 }
135
136 static inline Eigen::Vector<Scalar, Dof> rminus(const PlainObject & m1, const PlainObject & m2)
137 {
138 return m1.rminus(m2);
139 }
140};
141
142} // namespace traits
143
144SMOOTH_END_NAMESPACE
Type erasure Manifold class.
Definition any.hpp:16
Eigen::VectorXd rminus(const AnyManifold &m2) const
Right-minus.
Definition any.hpp:67
AnyManifold(AnyManifold &&m)
Move constructor.
Definition any.hpp:30
AnyManifold & operator=(const AnyManifold &m)
Copy assignment.
Definition any.hpp:33
AnyManifold rplus(Eigen::Ref< const Eigen::VectorXd > a) const
Right-plus.
Definition any.hpp:64
AnyManifold & operator=(AnyManifold &&m)
Move assignment.
Definition any.hpp:40
const M & get() const
Get value (const).
Definition any.hpp:55
Eigen::Index dof() const
Degrees of freedom.
Definition any.hpp:61
AnyManifold()
Constructor.
Definition any.hpp:19
AnyManifold(const AnyManifold &m)
Copy constructor.
Definition any.hpp:27
AnyManifold(const M &m)
Construct from typed manifoild.
Definition any.hpp:23
M & get()
Get value (mutable).
Definition any.hpp:48
PlainObject< M > Default()
Default-initialized Manifold with static dof.
Definition manifold.hpp:135
typename traits::man< M >::Scalar Scalar
Manifold scalar type.
Definition manifold.hpp:88
Eigen::Index dof(const M &m)
Manifold degrees of freedom (tangent space dimension)
Definition manifold.hpp:145
Tangent< M > rminus(const M &g1, const Mo &g2)
Manifold right-minus.
Definition manifold.hpp:172
PlainObject< M > rplus(const M &m, const Eigen::MatrixBase< Derived > &a)
Manifold right-plus.
Definition manifold.hpp:163
typename traits::man< M >::template CastT< NewScalar > CastT
Cast'ed type.
Definition manifold.hpp:100
CastT< NewScalar, M > cast(const M &m)
Cast to different scalar type.
Definition manifold.hpp:154
typename traits::man< M >::PlainObject PlainObject
Manifold default type.
Definition manifold.hpp:94