MessagePack for C++
map.hpp
Go to the documentation of this file.
1 //
2 // MessagePack for C++ static resolution routine
3 //
4 // Copyright (C) 2008-2016 FURUHASHI Sadayuki and KONDO Takatoshi
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 //
10 #ifndef MSGPACK_V1_TYPE_MAP_HPP
11 #define MSGPACK_V1_TYPE_MAP_HPP
12 
13 #include "msgpack/versioning.hpp"
14 #include "msgpack/cpp_version.hpp"
17 
18 #include <map>
19 #include <vector>
20 
21 namespace msgpack {
22 
26 
27 namespace type {
28 
29 template <typename K, typename V, typename Compare, typename Alloc>
30 class assoc_vector : public std::vector< std::pair<K, V>, Alloc > {
31 #if !defined(MSGPACK_USE_CPP03)
32  using std::vector<std::pair<K, V>, Alloc>::vector;
33 #endif // !defined(MSGPACK_USE_CPP03)
34 };
35 
36 namespace detail {
37  template <typename K, typename V, typename Compare, typename Alloc>
38  struct pair_first_less {
39  bool operator() (const std::pair<K, V>& x, const std::pair<K, V>& y) const
40  { return Compare()(x.first, y.first); }
41  };
42 }
43 
44 } //namespace type
45 
46 namespace adaptor {
47 
48 #if !defined(MSGPACK_USE_CPP03)
49 
50 template <typename K, typename V, typename Compare, typename Alloc>
51 struct as<
52  type::assoc_vector<K, V, Compare, Alloc>,
53  typename std::enable_if<msgpack::has_as<K>::value || msgpack::has_as<V>::value>::type> {
55  if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
57  v.reserve(o.via.map.size);
59  msgpack::object_kv* const pend = o.via.map.ptr + o.via.map.size;
60  for (; p < pend; ++p) {
61  v.emplace_back(p->key.as<K>(), p->val.as<V>());
62  }
63  std::sort(v.begin(), v.end(), type::detail::pair_first_less<K, V, Compare, Alloc>());
64  return v;
65  }
66 };
67 
68 #endif // !defined(MSGPACK_USE_CPP03)
69 
70 template <typename K, typename V, typename Compare, typename Alloc>
71 struct convert<type::assoc_vector<K, V, Compare, Alloc> > {
73  if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
74  v.resize(o.via.map.size);
75  if (o.via.map.size != 0) {
77  msgpack::object_kv* const pend = o.via.map.ptr + o.via.map.size;
78  std::pair<K, V>* it(&v.front());
79  for (; p < pend; ++p, ++it) {
80  p->key.convert(it->first);
81  p->val.convert(it->second);
82  }
83  std::sort(v.begin(), v.end(), type::detail::pair_first_less<K, V, Compare, Alloc>());
84  }
85  return o;
86  }
87 };
88 
89 template <typename K, typename V, typename Compare, typename Alloc>
90 struct pack<type::assoc_vector<K, V, Compare, Alloc> > {
91  template <typename Stream>
93  uint32_t size = checked_get_container_size(v.size());
94  o.pack_map(size);
95  for (typename type::assoc_vector<K, V, Compare, Alloc>::const_iterator it(v.begin()), it_end(v.end());
96  it != it_end; ++it) {
97  o.pack(it->first);
98  o.pack(it->second);
99  }
100  return o;
101  }
102 };
103 
104 template <typename K, typename V, typename Compare, typename Alloc>
105 struct object_with_zone<type::assoc_vector<K, V, Compare, Alloc> > {
108  if (v.empty()) {
110  o.via.map.size = 0;
111  }
112  else {
113  uint32_t size = checked_get_container_size(v.size());
115  msgpack::object_kv* const pend = p + size;
116  o.via.map.ptr = p;
117  o.via.map.size = size;
119  do {
120  p->key = msgpack::object(it->first, o.zone);
121  p->val = msgpack::object(it->second, o.zone);
122  ++p;
123  ++it;
124  } while(p < pend);
125  }
126  }
127 };
128 
129 #if !defined(MSGPACK_USE_CPP03)
130 
131 template <typename K, typename V, typename Compare, typename Alloc>
132 struct as<
133  std::map<K, V, Compare, Alloc>,
134  typename std::enable_if<msgpack::has_as<K>::value || msgpack::has_as<V>::value>::type> {
135  std::map<K, V, Compare, Alloc> operator()(msgpack::object const& o) const {
136  if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
138  msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
139  std::map<K, V, Compare, Alloc> v;
140  for (; p != pend; ++p) {
141  v.emplace(p->key.as<K>(), p->val.as<V>());
142  }
143  return v;
144  }
145 };
146 
147 #endif // !defined(MSGPACK_USE_CPP03)
148 
149 template <typename K, typename V, typename Compare, typename Alloc>
150 struct convert<std::map<K, V, Compare, Alloc> > {
151  msgpack::object const& operator()(msgpack::object const& o, std::map<K, V, Compare, Alloc>& v) const {
152  if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
154  msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
155  std::map<K, V, Compare, Alloc> tmp;
156  for (; p != pend; ++p) {
157  K key;
158  p->key.convert(key);
159 #if MSGPACK_CPP_VERSION >= 201103L
160  p->val.convert(tmp[std::move(key)]);
161 #else
162  p->val.convert(tmp[key]);
163 #endif
164  }
165 #if MSGPACK_CPP_VERSION >= 201103L
166  v = std::move(tmp);
167 #else
168  tmp.swap(v);
169 #endif
170  return o;
171  }
172 };
173 
174 template <typename K, typename V, typename Compare, typename Alloc>
175 struct pack<std::map<K, V, Compare, Alloc> > {
176  template <typename Stream>
177  msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::map<K, V, Compare, Alloc>& v) const {
178  uint32_t size = checked_get_container_size(v.size());
179  o.pack_map(size);
180  for (typename std::map<K, V, Compare, Alloc>::const_iterator it(v.begin()), it_end(v.end());
181  it != it_end; ++it) {
182  o.pack(it->first);
183  o.pack(it->second);
184  }
185  return o;
186  }
187 };
188 
189 template <typename K, typename V, typename Compare, typename Alloc>
190 struct object_with_zone<std::map<K, V, Compare, Alloc> > {
191  void operator()(msgpack::object::with_zone& o, const std::map<K, V, Compare, Alloc>& v) const {
193  if (v.empty()) {
195  o.via.map.size = 0;
196  }
197  else {
198  uint32_t size = checked_get_container_size(v.size());
199 
201  msgpack::object_kv* const pend = p + size;
202  o.via.map.ptr = p;
203  o.via.map.size = size;
204  typename std::map<K, V, Compare, Alloc>::const_iterator it(v.begin());
205  do {
206 #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
207 #pragma GCC diagnostic push
208 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
209 #endif // defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
210  p->key = msgpack::object(it->first, o.zone);
211  p->val = msgpack::object(it->second, o.zone);
212 #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
213 #pragma GCC diagnostic pop
214 #endif // defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
215  ++p;
216  ++it;
217  } while(p < pend);
218  }
219  }
220 };
221 
222 #if !defined(MSGPACK_USE_CPP03)
223 
224 template <typename K, typename V, typename Compare, typename Alloc>
225 struct as<
226  std::multimap<K, V, Compare, Alloc>,
227  typename std::enable_if<msgpack::has_as<K>::value || msgpack::has_as<V>::value>::type> {
228  std::multimap<K, V, Compare, Alloc> operator()(msgpack::object const& o) const {
229  if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
231  msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
232  std::multimap<K, V, Compare, Alloc> v;
233  for (; p != pend; ++p) {
234  v.emplace(p->key.as<K>(), p->val.as<V>());
235  }
236  return v;
237  }
238 };
239 
240 #endif // !defined(MSGPACK_USE_CPP03)
241 
242 template <typename K, typename V, typename Compare, typename Alloc>
243 struct convert<std::multimap<K, V, Compare, Alloc> > {
244  msgpack::object const& operator()(msgpack::object const& o, std::multimap<K, V, Compare, Alloc>& v) const {
245  if (o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
247  msgpack::object_kv* const pend(o.via.map.ptr + o.via.map.size);
248  std::multimap<K, V, Compare, Alloc> tmp;
249  for (; p != pend; ++p) {
250  std::pair<K, V> value;
251  p->key.convert(value.first);
252  p->val.convert(value.second);
253 #if MSGPACK_CPP_VERSION >= 201103L
254  tmp.insert(std::move(value));
255 #else
256  tmp.insert(value);
257 #endif
258  }
259 #if MSGPACK_CPP_VERSION >= 201103L
260  v = std::move(tmp);
261 #else
262  tmp.swap(v);
263 #endif
264  return o;
265  }
266 };
267 
268 template <typename K, typename V, typename Compare, typename Alloc>
269 struct pack<std::multimap<K, V, Compare, Alloc> > {
270  template <typename Stream>
271  msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::multimap<K, V, Compare, Alloc>& v) const {
272  uint32_t size = checked_get_container_size(v.size());
273  o.pack_map(size);
274  for (typename std::multimap<K, V, Compare, Alloc>::const_iterator it(v.begin()), it_end(v.end());
275  it != it_end; ++it) {
276  o.pack(it->first);
277  o.pack(it->second);
278  }
279  return o;
280  }
281 };
282 
283 template <typename K, typename V, typename Compare, typename Alloc>
284 struct object_with_zone<std::multimap<K, V, Compare, Alloc> > {
285  void operator()(msgpack::object::with_zone& o, const std::multimap<K, V, Compare, Alloc>& v) const {
287  if (v.empty()) {
289  o.via.map.size = 0;
290  }
291  else {
292  uint32_t size = checked_get_container_size(v.size());
294  msgpack::object_kv* const pend = p + size;
295  o.via.map.ptr = p;
296  o.via.map.size = size;
297  typename std::multimap<K, V, Compare, Alloc>::const_iterator it(v.begin());
298  do {
299  p->key = msgpack::object(it->first, o.zone);
300  p->val = msgpack::object(it->second, o.zone);
301  ++p;
302  ++it;
303  } while(p < pend);
304  }
305  }
306 };
307 
308 } // namespace adaptor
309 
311 } // MSGPACK_API_VERSION_NAMESPACE(v1)
313 
314 } // namespace msgpack
315 
316 #endif // MSGPACK_V1_TYPE_MAP_HPP
The class template that supports continuous packing.
Definition: pack.hpp:33
packer< Stream > & pack_map(uint32_t n)
Packing map header and size.
Definition: pack.hpp:1213
packer< Stream > & pack(const T &v)
Packing function template.
Definition: map.hpp:30
Definition: object_fwd.hpp:231
void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
Definition: cpp03_zone.hpp:256
std::size_t size(T const &t)
Definition: size_equal_only.hpp:24
@ MAP
Definition: object_fwd_decl.hpp:41
Definition: adaptor_base.hpp:15
uint32_t checked_get_container_size(T size)
Definition: check_container_size.hpp:55
Definition: object_fwd_decl.hpp:61
msgpack::object const & operator()(msgpack::object const &o, std::map< K, V, Compare, Alloc > &v) const
Definition: map.hpp:151
msgpack::object const & operator()(msgpack::object const &o, std::multimap< K, V, Compare, Alloc > &v) const
Definition: map.hpp:244
msgpack::object const & operator()(msgpack::object const &o, type::assoc_vector< K, V, Compare, Alloc > &v) const
Definition: map.hpp:72
Definition: adaptor_base.hpp:27
void operator()(msgpack::object::with_zone &o, const std::map< K, V, Compare, Alloc > &v) const
Definition: map.hpp:191
void operator()(msgpack::object::with_zone &o, const std::multimap< K, V, Compare, Alloc > &v) const
Definition: map.hpp:285
void operator()(msgpack::object::with_zone &o, const type::assoc_vector< K, V, Compare, Alloc > &v) const
Definition: map.hpp:106
Definition: adaptor_base.hpp:43
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, const std::map< K, V, Compare, Alloc > &v) const
Definition: map.hpp:177
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, const std::multimap< K, V, Compare, Alloc > &v) const
Definition: map.hpp:271
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, const type::assoc_vector< K, V, Compare, Alloc > &v) const
Definition: map.hpp:92
Definition: adaptor_base.hpp:32
Definition: object.hpp:35
msgpack::zone & zone
Definition: object.hpp:37
Definition: object.hpp:30
msgpack::object val
Definition: object.hpp:32
msgpack::object key
Definition: object.hpp:31
uint32_t size
Definition: object_fwd.hpp:28
msgpack::object_kv * ptr
Definition: object_fwd.hpp:29
Object class that corresponding to MessagePack format object.
Definition: object_fwd.hpp:75
std::enable_if< msgpack::has_as< T >::value, T >::type as() const
Get value as T.
Definition: object.hpp:1121
union_type via
Definition: object_fwd.hpp:93
msgpack::enable_if< !msgpack::is_array< T >::value &&!msgpack::is_pointer< T >::value, T & >::type convert(T &v) const
Convert the object.
Definition: object.hpp:1071
msgpack::type::object_type type
Definition: object_fwd.hpp:92
bool operator()(const std::pair< K, V > &x, const std::pair< K, V > &y) const
Definition: map.hpp:39
msgpack::object_map map
Definition: object_fwd.hpp:86
#define MSGPACK_NULLPTR
Definition: cpp_config_decl.hpp:85
#define MSGPACK_ZONE_ALIGNOF(type)
Definition: cpp03_zone_decl.hpp:30
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:66