MessagePack for C++
array_ref.hpp
Go to the documentation of this file.
1 //
2 // MessagePack for C++ static resolution routine
3 //
4 // Copyright (C) 2008-2016 FURUHASHI Sadayuki
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_ARRAY_REF_HPP
11 #define MSGPACK_V1_TYPE_ARRAY_REF_HPP
12 
15 #include "msgpack/cpp_config.hpp"
16 #include <cstring>
17 #include <string>
18 
19 namespace msgpack {
20 
24 
25 namespace type {
26 
27 template <typename T>
28 struct array_ref {
30  array_ref(T& t) : data(&t) {}
31 
32  T* data;
33 
34  std::size_t size() const {
35  return data->size();
36  }
37 
38  template <typename U>
39  bool operator==(array_ref<U> const& t) const {
40  return *data == *t.data;
41  }
42  template <typename U>
43  bool operator!=(array_ref<U> const& t) const {
44  return !(*data == *t.data);
45  }
46  template <typename U>
47  bool operator< (array_ref<U> const& t) const
48  {
49  return *data < *t.data;
50  }
51  template <typename U>
52  bool operator> (array_ref<U> const& t) const
53  {
54  return *t.data < *data;
55  }
56  template <typename U>
57  bool operator<= (array_ref<U> const& t) const
58  {
59  return !(*t.data < *data);
60  }
61  template <typename U>
62  bool operator>= (array_ref<U> const& t) const
63  {
64  return !(*data < *t.data);
65  }
66 };
67 
68 template <typename T, std::size_t N>
69 struct array_ref<T[N]> {
71  array_ref(T(&t)[N]) : data(t) {}
72 
73  T* data;
74 
75  std::size_t size() const {
76  return N;
77  }
78 
79  template <typename U>
80  bool operator==(array_ref<U> const& t) const {
81  if (N != t.size()) return false;
82  T const* pself = data;
83  U const* pother = t.data;
84  for (; pself != &data[N]; ++pself, ++pother) {
85  if (*pself != *pother) return false;
86  }
87  return true;
88  }
89  template <typename U>
90  bool operator!=(array_ref<U> const& t) const {
91  return !(*this == t);
92  }
93  template <typename U>
94  bool operator< (array_ref<U> const& t) const
95  {
96  T const* pself = data;
97  U const* pother = t.data;
98  for (; pself != &data[N] && pother != t.data[t.size()]; ++pself, ++pother) {
99  if (*pself < *pother) return true;
100  }
101  if (N < t.size()) return true;
102  return false;
103  }
104  template <typename U>
105  bool operator> (array_ref<U> const& t) const
106  {
107  return t.data < data;
108  }
109  template <typename U>
110  bool operator<= (array_ref<U> const& t) const
111  {
112  return !(t.data < data);
113  }
114  template <typename U>
115  bool operator>= (array_ref<U> const& t) const
116  {
117  return !(data < t.data);
118  }
119 };
120 
121 template <typename T>
122 inline
123 typename msgpack::enable_if<
126 >::type
127 make_array_ref(const T& t) {
128  return array_ref<T const>(t);
129 }
130 
131 template <typename T>
132 inline
133 typename msgpack::enable_if<
136 >::type
138  return array_ref<T>(t);
139 }
140 
141 template <typename T, std::size_t N>
142 inline array_ref<const T[N]> make_array_ref(const T(&t)[N]) {
143  return array_ref<const T[N]>(t);
144 }
145 
146 template <typename T, std::size_t N>
147 inline array_ref<T[N]> make_array_ref(T(&t)[N]) {
148  return array_ref<T[N]>(t);
149 }
150 
151 } // namespace type
152 
153 namespace adaptor {
154 
155 template <typename T>
158  if (!v.data) { throw msgpack::type_error(); }
159  if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
160  if (v.size() < o.via.bin.size) { throw msgpack::type_error(); }
161  if (o.via.array.size > 0) {
162  msgpack::object* p = o.via.array.ptr;
163  msgpack::object* const pend = o.via.array.ptr + o.via.array.size;
164  typename T::iterator it = v.data->begin();
165  do {
166  p->convert(*it);
167  ++p;
168  ++it;
169  } while(p < pend);
170  }
171  return o;
172  }
173 };
174 
175 template <typename T, std::size_t N>
176 struct convert<msgpack::type::array_ref<T[N]> > {
178  if (!v.data) { throw msgpack::type_error(); }
179  if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
180  if (v.size() < o.via.bin.size) { throw msgpack::type_error(); }
181  if (o.via.array.size > 0) {
182  msgpack::object* p = o.via.array.ptr;
183  msgpack::object* const pend = o.via.array.ptr + o.via.array.size;
184  T* it = v.data;
185  do {
186  p->convert(*it);
187  ++p;
188  ++it;
189  } while(p < pend);
190  }
191  return o;
192  }
193 };
194 
195 template <typename T>
196 struct convert<msgpack::type::array_ref<std::vector<T> > > {
197  msgpack::object const& operator()(msgpack::object const& o, msgpack::type::array_ref<std::vector<T> >& v) const {
198  if (!v.data) { throw msgpack::type_error(); }
199  if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
200  v.data->resize(o.via.bin.size);
201  if (o.via.array.size > 0) {
202  msgpack::object* p = o.via.array.ptr;
203  msgpack::object* const pend = o.via.array.ptr + o.via.array.size;
204  typename std::vector<T>::iterator it = v.data->begin();
205  do {
206  p->convert(*it);
207  ++p;
208  ++it;
209  } while(p < pend);
210  }
211  return o;
212  }
213 };
214 
215 template <typename T>
217  template <typename Stream>
219  if (!v.data) { throw msgpack::type_error(); }
220  uint32_t size = checked_get_container_size(v.size());
221  o.pack_array(size);
222  for (typename T::const_iterator it(v.data->begin()), it_end(v.data->end());
223  it != it_end; ++it) {
224  o.pack(*it);
225  }
226  return o;
227  }
228 };
229 
230 template <typename T, std::size_t N>
231 struct pack<msgpack::type::array_ref<T[N]> > {
232  template <typename Stream>
234  if (!v.data) { throw msgpack::type_error(); }
235  uint32_t size = checked_get_container_size(v.size());
236  o.pack_array(size);
237  for (T const* it = v.data;
238  it != &v.data[v.size()]; ++it) {
239  o.pack(*it);
240  }
241  return o;
242  }
243 };
244 
245 template <typename T>
248  if (!v.data) { throw msgpack::type_error(); }
250  if (v.data->empty()) {
252  o.via.array.size = 0;
253  }
254  else {
255  uint32_t size = checked_get_container_size(v.size());
256  msgpack::object* p = static_cast<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object)*size));
257  msgpack::object* const pend = p + size;
258  o.via.array.ptr = p;
259  o.via.array.size = size;
260  typename T::const_iterator it(v.data->begin());
261  do {
262 #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
263 #pragma GCC diagnostic push
264 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
265 #endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
266  *p = msgpack::object(*it, o.zone);
267 #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
268 #pragma GCC diagnostic pop
269 #endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
270  ++p;
271  ++it;
272  } while(p < pend);
273  }
274  }
275 };
276 
277 template <typename T, std::size_t N>
280  if (!v.data) { throw msgpack::type_error(); }
282  uint32_t size = checked_get_container_size(v.size());
283  msgpack::object* p = static_cast<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object)*size));
284  msgpack::object* const pend = p + size;
285  o.via.array.ptr = p;
286  o.via.array.size = size;
287  T const* it = v.data;
288  do {
289  *p = msgpack::object(*it, o.zone);
290  ++p;
291  ++it;
292  } while(p < pend);
293  }
294 };
295 
296 
297 } // namespace adaptor
298 
300 } // MSGPACK_API_VERSION_NAMESPACE(v1)
302 
303 } // namespace msgpack
304 
305 #endif // MSGPACK_V1_TYPE_ARRAY_REF_HPP
T * data
Definition: array_ref.hpp:73
Definition: cpp_config_decl.hpp:71
uint32_t size
Definition: object_fwd.hpp:23
void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
Definition: cpp03_zone.hpp:236
std::size_t size() const
Definition: array_ref.hpp:75
bool operator==(array_ref< U > const &t) const
Definition: array_ref.hpp:80
uint32_t checked_get_container_size(T size)
Definition: check_container_size.hpp:55
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, const msgpack::type::array_ref< T > &v) const
Definition: array_ref.hpp:218
union_type via
Definition: object_fwd.hpp:93
T * data
Definition: array_ref.hpp:32
msgpack::object const & operator()(msgpack::object const &o, msgpack::type::array_ref< std::vector< T > > &v) const
Definition: array_ref.hpp:197
msgpack::zone & zone
Definition: object.hpp:36
msgpack::object * ptr
Definition: object_fwd.hpp:24
packer< Stream > & pack_array(uint32_t n)
Packing array header and size.
Definition: pack.hpp:1160
uint32_t size
Definition: object_fwd.hpp:38
Definition: adaptor_base.hpp:15
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, const msgpack::type::array_ref< T[N]> &v) const
Definition: array_ref.hpp:233
bool operator!=(array_ref< U > const &t) const
Definition: array_ref.hpp:43
Definition: object.hpp:34
packer< Stream > & pack(const T &v)
Packing function template.
bool operator==(array_ref< U > const &t) const
Definition: array_ref.hpp:39
Definition: array_ref.hpp:28
void operator()(msgpack::object::with_zone &o, const msgpack::type::array_ref< T[N]> &v) const
Definition: array_ref.hpp:279
array_ref(T(&t)[N])
Definition: array_ref.hpp:71
Definition: adaptor_base.hpp:43
Definition: object_fwd.hpp:236
array_ref()
Definition: array_ref.hpp:29
array_ref()
Definition: array_ref.hpp:70
Definition: adaptor_base.hpp:32
msgpack::object_array array
Definition: object_fwd.hpp:85
Definition: array_ref.hpp:69
Definition: cpp_config_decl.hpp:56
Object class that corresponding to MessagePack format object.
Definition: object_fwd.hpp:75
msgpack::object const & operator()(msgpack::object const &o, msgpack::type::array_ref< T > &v) const
Definition: array_ref.hpp:157
void operator()(msgpack::object::with_zone &o, const msgpack::type::array_ref< T > &v) const
Definition: array_ref.hpp:247
msgpack::type::object_type type
Definition: object_fwd.hpp:92
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58
Definition: object_fwd_decl.hpp:41
std::size_t size() const
Definition: array_ref.hpp:34
msgpack::enable_if< !msgpack::is_array< T const >::value, array_ref< T const >>::type make_array_ref(const T &t)
Definition: array_ref.hpp:127
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:538
The class template that supports continuous packing.
Definition: adaptor_base_decl.hpp:24
bool operator>(array_ref< U > const &t) const
Definition: array_ref.hpp:52
#define MSGPACK_NULLPTR
Definition: cpp_config_decl.hpp:35
bool operator!=(array_ref< U > const &t) const
Definition: array_ref.hpp:90
array_ref(T &t)
Definition: array_ref.hpp:30
msgpack::object const & operator()(msgpack::object const &o, msgpack::type::array_ref< T[N]> &v) const
Definition: array_ref.hpp:177
Definition: adaptor_base.hpp:27
bool operator>=(array_ref< U > const &t) const
Definition: array_ref.hpp:62
msgpack::object_bin bin
Definition: object_fwd.hpp:88