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