mc_rtc  2.16.0
MessagePackBuilder.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <mc_rtc/utils_api.h>
4 
5 #include <mc_rbdyn/Gains.h>
6 
8 
9 #include <Eigen/Core>
10 #include <array>
11 #include <exception>
12 #include <map>
13 #include <memory>
14 #include <set>
15 #include <string>
16 #include <type_traits>
17 #include <variant>
18 #include <vector>
19 
20 namespace mc_rtc
21 {
22 
23 struct Configuration;
24 struct MessagePackBuilder;
25 struct MessagePackBuilderImpl;
26 
27 namespace internal
28 {
29 
30 template<typename T>
31 constexpr bool is_integral_v = std::is_integral_v<T> || std::numeric_limits<std::decay_t<T>>::is_integer;
32 
34 template<typename RefT, typename T>
35 constexpr bool is_like()
36 {
37  static_assert(std::is_integral_v<RefT>);
38  if constexpr(is_integral_v<T>)
39  {
40  // clang-format off
41  return std::numeric_limits<T>::is_signed == std::is_signed_v<RefT>
42  && std::numeric_limits<T>::max() == std::numeric_limits<RefT>::max();
43  // clang-format on
44  }
45  return false;
46 }
47 
48 template<typename T>
49 constexpr bool is_like_int8_t = is_like<int8_t, T>();
50 template<typename T>
51 constexpr bool is_like_int16_t = is_like<int16_t, T>();
52 template<typename T>
53 constexpr bool is_like_int32_t = is_like<int32_t, T>();
54 template<typename T>
55 constexpr bool is_like_int64_t = is_like<int64_t, T>();
56 template<typename T>
57 constexpr bool is_like_uint8_t = is_like<uint8_t, T>();
58 template<typename T>
59 constexpr bool is_like_uint16_t = is_like<uint16_t, T>();
60 template<typename T>
61 constexpr bool is_like_uint32_t = is_like<uint32_t, T>();
62 template<typename T>
63 constexpr bool is_like_uint64_t = is_like<uint64_t, T>();
64 
65 template<typename T, typename = void>
66 struct has_write_builder : std::false_type
67 {
68 };
69 
70 template<typename T>
71 struct has_write_builder<T, std::void_t<decltype(std::declval<const T &>().write(std::declval<MessagePackBuilder &>()))>>
72 : std::true_type
73 {
74 };
75 
76 template<typename T>
77 static inline constexpr bool has_write_builder_v = has_write_builder<T>::value;
78 
79 } // namespace internal
80 
87 {
93  MessagePackBuilder(std::vector<char> & buffer);
94 
97 
106  void write();
108  void write(bool b);
110  void write(int8_t i);
112  void write(int16_t i);
114  void write(int32_t i);
116  void write(int64_t i);
118  void write(uint8_t i);
120  void write(uint16_t i);
122  void write(uint32_t i);
124  void write(uint64_t i);
126  void write(float f);
128  void write(double d);
130  void write(const std::string & s);
132  void write(const char * s);
134  void write(const char * s, size_t len);
135 
137  /* End Add data to the MessagePack section */
138 
153  void write(const Eigen::Vector2d & v);
154 
159  void write(const Eigen::Vector3d & v);
160 
165  void write(const Eigen::Vector4d & v);
166 
171  void write(const Eigen::Vector6d & v);
172 
177  void write(const Eigen::VectorXd & v);
178 
179  template<int N, int _Options, int _MaxRows, int _MaxCols>
180  void write(const Eigen::Matrix<double, N, 1, _Options, _MaxRows, _MaxCols> & v)
181  {
182  static_assert(N != -1 && N != 2 && N != 3 && N != 6, "Should have gone to specialized function");
183  start_array(static_cast<size_t>(N));
184  for(Eigen::Index i = 0; i < N; ++i) { write(v(i)); }
185  finish_array();
186  }
187 
192  void write(const Eigen::Quaterniond & q);
193 
198  void write(const Eigen::Matrix3d & m);
199 
200  /* Write an Eigen::MatrixXd
201  *
202  * Serialized as an array of arrays
203  */
204  void write(const Eigen::MatrixXd & m);
205 
210  void write(const sva::PTransformd & pt);
211 
216  void write(const sva::ForceVecd & fv);
217 
222  void write(const sva::MotionVecd & mv);
223 
228  void write(const sva::ImpedanceVecd & mv);
229 
234  void write(const mc_rtc::Configuration & config);
235 
237  template<typename T, typename std::enable_if_t<internal::is_integral_v<T>, int> = 0>
238  void write(const T & number)
239  {
240  if constexpr(internal::is_like_int8_t<T>) { write(static_cast<int8_t>(number)); }
241  else if constexpr(internal::is_like_int16_t<T>) { write(static_cast<int16_t>(number)); }
242  else if constexpr(internal::is_like_int32_t<T>) { write(static_cast<int32_t>(number)); }
243  else if constexpr(internal::is_like_int64_t<T>) { write(static_cast<int64_t>(number)); }
244  else if constexpr(internal::is_like_uint8_t<T>) { write(static_cast<uint8_t>(number)); }
245  else if constexpr(internal::is_like_uint16_t<T>) { write(static_cast<uint16_t>(number)); }
246  else if constexpr(internal::is_like_uint32_t<T>) { write(static_cast<uint32_t>(number)); }
247  else if constexpr(internal::is_like_uint64_t<T>) { write(static_cast<uint64_t>(number)); }
248  else
249  {
250  static_assert(!std::is_same_v<T, T>, "T is integral but has an unsupported size");
251  }
252  }
253 
255  template<typename T, typename = std::enable_if_t<internal::has_write_builder_v<T>>>
256  void write(const T & value)
257  { value.write(*this); }
258 
260  /* End Add data to the MessagePack section (advanced) */
261 
271  template<typename T, typename A>
272  void write(const std::vector<T, A> & v)
273  {
274  start_array(v.size());
275  for(const auto & value : v) { write(value); }
276  finish_array();
277  }
278 
280  template<typename T, std::size_t N>
281  void write(const std::array<T, N> & a)
282  {
283  start_array(N);
284  for(const auto & value : a) { write(value); }
285  finish_array();
286  }
287 
289  template<typename T1, typename T2>
290  void write(const std::pair<T1, T2> & p)
291  {
292  start_array(2);
293  write(p.first);
294  write(p.second);
295  finish_array();
296  }
297 
299  template<typename KeyT, typename T, typename C, typename A>
300  void write(const std::map<KeyT, T, C, A> & m)
301  {
302  start_map(m.size());
303  for(const auto & p : m)
304  {
305  write(p.first);
306  write(p.second);
307  }
308  finish_map();
309  }
310 
312  template<typename T, typename C, typename A>
313  void write(const std::set<T, C, A> & s)
314  {
315  start_array(s.size());
316  for(const auto & value : s) { write(value); }
317  finish_array();
318  }
319 
321  template<typename... Args>
322  void write(const std::tuple<Args...> & t)
323  {
324  start_array(sizeof...(Args));
325  write_impl<0>(t);
326  finish_array();
327  }
328 
330  template<typename... Args>
331  void write(const std::variant<Args...> & value)
332  {
333  start_array(2);
334  write(value.index());
335  std::visit([this](const auto & v) { write(v); }, value);
336  finish_array();
337  }
338 
340  template<typename Type, int Options, typename StrideType>
341  void write(const Eigen::Ref<Type, Options, StrideType> & v)
342  {
343 #if !EIGEN_VERSION_AT_LEAST(3, 2, 90)
344  using Index = Eigen::DenseIndex;
345 #else
346  using Index = Eigen::Index;
347 #endif
348  start_array(v.size());
349  for(Index i = 0; i < v.size(); ++i) { write(v(i)); }
350  finish_array();
351  }
352 
354  /* End Add data to the MessagePack section (containers) */
355 
360  void start_array(size_t size);
361 
363  void finish_array();
364 
369  void start_map(size_t size);
370 
372  void finish_map();
373 
381  void write_object(const char * data, size_t s);
382 
390  size_t finish();
391 
392 private:
394  std::unique_ptr<MessagePackBuilderImpl> impl_;
395 
396  template<size_t i,
397  typename... Args,
398  typename std::enable_if<i<sizeof...(Args), int>::type = 0> void write_impl(const std::tuple<Args...> & t)
399  {
400  write(std::get<i>(t));
401  write_impl<i + 1>(t);
402  }
403 
404  template<size_t i, typename... Args, typename std::enable_if<i >= sizeof...(Args), int>::type = 0>
405  void write_impl(const std::tuple<Args...> &)
406  {
407  }
408 };
409 
410 } // namespace mc_rtc
std::optional< Eigen::VectorXd > value
Vector6< double > Vector6d
void void_t
Definition: traits.h:25
auto write(T &value)
Definition: traits.h:226
constexpr bool is_like_uint16_t
Definition: MessagePackBuilder.h:59
constexpr bool is_like_int8_t
Definition: MessagePackBuilder.h:49
constexpr bool is_like_int64_t
Definition: MessagePackBuilder.h:55
constexpr bool is_integral_v
Definition: MessagePackBuilder.h:31
constexpr bool is_like_uint32_t
Definition: MessagePackBuilder.h:61
constexpr bool is_like_uint64_t
Definition: MessagePackBuilder.h:63
constexpr bool is_like_uint8_t
Definition: MessagePackBuilder.h:57
constexpr bool is_like()
Definition: MessagePackBuilder.h:35
constexpr bool is_like_int16_t
Definition: MessagePackBuilder.h:51
constexpr bool is_like_int32_t
Definition: MessagePackBuilder.h:53
Definition: Contact.h:88
struct MC_RTC_UTILS_DLLAPI Configuration
Definition: Configuration.h:46
Simplify access to values hold within a JSON file.
Definition: Configuration.h:166
Definition: MessagePackBuilder.h:87
void write(const std::string &s)
void write(const Eigen::Vector4d &v)
void start_array(size_t size)
void write(const std::variant< Args... > &value)
Definition: MessagePackBuilder.h:331
void write(const std::set< T, C, A > &s)
Definition: MessagePackBuilder.h:313
void write(const Eigen::Vector3d &v)
void write(const Eigen::Matrix< double, N, 1, _Options, _MaxRows, _MaxCols > &v)
Definition: MessagePackBuilder.h:180
void write(const sva::ForceVecd &fv)
void write(const std::vector< T, A > &v)
Definition: MessagePackBuilder.h:272
void write(const sva::PTransformd &pt)
void write(const Eigen::Ref< Type, Options, StrideType > &v)
Definition: MessagePackBuilder.h:341
void write(const T &value)
Definition: MessagePackBuilder.h:256
void write(const char *s)
void write(const Eigen::MatrixXd &m)
void write(const Eigen::Quaterniond &q)
void write(const std::map< KeyT, T, C, A > &m)
Definition: MessagePackBuilder.h:300
void write_object(const char *data, size_t s)
void write(const sva::MotionVecd &mv)
MessagePackBuilder(std::vector< char > &buffer)
void write(const mc_rtc::Configuration &config)
void write(const T &number)
Definition: MessagePackBuilder.h:238
void write(const std::array< T, N > &a)
Definition: MessagePackBuilder.h:281
void write(uint64_t i)
void start_map(size_t size)
void write(const char *s, size_t len)
void write(const Eigen::Matrix3d &m)
void write(const sva::ImpedanceVecd &mv)
void write(const std::tuple< Args... > &t)
Definition: MessagePackBuilder.h:322
void write(uint16_t i)
void write(const Eigen::Vector2d &v)
void write(uint32_t i)
void write(const Eigen::Vector6d &v)
void write(const std::pair< T1, T2 > &p)
Definition: MessagePackBuilder.h:290
void write(const Eigen::VectorXd &v)
Definition: MessagePackBuilder.h:67
#define MC_RTC_UTILS_DLLAPI
Definition: utils_api.h:50