MRPT  2.0.2
stl_serialization.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #pragma once
10 
13 #include <mrpt/typemeta/TTypeName_stl.h> // TTypeName<> for STL templates, needed for serialization of STL templates
14 #include <algorithm> // for_each()
15 #include <array>
16 #include <deque>
17 #include <list>
18 #include <map>
19 #include <set>
20 #include <vector>
21 
22 namespace mrpt::serialization
23 {
24 /** \addtogroup stlext_grp
25  * @{ */
26 
27 #define MRPTSTL_SERIALIZABLE_SEQ_CONTAINER(CONTAINER) \
28  /** Template method to serialize a sequential STL container */ \
29  template <class T, class _Ax> \
30  CArchive& operator<<(CArchive& out, const CONTAINER<T, _Ax>& obj) \
31  { \
32  out << std::string(#CONTAINER) << mrpt::typemeta::TTypeName<T>::get(); \
33  out.WriteAs<uint32_t>(obj.size()); \
34  std::for_each( \
35  obj.begin(), obj.end(), \
36  metaprogramming::ObjectWriteToStream(&out)); \
37  return out; \
38  } \
39  /** Template method to deserialize a sequential STL container */ \
40  template <class T, class _Ax> \
41  CArchive& operator>>(CArchive& in, CONTAINER<T, _Ax>& obj) \
42  { \
43  obj.clear(); \
44  std::string pref, stored_T; \
45  in >> pref; \
46  if (pref != #CONTAINER) \
47  THROW_EXCEPTION_FMT( \
48  "Error: serialized container %s<%s>'s preambles is wrong: " \
49  "'%s'", \
50  #CONTAINER, mrpt::typemeta::TTypeName<T>::get().c_str(), \
51  pref.c_str()); \
52  in >> stored_T; \
53  if (stored_T != \
54  std::string(mrpt::typemeta::TTypeName<T>::get().c_str())) \
55  THROW_EXCEPTION_FMT( \
56  "Error: serialized container %s< %s != %s >", #CONTAINER, \
57  stored_T.c_str(), \
58  mrpt::typemeta::TTypeName<T>::get().c_str()); \
59  const uint32_t n = in.ReadAs<uint32_t>(); \
60  obj.resize(n); \
61  std::for_each( \
62  obj.begin(), obj.end(), \
63  metaprogramming::ObjectReadFromStream(&in)); \
64  return in; \
65  }
66 
67 template <typename T>
68 using is_map_like = std::is_same<
69  typename T::value_type,
70  std::pair<const typename T::key_type, typename T::mapped_type>>;
71 
72 template <typename T>
73 using is_map = std::is_same<
74  T, typename std::map<
75  typename T::key_type, typename T::mapped_type,
76  typename T::key_compare, typename T::allocator_type>>;
77 
78 template <typename T>
79 using is_multimap = std::is_same<
80  T, typename std::multimap<
81  typename T::key_type, typename T::mapped_type,
82  typename T::key_compare, typename T::allocator_type>>;
83 
84 template <typename T, std::enable_if_t<is_map<T>::value, int> = 0>
85 std::string containerName()
86 {
87  return "std::map";
88 }
89 template <typename T, std::enable_if_t<is_multimap<T>::value, int> = 0>
90 std::string containerName()
91 {
92  return "std::multimap";
93 }
94 
95 /** Template method to serialize an associative STL container */
96 template <class T, std::enable_if_t<is_map_like<T>::value, int> = 0>
97 CArchive& operator<<(CArchive& out, const T& obj)
98 {
99  out << containerName<T>()
102  std::decay_t<typename T::mapped_type>>::get();
103  out.WriteAs<uint32_t>(obj.size());
104  for (typename T::const_iterator it = obj.begin(); it != obj.end(); ++it)
105  out << it->first << it->second;
106  return out;
107 }
108 /** Template method to deserialize an associative STL container */
109 template <class T, std::enable_if_t<is_map_like<T>::value, int> = 0>
110 CArchive& operator>>(CArchive& in, T& obj)
111 {
112  obj.clear();
113  std::string pref, stored_K, stored_V;
114  in >> pref;
115  if (pref != containerName<T>())
117  "Error: serialized container %s<%s,%s>'s preamble is "
118  "wrong: '%s'",
119  containerName<T>().c_str(),
122  pref.c_str()));
123  in >> stored_K;
124  if (stored_K !=
125  std::string(
128  "Error: serialized container %s key type %s != %s",
129  containerName<T>().c_str(), stored_K.c_str(),
131  in >> stored_V;
132  if (stored_V !=
133  std::string(
136  "Error: serialized container %s value type %s != %s",
137  containerName<T>().c_str(), stored_V.c_str(),
139  const uint32_t n = in.ReadAs<uint32_t>();
140  for (uint32_t i = 0; i < n; i++)
141  {
142  typename T::key_type key_obj;
143  in >> key_obj;
144  /* Create an pair (Key, empty), then read directly into the
145  * ".second": */
146  typename T::iterator it_new = obj.insert(
147  obj.end(), std::make_pair(key_obj, typename T::mapped_type()));
148  in >> it_new->second;
149  }
150  return in;
151 }
152 
153 #define MRPTSTL_SERIALIZABLE_SIMPLE_ASSOC_CONTAINER(CONTAINER) \
154  /** Template method to serialize an associative STL container */ \
155  template <class K, class _Pr, class _Alloc> \
156  CArchive& operator<<(CArchive& out, const CONTAINER<K, _Pr, _Alloc>& obj) \
157  { \
158  out << std::string(#CONTAINER) << mrpt::typemeta::TTypeName<K>::get(); \
159  out.WriteAs<uint32_t>(obj.size()); \
160  for (typename CONTAINER<K, _Pr, _Alloc>::const_iterator it = \
161  obj.begin(); \
162  it != obj.end(); ++it) \
163  out << *it; \
164  return out; \
165  } \
166  /** Template method to deserialize an associative STL container */ \
167  template <class K, class _Pr, class _Alloc> \
168  CArchive& operator>>(CArchive& in, CONTAINER<K, _Pr, _Alloc>& obj) \
169  { \
170  obj.clear(); \
171  std::string pref, stored_K; \
172  in >> pref; \
173  if (pref != #CONTAINER) \
174  THROW_EXCEPTION(format( \
175  "Error: serialized container %s<%s>'s preamble is wrong: " \
176  "'%s'", \
177  #CONTAINER, mrpt::typemeta::TTypeName<K>::get().c_str(), \
178  pref.c_str())); \
179  in >> stored_K; \
180  if (stored_K != \
181  std::string(mrpt::typemeta::TTypeName<K>::get().c_str())) \
182  THROW_EXCEPTION(format( \
183  "Error: serialized container %s key type %s != %s", \
184  #CONTAINER, stored_K.c_str(), \
185  mrpt::typemeta::TTypeName<K>::get().c_str())); \
186  const uint32_t n = in.ReadAs<uint32_t>(); \
187  for (uint32_t i = 0; i < n; i++) \
188  { \
189  K key_obj; \
190  in >> key_obj; \
191  obj.insert(key_obj); \
192  } \
193  return in; \
194  }
195 
199 
202 
203 /** Template method to serialize a std::array<T,N> */
204 template <class T, size_t N>
205 CArchive& operator<<(CArchive& out, const std::array<T, N>& obj)
206 {
207  out << std::string("std::array") << static_cast<uint32_t>(N)
209  std::for_each(
210  obj.begin(), obj.end(), metaprogramming::ObjectWriteToStream(&out));
211  return out;
212 }
213 
214 /** Template method to deserialize a std::array<T,N> */
215 template <class T, size_t N>
216 CArchive& operator>>(CArchive& in, std::array<T, N>& obj)
217 {
218  std::string pref, stored_T;
219  uint32_t stored_N;
220  in >> pref >> stored_N;
221  if (pref != "std::array" || stored_N != N)
223  "Error: serialized container %s's preambles is wrong: "
224  "'%s'",
225  mrpt::typemeta::TTypeName<std::array<T, N>>::get().c_str(),
226  pref.c_str());
227  in >> stored_T;
228  if (stored_T != std::string(mrpt::typemeta::TTypeName<T>::get().c_str()))
230  "Error: serialized container std::array< %s != %s >",
231  stored_T.c_str(), mrpt::typemeta::TTypeName<T>::get().c_str());
232  std::for_each(
233  obj.begin(), obj.end(), metaprogramming::ObjectReadFromStream(&in));
234  return in;
235 }
236 
237 /** Template method to serialize a STL pair */
238 template <class T1, class T2>
239 CArchive& operator<<(CArchive& out, const std::pair<T1, T2>& obj)
240 {
241  out << std::string("std::pair") << mrpt::typemeta::TTypeName<T1>::get()
243  out << obj.first << obj.second;
244  return out;
245 }
246 /** Template method to deserialize a STL pair */
247 template <class T1, class T2>
248 CArchive& operator>>(CArchive& in, std::pair<T1, T2>& obj)
249 {
250  std::string pref, stored_K, stored_V;
251  in >> pref;
252  if (pref != "std::pair")
254  "Error: serialized std::pair<%s,%s>'s preamble is wrong: '%s'",
256  mrpt::typemeta::TTypeName<T2>::get().c_str(), pref.c_str()));
257  in >> stored_K;
258  if (stored_K != std::string(mrpt::typemeta::TTypeName<T1>::get().c_str()))
260  "Error: serialized std::pair first type %s != %s", stored_K.c_str(),
262  in >> stored_V;
263  if (stored_V != std::string(mrpt::typemeta::TTypeName<T2>::get().c_str()))
265  "Error: serialized std::pair second type %s != %s",
266  stored_V.c_str(), mrpt::typemeta::TTypeName<T2>::get().c_str()));
267  in >> obj.first >> obj.second;
268  return in;
269 }
270 
271 /** @} */ // end of grouping
272 } // namespace mrpt::serialization
std::string containerName()
An object for reading objects from a stream, intended for being used in STL algorithms.
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
std::string std::string format(std::string_view fmt, ARGS &&... args)
Definition: format.h:26
std::is_same< T, typename std::multimap< typename T::key_type, typename T::mapped_type, typename T::key_compare, typename T::allocator_type > > is_multimap
A template to obtain the type of its argument as a string at compile time.
Definition: TTypeName.h:69
std::is_same< typename T::value_type, std::pair< const typename T::key_type, typename T::mapped_type > > is_map_like
#define MRPTSTL_SERIALIZABLE_SEQ_CONTAINER(CONTAINER)
CArchive & operator>>(CArchive &s, mrpt::aligned_std_vector< float > &a)
Definition: CArchive.cpp:250
std::is_same< T, typename std::map< typename T::key_type, typename T::mapped_type, typename T::key_compare, typename T::allocator_type > > is_map
Virtual base class for "archives": classes abstracting I/O streams.
Definition: CArchive.h:54
mrpt::vision::TStereoCalibResults out
CArchive & operator<<(CArchive &s, const mrpt::aligned_std_vector< float > &a)
Definition: CArchive.cpp:199
#define MRPTSTL_SERIALIZABLE_SIMPLE_ASSOC_CONTAINER(CONTAINER)
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
Definition: exceptions.h:69
static constexpr auto get()
Definition: TTypeName.h:71
An object for writing objects to a stream, intended for being used in STL algorithms.



Page generated by Doxygen 1.8.14 for MRPT 2.0.2 Git: 9b4fd2465 Mon May 4 16:59:08 2020 +0200 at lun may 4 17:26:07 CEST 2020