aron_conversions.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <map>
4 #include <memory>
5 #include <optional>
6 #include <type_traits>
7 #include <vector>
8 #include <algorithm>
9 
10 #include "Path.h"
11 
12 namespace armarx::aron
13 {
14 
15 namespace detail
16 {
17 
18  // Helper concept to avoid ambiguities
19  template<typename DtoT, typename BoT>
21 
22  template <class ...>
23  struct is_optional : public std::false_type {};
24 
25  template <class ...Ts>
26  struct is_optional<std::optional<Ts...>> : public std::true_type {};
27 
28 }
29 
30  /**
31  * Framework for converting ARON DTOs (Data Transfer Objects) to C++ BOs
32  * (Business Objects) and back.
33  *
34  * To allow conversion between custom ARON and C++ types, declare two
35  * functions in the namespace of the BO:
36  *
37  * @code
38  * // aron_conversions.h
39  *
40  * namespace bo_namespace
41  * {
42  * void toAron(arondto::MyObject& dto, const MyObject& bo);
43  * void fromAron(const arondto::MyObject& dto, MyObject& bo);
44  * }
45  * @endcode
46  *
47  * Note that the DTO always comes first, and the target object is
48  * non-const.
49  *
50  * In the implementation,
51  *
52  *
53  * @code
54  * // aron_conversions.cpp
55  *
56  * #include "aron_conversions.h"
57  * #include <Path/to/MyValue/aron_conversions.h>
58  *
59  * void bo_namespace::toAron(arondto::MyObject& dto, const MyObject& bo)
60  * {
61  * dto.name = bo.name;
62  * toAron(dto.myValue, bo.myValue);
63  * }
64  *
65  * void bo_namespace::fromAron(const arondto::MyObject& dto, MyObject& bo)
66  * {
67  * bo.name = dto.name;
68  * fromAron(dto.myValue, bo.myValue);
69  * }
70  * @endcode
71  */
72  // Same type
73  template <class T>
74  void toAron(T& dto, const T& bo)
75  {
76  dto = bo;
77  }
78  template <class T>
79  void fromAron(const T& dto, T& bo)
80  {
81  bo = dto;
82  }
83 
84 
85  // Generic return version
86  template <class DtoT, class BoT>
87  DtoT toAron(const BoT& bo)
88  {
89  DtoT dto;
90  toAron(dto, bo);
91  return dto;
92  }
93  template <class BoT, class DtoT>
94  BoT fromAron(const DtoT& dto)
95  {
96  BoT bo;
97  fromAron(dto, bo);
98  return bo;
99  }
100 
101 
102 
103 
104 
105 
106 
107  // std::unique_ptr
108  template <class DtoT, class BoT>
109  void toAron(DtoT& dto, const std::unique_ptr<BoT>& bo)
110  {
111  if (bo)
112  {
113  toAron(dto, *bo);
114  }
115  }
116 
117  template <class DtoT, class BoT>
118  void fromAron(const DtoT& dto, std::unique_ptr<BoT>& bo)
119  {
120  bo = std::make_unique<BoT>();
121  fromAron(dto, *bo);
122  }
123 
124 
125  // std::optional
126  template <class DtoT, class BoT>
127  void toAron(std::optional<DtoT>& dto, const std::optional<BoT>& bo)
128  {
129  if (bo.has_value())
130  {
131  dto = DtoT{};
132  toAron(*dto, *bo);
133  }
134  else
135  {
136  dto = std::nullopt;
137  }
138  }
139 
140  template <class DtoT, class BoT>
141  void fromAron(const std::optional<DtoT>& dto, std::optional<BoT>& bo)
142  {
143  if (dto.has_value())
144  {
145  bo = BoT{};
146  fromAron(*dto, *bo);
147  }
148  else
149  {
150  bo = std::nullopt;
151  }
152  }
153 
154 
155  // One-sided optional
156  template <class DtoT, class BoT>
158  void toAron(std::optional<DtoT>& dto, const BoT& bo)
159  {
160  dto = DtoT{};
161  toAron(*dto, bo);
162  }
163  template <class DtoT, class BoT>
165  void fromAron(DtoT& dto, const std::optional<BoT>& bo)
166  {
167  bo = BoT{};
168  fromAron(dto, *bo);
169  }
170 
171 
172  // Flag-controlled optional
173  template <class DtoT, class BoT>
174  void toAron(DtoT& dto, bool& dtoValid, const BoT& bo, bool boValid)
175  {
176  dtoValid = boValid;
177  if (boValid)
178  {
179  toAron(dto, bo);
180  }
181  else
182  {
183  dto = {};
184  }
185  }
186 
187 
188  template <class DtoT, class BoT>
189  void fromAron(const DtoT& dto, bool dtoValid, BoT& bo, bool& boValid)
190  {
191  boValid = dtoValid;
192  if (dtoValid)
193  {
194  fromAron(dto, bo);
195  }
196  else
197  {
198  bo = {};
199  }
200  }
201 
202  template <class DtoT, class BoT>
203  void toAron(DtoT& dto, bool& dtoValid, const std::optional<BoT>& bo)
204  {
205  dtoValid = bo.has_value();
206  if (dtoValid)
207  {
208  toAron(dto, *bo);
209  }
210  else
211  {
212  dto = {};
213  }
214  }
215 
216  template <class DtoT, class BoT>
217  void fromAron(const DtoT& dto, bool dtoValid, std::optional<BoT>& bo)
218  {
219  if (dtoValid)
220  {
221  bo = BoT{};
222  fromAron(dto, *bo);
223  }
224  else
225  {
226  bo = std::nullopt;
227  }
228  }
229 
230 
231  // std::vector
232  template <class DtoT, class BoT>
233  void toAron(std::vector<DtoT>& dtos, const std::vector<BoT>& bos)
234  {
235  dtos.clear();
236  dtos.reserve(bos.size());
237  for (const auto& bo : bos)
238  {
239  toAron(dtos.emplace_back(), bo);
240  }
241  }
242  template <class DtoT, class BoT>
243  void fromAron(const std::vector<DtoT>& dtos, std::vector<BoT>& bos)
244  {
245  bos.clear();
246  bos.reserve(dtos.size());
247  for (const auto& dto : dtos)
248  {
249  fromAron(dto, bos.emplace_back());
250  }
251  }
252 
253 
254  // std::map
255  template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT>
256  requires (!(detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and detail::DtoAndBoAreSame<DtoValueT, BoValueT>))
257  void toAron(std::map<DtoKeyT, DtoValueT>& dtoMap,
258  const std::map<BoKeyT, BoValueT>& boMap)
259  {
260  dtoMap.clear();
261  for (const auto& [boKey, boValue] : boMap)
262  {
263  DtoKeyT dtoKey;
264  toAron(dtoKey, boKey);
265  auto [it, _] = dtoMap.emplace(std::move(dtoKey), DtoValueT{});
266  toAron(it->second, boValue);
267  }
268  }
269  template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT>
270  requires (!(detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and detail::DtoAndBoAreSame<DtoValueT, BoValueT>))
271  void fromAron(const std::map<DtoKeyT, DtoValueT>& dtoMap,
272  std::map<BoKeyT, BoValueT>& boMap)
273  {
274  boMap.clear();
275  for (const auto& [dtoKey, dtoValue] : dtoMap)
276  {
277  BoKeyT boKey;
278  fromAron(dtoKey, boKey);
279  auto [it, _] = boMap.emplace(boKey, BoValueT{});
280  fromAron(dtoValue, it->second);
281  }
282  }
283 
284 
285  template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT>
286  requires (!(detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and detail::DtoAndBoAreSame<DtoValueT, BoValueT>))
287  std::map<DtoKeyT, DtoValueT> toAron(const std::map<BoKeyT, BoValueT>& boMap)
288  {
289  std::map<DtoKeyT, DtoValueT> dtoMap;
290  toAron(dtoMap, boMap);
291  return dtoMap;
292  }
293 }
294 
295 
296 
297 
298 
299 // And do the same for the armarx namespace to ensure consistency with all the other aron_conversions declaraions
300 // (which are usually in the armarx namespace)
301 namespace armarx
302 {
303  // Same type
304  template <class T>
305  void toAron(T& dto, const T& bo)
306  {
307  armarx::aron::toAron(dto, bo);
308  }
309  template <class T>
310  void fromAron(const T& dto, T& bo)
311  {
313  }
314 
315 
316  // Generic return version
317  template <class DtoT, class BoT>
318  DtoT toAron(const BoT& bo)
319  {
320  return armarx::aron::toAron<DtoT, BoT>(bo);
321  }
322  template <class BoT, class DtoT>
323  BoT fromAron(const DtoT& dto)
324  {
325  return armarx::aron::fromAron<BoT, DtoT>(dto);
326  }
327 
328  // std::unique_ptr
329  template <class DtoT, class BoT>
330  void toAron(DtoT& dto, const std::unique_ptr<BoT>& bo)
331  {
332  armarx::aron::toAron(dto, bo);
333  }
334  template <class DtoT, class BoT>
335  void fromAron(const DtoT& dto, std::unique_ptr<BoT>& bo)
336  {
338  }
339 
340  // std::optional
341  template <class DtoT, class BoT>
342  void toAron(std::optional<DtoT>& dto, const std::optional<BoT>& bo)
343  {
344  armarx::aron::toAron(dto, bo);
345  }
346  template <class DtoT, class BoT>
347  void fromAron(const std::optional<DtoT>& dto, std::optional<BoT>& bo)
348  {
350  }
351 
352  // Flag-controlled optional
353  template <class DtoT, class BoT>
354  void toAron(DtoT& dto, bool& dtoValid, const BoT& bo, bool boValid)
355  {
356  armarx::aron::toAron(dto, dtoValid, bo, boValid);
357  }
358  template <class DtoT, class BoT>
359  void fromAron(const DtoT& dto, bool dtoValid, BoT& bo, bool& boValid)
360  {
361  armarx::aron::fromAron(dto, dtoValid, bo, boValid);
362  }
363 
364  template <class DtoT, class BoT>
365  void toAron(DtoT& dto, bool& dtoValid, const std::optional<BoT>& bo)
366  {
367  armarx::aron::toAron(dto, dtoValid, bo);
368  }
369  template <class DtoT, class BoT>
370  void fromAron(const DtoT& dto, bool dtoValid, std::optional<BoT>& bo)
371  {
372  armarx::aron::fromAron(dto, dtoValid, bo);
373  }
374 
375  // std::vector
376  template <class DtoT, class BoT>
377  requires (!aron::detail::DtoAndBoAreSame<DtoT, BoT>)
378  void toAron(std::vector<DtoT>& dtos, const std::vector<BoT>& bos)
379  {
380  armarx::aron::toAron(dtos, bos);
381  }
382  template <class DtoT, class BoT>
383  requires (!aron::detail::DtoAndBoAreSame<DtoT, BoT>)
384  void fromAron(const std::vector<DtoT>& dtos, std::vector<BoT>& bos)
385  {
386  armarx::aron::fromAron(dtos, bos);
387  }
388 
389  template <class DtoT, class BoT>
390  requires (!aron::detail::DtoAndBoAreSame<DtoT, BoT>)
391  std::vector<DtoT> toAron(const std::vector<BoT>& bos)
392  {
393  return armarx::aron::toAron<DtoT, BoT>(bos);
394  }
395 
396 
397  // std::map
398  template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT>
399  requires (!(aron::detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::detail::DtoAndBoAreSame<DtoValueT, BoValueT>))
400  void toAron(std::map<DtoKeyT, DtoValueT>& dtoMap, const std::map<BoKeyT, BoValueT>& boMap)
401  {
402  armarx::aron::toAron(dtoMap, boMap);
403  }
404  template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT>
405  requires (!(aron::detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::detail::DtoAndBoAreSame<DtoValueT, BoValueT>))
406  void fromAron(const std::map<DtoKeyT, DtoValueT>& dtoMap, std::map<BoKeyT, BoValueT>& boMap)
407  {
408  armarx::aron::fromAron(dtoMap, boMap);
409  }
410 
411 
412  template <class DtoKeyT, class DtoValueT, class BoKeyT, class BoValueT>
413  requires (!(aron::detail::DtoAndBoAreSame<DtoKeyT, BoKeyT> and aron::detail::DtoAndBoAreSame<DtoValueT, BoValueT>))
414  std::map<DtoKeyT, DtoValueT> toAron(const std::map<BoKeyT, BoValueT>& boMap)
415  {
416  armarx::aron::toAron<DtoKeyT, DtoValueT, BoKeyT, BoValueT>(boMap);
417  }
418 
419  /**
420  * @brief Converter function for vector of aron elements to plain cpp type
421  *
422  * You have to provide a converter function for the element with the signature
423  *
424  * PlainCppType fromAron(const AronType&)
425  *
426  * @tparam T the aron vector element
427  * @param v the vector of elements
428  * @return the vector of aron elements
429  */
430  template <typename T>
431  auto fromAron(const std::vector<T>& v) -> std::vector<decltype(fromAron(T()))>
432  {
433  std::vector<decltype(fromAron(T()))> r;
434  r.reserve(v.size());
435 
436  std::transform(v.begin(), v.end(), std::back_inserter(r),
437  [](const T & t)
438  {
439  return fromAron(t);
440  });
441 
442  return r;
443  }
444 
445 
446  template <typename T> auto toAron(const std::vector<T>& v)
447  {
448  std::vector<decltype(toAron(T()))> r;
449  r.reserve(v.size());
450 
451  std::transform(v.begin(), v.end(), std::back_inserter(r),
452  [](const T & t)
453  {
454  return toAron(t);
455  });
456 
457  return r;
458  }
459 }
Path.h
armarx::requires
requires(!aron::detail::DtoAndBoAreSame< DtoT, BoT >) void toAron(std
Definition: aron_conversions.h:377
detail
Definition: OpenCVUtil.cpp:127
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::aron::detail::is_optional
Definition: aron_conversions.h:23
armarx::aron
Definition: DataDisplayVisitor.cpp:5
armarx::aron::detail::DtoAndBoAreSame
concept DtoAndBoAreSame
Definition: aron_conversions.h:20
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
armarx::aron::toAron
void toAron(T &dto, const T &bo)
Framework for converting ARON DTOs (Data Transfer Objects) to C++ BOs (Business Objects) and back.
Definition: aron_conversions.h:74
std
Definition: Application.h:66
armarx::aron::requires
requires(not detail::is_optional< BoT >::value) void toAron(std
Definition: aron_conversions.h:157
armarx::transform
auto transform(const Container< InputT, Alloc > &in, OutputT(*func)(InputT const &)) -> Container< OutputT, typename std::allocator_traits< Alloc >::template rebind_alloc< OutputT > >
Convenience function (with less typing) to transform a container of type InputT into the same contain...
Definition: algorithm.h:315
armarx::fromAron
void fromAron(const arondto::PackagePath &dto, PackageFileLocation &bo)
armarx::toAron
void toAron(arondto::PackagePath &dto, const PackageFileLocation &bo)
T
float T
Definition: UnscentedKalmanFilterTest.cpp:35
armarx::aron::fromAron
void fromAron(const T &dto, T &bo)
Definition: aron_conversions.h:79
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::aron::bo
const std::optional< BoT > & bo
Definition: aron_conversions.h:166