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_INNER_DERIVED_CAST(base_class, inner_class, derived_class) \
172 template <typename NewScalar> \
173 explicit derived_class( \
174 const typename inner_class<NewScalar>::derived_class& other) { \
175 *this = other.template cast<Scalar>(); /* This needs to define a cast \
176 operator */ \
177 } \
178 /* Implements casting by overriding `cloneAsFloat` */ \
179 std::shared_ptr<base_class> cloneAsDouble() const override { \
180 return std::make_shared<typename inner_class<double>::derived_class>( \
181 this->template cast<double>()); \
182 } \
183 std::shared_ptr<base_class> cloneAsFloat() const override { \
184 return std::make_shared<typename inner_class<float>::derived_class>( \
185 this->template cast<float>()); \
186 } \
187 std::shared_ptr<base_class> cloneAsADDouble() const override { \
188 return std::make_shared<typename inner_class<ADFloat64>::derived_class>( \
189 this->template cast<ADFloat64>()); \
190 }
191#else
192#define CROCODDYL_BASE_CAST(base_class, class) \
193 template <typename Scalar> \
194 std::shared_ptr<class<Scalar>> cast() const { \
195 return std::static_pointer_cast<class<Scalar>>(cast_impl<Scalar>()); \
196 } template <typename Scalar> \
197 std::shared_ptr<base_class> cast_impl() const { \
198 if (typeid(Scalar) == typeid(double)) { \
199 return cloneAsDouble(); \
200 } else if (typeid(Scalar) == typeid(float)) { \
201 return cloneAsFloat(); \
202 } else { \
203 std::cout << "Unsupported casting: casting to double as default" \
204 << std::endl; \
205 return cloneAsDouble(); \
206 } \
207 } \
208 /* Pure virtual method that derived classes must implement for casting */ \
209 virtual std::shared_ptr<base_class> cloneAsDouble() const = 0; \
210 virtual std::shared_ptr<base_class> cloneAsFloat() const = 0;
211
223#define CROCODDYL_DERIVED_CAST(base_class, derived_class) \
224 template <typename NewScalar> \
225 explicit derived_class(const derived_class<NewScalar>& other) \
226 : derived_class(std::move(other.template cast<Scalar>())) {} \
227 /* Implements casting by overriding `cloneAsFloat` */ \
228 std::shared_ptr<base_class> cloneAsDouble() const override { \
229 return std::make_shared<derived_class<double>>(*this); \
230 } \
231 std::shared_ptr<base_class> cloneAsFloat() const override { \
232 return std::make_shared<derived_class<float>>(*this); \
233 }
234
235#define CROCODDYL_DERIVED_FLOATINGPOINT_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_BASE_DERIVED_CAST(base_class, derived_class) \
248 /* Implements casting by overriding `cloneAsFloat` */ \
249 std::shared_ptr<base_class> cloneAsDouble() const override { \
250 return std::shared_ptr<base_class>(nullptr); \
251 } \
252 std::shared_ptr<base_class> cloneAsFloat() const override { \
253 return std::shared_ptr<base_class>(nullptr); \
254 }
255
256#define CROCODDYL_INNER_DERIVED_CAST(base_class, inner_class, derived_class) \
257 template <typename NewScalar> \
258 explicit derived_class( \
259 const typename inner_class<NewScalar>::derived_class& other) { \
260 *this = other.template cast<Scalar>(); /* This needs to define a cast \
261 operator */ \
262 } \
263 /* Implements casting by overriding `cloneAsFloat` */ \
264 std::shared_ptr<base_class> cloneAsDouble() const override { \
265 return std::make_shared<typename inner_class<double>::derived_class>( \
266 this->template cast<double>()); \
267 } \
268 std::shared_ptr<base_class> cloneAsFloat() const override { \
269 return std::make_shared<typename inner_class<float>::derived_class>( \
270 this->template cast<float>()); \
271 }
272#endif
273#endif // CROCODDYL_MACROS_HPP_