Tesseract
Motion Planning Environment
Loading...
Searching...
No Matches
type_erasure.h
Go to the documentation of this file.
1
26#ifndef TESSERACT_COMMON_TYPE_ERASURE_H
27#define TESSERACT_COMMON_TYPE_ERASURE_H
28
29#include <memory>
30#include <typeindex>
31#include <boost/serialization/base_object.hpp>
32#include <boost/serialization/nvp.hpp>
33#include <boost/serialization/unique_ptr.hpp>
35
36namespace tesseract_common
37{
40{
41 virtual ~TypeErasureInterface() = default;
42
43 // This is not required for user defined implementation
44 virtual bool equals(const TypeErasureInterface& other) const = 0;
45
46 // This is not required for user defined implementation
47 virtual std::type_index getType() const = 0;
48
49 // This is not required for user defined implementation
50 virtual void* recover() = 0;
51
52 // This is not required for user defined implementation
53 virtual const void* recover() const = 0;
54
55 // This is not required for user defined implementation
56 virtual std::unique_ptr<TypeErasureInterface> clone() const = 0;
57
58private:
61 template <class Archive>
62 void serialize(Archive& /*ar*/, const unsigned int /*version*/){}; // NOLINT
63};
64
65template <typename ConcreteType, typename ConceptInterface>
66struct TypeErasureInstance : ConceptInterface
67{
68 using ConceptValueType = ConcreteType;
69 using ConceptInterfaceType = ConceptInterface;
70
72
73 explicit TypeErasureInstance(ConcreteType value) : value_(std::move(value)) {}
74
75 explicit TypeErasureInstance(ConcreteType&& value) : value_(std::move(value)) {}
76
77 const ConceptValueType& get() const { return value_; }
78
80
81 void* recover() final { return &value_; }
82
83 const void* recover() const final { return &value_; }
84
85 std::type_index getType() const final { return std::type_index(typeid(ConceptValueType)); }
86
87 bool equals(const TypeErasureInterface& other) const final
88 {
89 return this->getType() == other.getType() && this->get() == *static_cast<const ConceptValueType*>(other.recover());
90 }
91
92 ConcreteType value_;
93
94private:
97 template <class Archive>
98 void serialize(Archive& ar, const unsigned int /*version*/) // NOLINT
99 {
100 // If this line is removed a exception is thrown for unregistered cast need to too look into this.
101 ar& boost::serialization::make_nvp("base", boost::serialization::base_object<ConceptInterface>(*this));
102 ar& boost::serialization::make_nvp("impl", value_);
103 }
104};
105
106template <typename F>
107struct TypeErasureInstanceWrapper : F // NOLINT
108{
109 using ConceptValueType = typename F::ConceptValueType;
110 using ConceptInterfaceType = typename F::ConceptInterfaceType;
111
115
116 std::unique_ptr<TypeErasureInterface> clone() const final
117 {
118 return std::make_unique<TypeErasureInstanceWrapper<F>>(this->get());
119 }
120
121private:
124 template <class Archive>
125 void serialize(Archive& ar, const unsigned int /*version*/) // NOLINT
126 {
127 // If this line is removed a exception is thrown for unregistered cast need to too look into this.
128 ar& boost::serialization::make_nvp("base", boost::serialization::base_object<F>(*this));
129 }
130};
131
132template <typename ConceptInterface, template <typename> class ConceptInstance>
134{
135private:
136 template <typename T>
137 using uncvref_t = std::remove_cv_t<typename std::remove_reference<T>::type>;
138
139 // Enable the generic ctor only if ``T`` is not a ForwardKinematics (after removing const/reference qualifiers)
140 // If ``T`` is of type ForwardKinematics we disable so it will use the copy or move constructors of this class.
141 template <typename T>
142 using generic_ctor_enabler = std::enable_if_t<!std::is_base_of<TypeErasureBase, uncvref_t<T>>::value, int>;
143
144public:
145 using ConceptInterfaceType = ConceptInterface;
146
147 template <typename T, generic_ctor_enabler<T> = 0>
149 : value_(std::make_unique<TypeErasureInstanceWrapper<ConceptInstance<uncvref_t<T>>>>(value))
150 {
151 }
152
153 TypeErasureBase() : value_(nullptr){}; // NOLINT
154
155 // Destructor
156 ~TypeErasureBase() = default;
157
158 // Copy constructor
159 TypeErasureBase(const TypeErasureBase& other) : value_((other.value_ != nullptr) ? other.value_->clone() : nullptr) {}
160
161 // Move ctor.
162 TypeErasureBase(TypeErasureBase&& other) noexcept { value_.swap(other.value_); }
163
164 // Move assignment.
166 {
167 value_.swap(other.value_);
168 return (*this);
169 }
170
171 // Copy assignment.
173 {
174 (*this) = TypeErasureBase(other);
175 return (*this);
176 }
177
178 template <typename T, generic_ctor_enabler<T> = 0>
180 {
181 (*this) = TypeErasureBase(std::forward<T>(other));
182 return (*this);
183 }
184
185 std::type_index getType() const
186 {
187 if (value_ == nullptr)
188 return std::type_index{ typeid(nullptr) };
189
190 return value_->getType();
191 }
192
193 bool isNull() const { return (value_ == nullptr); }
194
195 bool operator==(const TypeErasureBase& rhs) const
196 {
197 if (value_ == nullptr && rhs.value_ == nullptr)
198 return true;
199
200 if (value_ != nullptr && rhs.value_ != nullptr)
201 return value_->equals(*rhs.value_);
202
203 return false;
204 }
205
206 bool operator!=(const TypeErasureBase& rhs) const { return !operator==(rhs); }
207
209
210 const ConceptInterfaceType& getInterface() const { return *static_cast<const ConceptInterfaceType*>(value_.get()); }
211
212 template <typename T>
213 T& as()
214 {
215 if (getType() != typeid(T))
216 throw std::runtime_error("TypeErasureBase, tried to cast '" + std::string(getType().name()) + "' to '" +
217 std::string(typeid(T).name()) + "'!");
218
219 auto* p = static_cast<uncvref_t<T>*>(value_->recover());
220 return *p;
221 }
222
223 template <typename T>
224 const T& as() const
225 {
226 if (getType() != typeid(T))
227 throw std::runtime_error("TypeErasureBase, tried to cast '" + std::string(getType().name()) + "' to '" +
228 std::string(typeid(T).name()) + "'!");
229
230 const auto* p = static_cast<const uncvref_t<T>*>(value_->recover());
231 return *p;
232 }
233
234private:
237
238 template <class Archive>
239 void serialize(Archive& ar, const unsigned int /*version*/) // NOLINT
240 {
241 ar& boost::serialization::make_nvp("value", value_);
242 }
243
244 std::unique_ptr<TypeErasureInterface> value_{ nullptr };
245};
246
247} // namespace tesseract_common
248
249BOOST_SERIALIZATION_ASSUME_ABSTRACT(tesseract_common::TypeErasureInterface)
250#endif // TESSERACT_COMMON_TYPE_ERASURE_H
Definition: polygon_mesh.h:46
auto clone
Definition: clone_cache_unit.cpp:126
Definition: allowed_collision_matrix.h:16
Definition: serialization.h:90
Definition: type_erasure.h:134
TypeErasureBase(TypeErasureBase &&other) noexcept
Definition: type_erasure.h:162
TypeErasureBase(T &&value)
Definition: type_erasure.h:148
bool isNull() const
Definition: type_erasure.h:193
TypeErasureBase & operator=(T &&other)
Definition: type_erasure.h:179
TypeErasureBase & operator=(TypeErasureBase &&other) noexcept
Definition: type_erasure.h:165
std::enable_if_t<!std::is_base_of< TypeErasureBase, uncvref_t< T > >::value, int > generic_ctor_enabler
Definition: type_erasure.h:142
TypeErasureBase()
Definition: type_erasure.h:153
std::unique_ptr< TypeErasureInterface > value_
Definition: type_erasure.h:244
TypeErasureBase(const TypeErasureBase &other)
Definition: type_erasure.h:159
bool operator==(const TypeErasureBase &rhs) const
Definition: type_erasure.h:195
ConceptInterfaceType & getInterface()
Definition: type_erasure.h:208
const T & as() const
Definition: type_erasure.h:224
bool operator!=(const TypeErasureBase &rhs) const
Definition: type_erasure.h:206
std::type_index getType() const
Definition: type_erasure.h:185
const ConceptInterfaceType & getInterface() const
Definition: type_erasure.h:210
void serialize(Archive &ar, const unsigned int)
Definition: type_erasure.h:239
friend class boost::serialization::access
Definition: type_erasure.h:235
std::remove_cv_t< typename std::remove_reference< T >::type > uncvref_t
Definition: type_erasure.h:137
TypeErasureBase & operator=(const TypeErasureBase &other)
Definition: type_erasure.h:172
ConceptInterface ConceptInterfaceType
Definition: type_erasure.h:145
T & as()
Definition: type_erasure.h:213
Definition: type_erasure.h:108
TypeErasureInstanceWrapper(const ConceptValueType &x)
Definition: type_erasure.h:113
void serialize(Archive &ar, const unsigned int)
Definition: type_erasure.h:125
typename F::ConceptInterfaceType ConceptInterfaceType
Definition: type_erasure.h:110
std::unique_ptr< TypeErasureInterface > clone() const final
Definition: type_erasure.h:116
TypeErasureInstanceWrapper(TypeErasureInstanceWrapper &&x) noexcept
Definition: type_erasure.h:114
friend class boost::serialization::access
Definition: type_erasure.h:122
typename F::ConceptValueType ConceptValueType
Definition: type_erasure.h:109
Definition: type_erasure.h:67
const void * recover() const final
Definition: type_erasure.h:83
ConceptValueType & get()
Definition: type_erasure.h:79
void * recover() final
Definition: type_erasure.h:81
TypeErasureInstance(ConcreteType value)
Definition: type_erasure.h:73
ConcreteType ConceptValueType
Definition: type_erasure.h:68
ConcreteType value_
Definition: type_erasure.h:92
std::type_index getType() const final
Definition: type_erasure.h:85
TypeErasureInstance(ConcreteType &&value)
Definition: type_erasure.h:75
void serialize(Archive &ar, const unsigned int)
Definition: type_erasure.h:98
bool equals(const TypeErasureInterface &other) const final
Definition: type_erasure.h:87
friend class boost::serialization::access
Definition: type_erasure.h:95
ConceptInterface ConceptInterfaceType
Definition: type_erasure.h:69
const ConceptValueType & get() const
Definition: type_erasure.h:77
This is the interface that all type erasures interfaces must inherit from.
Definition: type_erasure.h:40
virtual std::type_index getType() const =0
virtual std::unique_ptr< TypeErasureInterface > clone() const =0
virtual bool equals(const TypeErasureInterface &other) const =0
void serialize(Archive &, const unsigned int)
Definition: type_erasure.h:62
friend class boost::serialization::access
Definition: type_erasure.h:59
virtual const void * recover() const =0
Additional Boost serialization wrappers.
object value
Definition: tesseract_common_serialization_unit.cpp:495