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 
7 #include <SpaceVecAlg/SpaceVecAlg>
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 
204  void write(const sva::PTransformd & pt);
205 
210  void write(const sva::ForceVecd & fv);
211 
216  void write(const sva::MotionVecd & mv);
217 
222  void write(const sva::ImpedanceVecd & mv);
223 
228  void write(const mc_rtc::Configuration & config);
229 
231  template<typename T, typename std::enable_if_t<internal::is_integral_v<T>, int> = 0>
232  void write(const T & number)
233  {
234  if constexpr(internal::is_like_int8_t<T>) { write(static_cast<int8_t>(number)); }
235  else if constexpr(internal::is_like_int16_t<T>) { write(static_cast<int16_t>(number)); }
236  else if constexpr(internal::is_like_int32_t<T>) { write(static_cast<int32_t>(number)); }
237  else if constexpr(internal::is_like_int64_t<T>) { write(static_cast<int64_t>(number)); }
238  else if constexpr(internal::is_like_uint8_t<T>) { write(static_cast<uint8_t>(number)); }
239  else if constexpr(internal::is_like_uint16_t<T>) { write(static_cast<uint16_t>(number)); }
240  else if constexpr(internal::is_like_uint32_t<T>) { write(static_cast<uint32_t>(number)); }
241  else if constexpr(internal::is_like_uint64_t<T>) { write(static_cast<uint64_t>(number)); }
242  else { static_assert(!std::is_same_v<T, T>, "T is integral but has an unsupported size"); }
243  }
244 
246  template<typename T, typename = std::enable_if_t<internal::has_write_builder_v<T>>>
247  void write(const T & value)
248  {
249  value.write(*this);
250  }
251 
253  /* End Add data to the MessagePack section (advanced) */
254 
264  template<typename T, typename A>
265  void write(const std::vector<T, A> & v)
266  {
267  start_array(v.size());
268  for(const auto & value : v) { write(value); }
269  finish_array();
270  }
271 
273  template<typename T, std::size_t N>
274  void write(const std::array<T, N> & a)
275  {
276  start_array(N);
277  for(const auto & value : a) { write(value); }
278  finish_array();
279  }
280 
282  template<typename T1, typename T2>
283  void write(const std::pair<T1, T2> & p)
284  {
285  start_array(2);
286  write(p.first);
287  write(p.second);
288  finish_array();
289  }
290 
292  template<typename KeyT, typename T, typename C, typename A>
293  void write(const std::map<KeyT, T, C, A> & m)
294  {
295  start_map(m.size());
296  for(const auto & p : m)
297  {
298  write(p.first);
299  write(p.second);
300  }
301  finish_map();
302  }
303 
305  template<typename T, typename C, typename A>
306  void write(const std::set<T, C, A> & s)
307  {
308  start_array(s.size());
309  for(const auto & value : s) { write(value); }
310  finish_array();
311  }
312 
314  template<typename... Args>
315  void write(const std::tuple<Args...> & t)
316  {
317  start_array(sizeof...(Args));
318  write_impl<0>(t);
319  finish_array();
320  }
321 
323  template<typename... Args>
324  void write(const std::variant<Args...> & value)
325  {
326  start_array(2);
327  write(value.index());
328  std::visit([this](const auto & v) { write(v); }, value);
329  finish_array();
330  }
331 
333  template<typename Type, int Options, typename StrideType>
334  void write(const Eigen::Ref<Type, Options, StrideType> & v)
335  {
336 #if !EIGEN_VERSION_AT_LEAST(3, 2, 90)
337  using Index = Eigen::DenseIndex;
338 #else
339  using Index = Eigen::Index;
340 #endif
341  start_array(v.size());
342  for(Index i = 0; i < v.size(); ++i) { write(v(i)); }
343  finish_array();
344  }
345 
347  /* End Add data to the MessagePack section (containers) */
348 
353  void start_array(size_t size);
354 
356  void finish_array();
357 
362  void start_map(size_t size);
363 
365  void finish_map();
366 
374  void write_object(const char * data, size_t s);
375 
383  size_t finish();
384 
385 private:
387  std::unique_ptr<MessagePackBuilderImpl> impl_;
388 
389  template<size_t i,
390  typename... Args,
391  typename std::enable_if<i<sizeof...(Args), int>::type = 0> void write_impl(const std::tuple<Args...> & t)
392  {
393  write(std::get<i>(t));
394  write_impl<i + 1>(t);
395  }
396 
397  template<size_t i, typename... Args, typename std::enable_if<i >= sizeof...(Args), int>::type = 0>
398  void write_impl(const std::tuple<Args...> &)
399  {
400  }
401 };
402 
403 } // namespace mc_rtc
mc_rtc::Configuration
Simplify access to values hold within a JSON file.
Definition: Configuration.h:165
mc_rtc::internal::is_like_int32_t
constexpr bool is_like_int32_t
Definition: MessagePackBuilder.h:53
mc_rtc::MessagePackBuilder
Definition: MessagePackBuilder.h:86
mc_rtc::internal::is_like_uint64_t
constexpr bool is_like_uint64_t
Definition: MessagePackBuilder.h:63
mc_rtc::MessagePackBuilder::write
void write(const T &number)
Definition: MessagePackBuilder.h:232
mc_rtc::MessagePackBuilder::write
void write(const std::map< KeyT, T, C, A > &m)
Definition: MessagePackBuilder.h:293
mc_rtc::internal::is_like
constexpr bool is_like()
Definition: MessagePackBuilder.h:35
mc_rtc::MessagePackBuilder::write
void write(const std::pair< T1, T2 > &p)
Definition: MessagePackBuilder.h:283
mc_rtc::internal::is_like_int16_t
constexpr bool is_like_int16_t
Definition: MessagePackBuilder.h:51
mc_rtc::MessagePackBuilder::write
void write(const std::tuple< Args... > &t)
Definition: MessagePackBuilder.h:315
Gains.h
mc_rtc::internal::is_like_uint8_t
constexpr bool is_like_uint8_t
Definition: MessagePackBuilder.h:57
mc_rtc::internal::is_like_int8_t
constexpr bool is_like_int8_t
Definition: MessagePackBuilder.h:49
mc_rtc::internal::has_write_builder
Definition: MessagePackBuilder.h:66
mc_rtc::MessagePackBuilder::write
void write(const std::variant< Args... > &value)
Definition: MessagePackBuilder.h:324
mc_rtc::internal::is_like_uint16_t
constexpr bool is_like_uint16_t
Definition: MessagePackBuilder.h:59
mc_rtc::MessagePackBuilder::write
void write(const Eigen::Matrix< double, N, 1, _Options, _MaxRows, _MaxCols > &v)
Definition: MessagePackBuilder.h:180
mc_rtc::gui::details::void_t
void void_t
Definition: traits.h:25
mc_rtc::MessagePackBuilder::write
void write(const T &value)
Definition: MessagePackBuilder.h:247
mc_rtc::gui::details::write
auto write(T &value)
Definition: traits.h:224
mc_rtc::internal::is_like_uint32_t
constexpr bool is_like_uint32_t
Definition: MessagePackBuilder.h:61
mc_rtc::MessagePackBuilder::write
void write(const Eigen::Ref< Type, Options, StrideType > &v)
Definition: MessagePackBuilder.h:334
mc_rtc::MessagePackBuilder::write
void write(const std::vector< T, A > &v)
Definition: MessagePackBuilder.h:265
mc_rtc::MessagePackBuilder::write
void write(const std::set< T, C, A > &s)
Definition: MessagePackBuilder.h:306
mc_rtc::internal::is_integral_v
constexpr bool is_integral_v
Definition: MessagePackBuilder.h:31
MC_RTC_UTILS_DLLAPI
#define MC_RTC_UTILS_DLLAPI
Definition: utils_api.h:50
utils_api.h
std
Definition: Contact.h:66
mc_rtc::internal::is_like_int64_t
constexpr bool is_like_int64_t
Definition: MessagePackBuilder.h:55
mc_rtc::Configuration
struct MC_RTC_UTILS_DLLAPI Configuration
Definition: Configuration.h:46
mc_rtc::MessagePackBuilder::write
void write(const std::array< T, N > &a)
Definition: MessagePackBuilder.h:274
mc_rtc
Definition: Contact.h:87