Crocoddyl
Loading...
Searching...
No Matches
macros.hpp
1
2// BSD 3-Clause License
3//
4// Copyright (C) 2025, Heriot-Watt University
5// Copyright note valid unless otherwise stated in individual files.
6// All rights reserved.
8
9#ifndef CROCODDYL_MACROS_HPP_
10#define CROCODDYL_MACROS_HPP_
11
12#include <iostream>
13#include <memory>
14#include <vector>
15
16#ifdef CROCODDYL_WITH_CODEGEN
17#include <cppad/cg/support/cppadcg_eigen.hpp>
18#include <cppad/cppad.hpp>
19#endif
20
21#define DEFAULT_SCALAR double
22typedef double Float64;
23typedef float Float32;
24#ifdef CROCODDYL_WITH_CODEGEN
25typedef CppAD::cg::CG<Float64> CGFloat64;
26typedef CppAD::AD<CGFloat64> ADFloat64;
27#endif
28
29#if __cplusplus <= 201103L
30namespace std {
31template <typename T, typename... Args>
32std::unique_ptr<T> make_unique(Args&&... args) {
33 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
34}
35} // namespace std
36#endif
37
38#ifdef CROCODDYL_WITH_CODEGEN
39#define CROCODDYL_DECLARE_EXTERN_TEMPLATE_CLASS(class_name) \
40 extern template class CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
41 class_name<double>; \
42 extern template class CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
43 class_name<float>; \
44 extern template class CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
45 class_name<ADFloat64>;
46
47#define CROCODDYL_DECLARE_EXTERN_TEMPLATE_STRUCT(class_name) \
48 extern template struct CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
49 class_name<double>; \
50 extern template struct CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
51 class_name<float>; \
52 extern template struct CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
53 class_name<ADFloat64>;
54
55#define CROCODDYL_DECLARE_FLOATINGPOINT_EXTERN_TEMPLATE_CLASS(class_name) \
56 extern template class CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
57 class_name<double>; \
58 extern template class CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
59 class_name<float>;
60
61#define CROCODDYL_DECLARE_FLOATINGPOINT_EXTERN_TEMPLATE_STRUCT(class_name) \
62 extern template struct CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
63 class_name<double>; \
64 extern template struct CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
65 class_name<float>;
66#else
67#define CROCODDYL_DECLARE_EXTERN_TEMPLATE_CLASS(class_name) \
68 extern template class CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
69 class_name<double>; \
70 extern template class CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
71 class_name<float>;
72
73#define CROCODDYL_DECLARE_EXTERN_TEMPLATE_STRUCT(class_name) \
74 extern template struct CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
75 class_name<double>; \
76 extern template struct CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
77 class_name<float>;
78
79#define CROCODDYL_DECLARE_FLOATINGPOINT_EXTERN_TEMPLATE_CLASS(class_name) \
80 extern template class CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
81 class_name<double>; \
82 extern template class CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
83 class_name<float>;
84
85#define CROCODDYL_DECLARE_FLOATINGPOINT_EXTERN_TEMPLATE_STRUCT(class_name) \
86 extern template struct CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
87 class_name<double>; \
88 extern template struct CROCODDYL_EXPLICIT_INSTANTIATION_DECLARATION_DLLAPI \
89 class_name<float>;
90#endif
91
92#ifdef CROCODDYL_WITH_CODEGEN
93#define CROCODDYL_BASE_CAST(base_class, class) \
94 template <typename Scalar> \
95 std::shared_ptr<class<Scalar>> cast() const { \
96 return std::static_pointer_cast<class<Scalar>>(cast_impl<Scalar>()); \
97 } template <typename Scalar> \
98 std::shared_ptr<base_class> cast_impl() const { \
99 if (typeid(Scalar) == typeid(double)) { \
100 return cloneAsDouble(); \
101 } else if (typeid(Scalar) == typeid(float)) { \
102 return cloneAsFloat(); \
103 } else if (typeid(Scalar) == typeid(ADFloat64)) { \
104 return cloneAsADDouble(); \
105 } else { \
106 std::cout << "Unsupported casting: casting to double as default" \
107 << std::endl; \
108 return cloneAsDouble(); \
109 } \
110 } \
111 /* Pure virtual method that derived classes must implement for casting */ \
112 virtual std::shared_ptr<base_class> cloneAsDouble() const = 0; \
113 virtual std::shared_ptr<base_class> cloneAsFloat() const = 0; \
114 virtual std::shared_ptr<base_class> cloneAsADDouble() const = 0;
115
127#define CROCODDYL_DERIVED_CAST(base_class, derived_class) \
128 template <typename NewScalar> \
129 explicit derived_class(const derived_class<NewScalar>& other) \
130 : derived_class(std::move(other.template cast<Scalar>())) {} \
131 /* Implements casting by overriding `cloneAsFloat` */ \
132 std::shared_ptr<base_class> cloneAsDouble() const override { \
133 return std::make_shared<derived_class<double>>(*this); \
134 } \
135 std::shared_ptr<base_class> cloneAsFloat() const override { \
136 return std::make_shared<derived_class<float>>(*this); \
137 } \
138 std::shared_ptr<base_class> cloneAsADDouble() const override { \
139 return std::make_shared<derived_class<ADFloat64>>(*this); \
140 }
141
142#define CROCODDYL_DERIVED_FLOATINGPOINT_CAST(base_class, derived_class) \
143 template <typename NewScalar> \
144 explicit derived_class(const derived_class<NewScalar>& other) \
145 : derived_class(std::move(other.template cast<Scalar>())) {} \
146 /* Implements casting by overriding `cloneAsFloat` */ \
147 std::shared_ptr<base_class> cloneAsDouble() const override { \
148 return std::make_shared<derived_class<double>>(*this); \
149 } \
150 std::shared_ptr<base_class> cloneAsFloat() const override { \
151 return std::make_shared<derived_class<float>>(*this); \
152 } \
153 std::shared_ptr<base_class> cloneAsADDouble() const override { \
154 std::cout << "Unsupported casting: retuning to double as default" \
155 << std::endl; \
156 return cloneAsDouble(); \
157 }
158
159#define CROCODDYL_BASE_DERIVED_CAST(base_class, derived_class) \
160 /* Implements casting by overriding `cloneAsFloat` */ \
161 std::shared_ptr<base_class> cloneAsDouble() const override { \
162 return std::shared_ptr<base_class>(nullptr); \
163 } \
164 std::shared_ptr<base_class> cloneAsFloat() const override { \
165 return std::shared_ptr<base_class>(nullptr); \
166 } \
167 std::shared_ptr<base_class> cloneAsADDouble() const override { \
168 return std::shared_ptr<base_class>(nullptr); \
169 }
170
171#define CROCODDYL_BASE_DERIVED_FLOATINGPOINT_CAST(base_class, derived_class) \
172 /* Implements casting by overriding `cloneAsFloat` */ \
173 std::shared_ptr<base_class> cloneAsDouble() const override { \
174 return std::shared_ptr<base_class>(nullptr); \
175 } \
176 std::shared_ptr<base_class> cloneAsFloat() const override { \
177 return std::shared_ptr<base_class>(nullptr); \
178 } \
179 std::shared_ptr<base_class> cloneAsADDouble() const override { \
180 return std::shared_ptr<base_class>(nullptr); \
181 }
182
183#define CROCODDYL_INNER_DERIVED_CAST(base_class, inner_class, derived_class) \
184 template <typename NewScalar> \
185 explicit derived_class( \
186 const typename inner_class<NewScalar>::derived_class& other) { \
187 *this = other.template cast<Scalar>(); /* This needs to define a cast \
188 operator */ \
189 } \
190 /* Implements casting by overriding `cloneAsFloat` */ \
191 std::shared_ptr<base_class> cloneAsDouble() const override { \
192 return std::make_shared<typename inner_class<double>::derived_class>( \
193 this->template cast<double>()); \
194 } \
195 std::shared_ptr<base_class> cloneAsFloat() const override { \
196 return std::make_shared<typename inner_class<float>::derived_class>( \
197 this->template cast<float>()); \
198 } \
199 std::shared_ptr<base_class> cloneAsADDouble() const override { \
200 return std::make_shared<typename inner_class<ADFloat64>::derived_class>( \
201 this->template cast<ADFloat64>()); \
202 }
203#else
204#define CROCODDYL_BASE_CAST(base_class, class) \
205 template <typename Scalar> \
206 std::shared_ptr<class<Scalar>> cast() const { \
207 return std::static_pointer_cast<class<Scalar>>(cast_impl<Scalar>()); \
208 } template <typename Scalar> \
209 std::shared_ptr<base_class> cast_impl() const { \
210 if (typeid(Scalar) == typeid(double)) { \
211 return cloneAsDouble(); \
212 } else if (typeid(Scalar) == typeid(float)) { \
213 return cloneAsFloat(); \
214 } else { \
215 std::cout << "Unsupported casting: casting to double as default" \
216 << std::endl; \
217 return cloneAsDouble(); \
218 } \
219 } \
220 /* Pure virtual method that derived classes must implement for casting */ \
221 virtual std::shared_ptr<base_class> cloneAsDouble() const = 0; \
222 virtual std::shared_ptr<base_class> cloneAsFloat() const = 0;
223
235#define CROCODDYL_DERIVED_CAST(base_class, derived_class) \
236 template <typename NewScalar> \
237 explicit derived_class(const derived_class<NewScalar>& other) \
238 : derived_class(std::move(other.template cast<Scalar>())) {} \
239 /* Implements casting by overriding `cloneAsFloat` */ \
240 std::shared_ptr<base_class> cloneAsDouble() const override { \
241 return std::make_shared<derived_class<double>>(*this); \
242 } \
243 std::shared_ptr<base_class> cloneAsFloat() const override { \
244 return std::make_shared<derived_class<float>>(*this); \
245 }
246
247#define CROCODDYL_DERIVED_FLOATINGPOINT_CAST(base_class, derived_class) \
248 template <typename NewScalar> \
249 explicit derived_class(const derived_class<NewScalar>& other) \
250 : derived_class(std::move(other.template cast<Scalar>())) {} \
251 /* Implements casting by overriding `cloneAsFloat` */ \
252 std::shared_ptr<base_class> cloneAsDouble() const override { \
253 return std::make_shared<derived_class<double>>(*this); \
254 } \
255 std::shared_ptr<base_class> cloneAsFloat() const override { \
256 return std::make_shared<derived_class<float>>(*this); \
257 }
258
259#define CROCODDYL_BASE_DERIVED_CAST(base_class, derived_class) \
260 /* Implements casting by overriding `cloneAsFloat` */ \
261 std::shared_ptr<base_class> cloneAsDouble() const override { \
262 return std::shared_ptr<base_class>(nullptr); \
263 } \
264 std::shared_ptr<base_class> cloneAsFloat() const override { \
265 return std::shared_ptr<base_class>(nullptr); \
266 }
267
268#define CROCODDYL_BASE_DERIVED_FLOATINGPOINT_CAST(base_class, derived_class) \
269 /* Implements casting by overriding `cloneAsFloat` */ \
270 std::shared_ptr<base_class> cloneAsDouble() const override { \
271 return std::shared_ptr<base_class>(nullptr); \
272 } \
273 std::shared_ptr<base_class> cloneAsFloat() const override { \
274 return std::shared_ptr<base_class>(nullptr); \
275 }
276
277#define CROCODDYL_INNER_DERIVED_CAST(base_class, inner_class, derived_class) \
278 template <typename NewScalar> \
279 explicit derived_class( \
280 const typename inner_class<NewScalar>::derived_class& other) { \
281 *this = other.template cast<Scalar>(); /* This needs to define a cast \
282 operator */ \
283 } \
284 /* Implements casting by overriding `cloneAsFloat` */ \
285 std::shared_ptr<base_class> cloneAsDouble() const override { \
286 return std::make_shared<typename inner_class<double>::derived_class>( \
287 this->template cast<double>()); \
288 } \
289 std::shared_ptr<base_class> cloneAsFloat() const override { \
290 return std::make_shared<typename inner_class<float>::derived_class>( \
291 this->template cast<float>()); \
292 }
293#endif
294#endif // CROCODDYL_MACROS_HPP_