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