MessagePack for C++
cpp11_define_array.hpp
Go to the documentation of this file.
1 //
2 // MessagePack for C++ static resolution routine
3 //
4 // Copyright (C) 2008-2013 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_CPP11_DEFINE_ARRAY_HPP
11 #define MSGPACK_CPP11_DEFINE_ARRAY_HPP
12 
13 #include "msgpack/versioning.hpp"
15 
16 // for MSGPACK_ADD_ENUM
17 #include "msgpack/adaptor/int.hpp"
18 
19 #include <type_traits>
20 #include <tuple>
21 
22 #define MSGPACK_DEFINE_ARRAY(...) \
23  template <typename Packer> \
24  void msgpack_pack(Packer& pk) const \
25  { \
26  msgpack::type::make_define_array(__VA_ARGS__).msgpack_pack(pk); \
27  } \
28  void msgpack_unpack(msgpack::object const& o) \
29  { \
30  msgpack::type::make_define_array(__VA_ARGS__).msgpack_unpack(o); \
31  }\
32  template <typename MSGPACK_OBJECT> \
33  void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone& z) const \
34  { \
35  msgpack::type::make_define_array(__VA_ARGS__).msgpack_object(o, z); \
36  }
37 
38 #define MSGPACK_BASE_ARRAY(base) (*const_cast<base *>(static_cast<base const*>(this)))
39 
40 // MSGPACK_ADD_ENUM must be used in the global namespace.
41 #define MSGPACK_ADD_ENUM(enum_name) \
42  namespace msgpack { \
43  \
44  MSGPACK_API_VERSION_NAMESPACE(v1) { \
45  \
46  namespace adaptor { \
47  template<> \
48  struct convert<enum_name> { \
49  msgpack::object const& operator()(msgpack::object const& o, enum_name& v) const { \
50  std::underlying_type<enum_name>::type tmp; \
51  o >> tmp; \
52  v = static_cast<enum_name>(tmp); \
53  return o; \
54  } \
55  }; \
56  template<> \
57  struct object<enum_name> { \
58  void operator()(msgpack::object& o, const enum_name& v) const { \
59  auto tmp = static_cast<std::underlying_type<enum_name>::type>(v); \
60  o << tmp; \
61  } \
62  }; \
63  template<> \
64  struct object_with_zone<enum_name> { \
65  void operator()(msgpack::object::with_zone& o, const enum_name& v) const { \
66  auto tmp = static_cast<std::underlying_type<enum_name>::type>(v); \
67  o << tmp; \
68  } \
69  }; \
70  template <> \
71  struct pack<enum_name> { \
72  template <typename Stream> \
73  msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const enum_name& v) const { \
74  return o << static_cast<std::underlying_type<enum_name>::type>(v); \
75  } \
76  }; \
77  } \
78  \
79  } \
80  \
81  }
82 
83 namespace msgpack {
87 namespace type {
88 
89 template <typename Tuple, std::size_t N>
91  template <typename Packer>
92  static void pack(Packer& pk, Tuple const& t) {
94  pk.pack(std::get<N-1>(t));
95  }
96  static void unpack(msgpack::object const& o, Tuple& t) {
98  const size_t size = o.via.array.size;
99  if(size <= N-1) { return; }
100  o.via.array.ptr[N-1].convert(std::get<N-1>(t));
101  }
102  static void object(msgpack::object* o, msgpack::zone& z, Tuple const& t) {
104  o->via.array.ptr[N-1] = msgpack::object(std::get<N-1>(t), z);
105  }
106 };
107 
108 template <typename Tuple>
109 struct define_array_imp<Tuple, 1> {
110  template <typename Packer>
111  static void pack(Packer& pk, Tuple const& t) {
112  pk.pack(std::get<0>(t));
113  }
114  static void unpack(msgpack::object const& o, Tuple& t) {
115  const size_t size = o.via.array.size;
116  if(size <= 0) { return; }
117  o.via.array.ptr[0].convert(std::get<0>(t));
118  }
119  static void object(msgpack::object* o, msgpack::zone& z, Tuple const& t) {
120  o->via.array.ptr[0] = msgpack::object(std::get<0>(t), z);
121  }
122 };
123 
124 template <typename... Args>
125 struct define_array {
126  typedef define_array<Args...> value_type;
127  typedef std::tuple<Args...> tuple_type;
128  define_array(Args&... args) :
129  a(args...) {}
130  template <typename Packer>
131  void msgpack_pack(Packer& pk) const
132  {
133  pk.pack_array(sizeof...(Args));
134 
135  define_array_imp<std::tuple<Args&...>, sizeof...(Args)>::pack(pk, a);
136  }
138  {
139  if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
140 
141  define_array_imp<std::tuple<Args&...>, sizeof...(Args)>::unpack(o, a);
142  }
144  {
146  o->via.array.ptr = static_cast<msgpack::object*>(z.allocate_align(sizeof(msgpack::object)*sizeof...(Args)));
147  o->via.array.size = sizeof...(Args);
148 
149  define_array_imp<std::tuple<Args&...>, sizeof...(Args)>::object(o, z, a);
150  }
151 
152  std::tuple<Args&...> a;
153 };
154 
155 template <>
156 struct define_array<> {
158  typedef std::tuple<> tuple_type;
159  template <typename Packer>
160  void msgpack_pack(Packer& pk) const
161  {
162  pk.pack_array(0);
163  }
165  {
166  if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
167  }
169  {
171  o->via.array.ptr = NULL;
172  o->via.array.size = 0;
173  }
174 };
175 
177 {
178  return define_array<>();
179 }
180 
181 template <typename... Args>
182 inline define_array<Args...> make_define_array(Args&... args)
183 {
184  return define_array<Args...>(args...);
185 }
186 
187 } // namespace type
189 } // MSGPACK_API_VERSION_NAMESPACE(v1)
191 } // namespace msgpack
192 
193 #endif // MSGPACK_CPP11_DEFINE_ARRAY_HPP
T & convert(T &v) const
Convert the object.
Definition: object.hpp:520
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58
define_array make_define_array()
Definition: cpp03_define_array.hpp:3282
define_array< Args... > value_type
Definition: cpp11_define_array.hpp:126
uint32_t size
Definition: object_fwd.hpp:50
void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
Definition: cpp03_zone.hpp:248
static void unpack(msgpack::object const &o, Tuple &t)
Definition: cpp11_define_array.hpp:96
void msgpack_object(msgpack::object *o, msgpack::zone &) const
Definition: cpp11_define_array.hpp:168
std::tuple tuple_type
Definition: cpp11_define_array.hpp:158
union_type via
Definition: object_fwd.hpp:123
void msgpack_pack(Packer &pk) const
Definition: cpp11_define_array.hpp:131
Definition: cpp11_define_array.hpp:90
void msgpack_unpack(msgpack::object const &o)
Definition: cpp11_define_array.hpp:164
static void object(msgpack::object *o, msgpack::zone &z, Tuple const &t)
Definition: cpp11_define_array.hpp:102
Definition: cpp11_define_array.hpp:125
static void object(msgpack::object *o, msgpack::zone &z, Tuple const &t)
Definition: cpp11_define_array.hpp:119
msgpack::object * ptr
Definition: object_fwd.hpp:51
static void pack(Packer &pk, Tuple const &t)
Definition: cpp11_define_array.hpp:92
Definition: adaptor_base.hpp:15
Definition: cpp03_zone.hpp:34
void msgpack_pack(Packer &pk) const
Definition: cpp11_define_array.hpp:160
Definition: object_fwd.hpp:253
static void pack(Packer &pk, Tuple const &t)
Definition: cpp11_define_array.hpp:111
define_array(Args &... args)
Definition: cpp11_define_array.hpp:128
msgpack::object_array array
Definition: object_fwd.hpp:115
std::tuple< Args &... > a
Definition: cpp11_define_array.hpp:152
void msgpack_unpack(msgpack::object const &o)
Definition: cpp11_define_array.hpp:137
Object class that corresponding to MessagePack format object.
Definition: object_fwd.hpp:106
msgpack::type::object_type type
Definition: object_fwd.hpp:122
void msgpack_object(msgpack::object *o, msgpack::zone &z) const
Definition: cpp11_define_array.hpp:143
Definition: object_fwd.hpp:39
std::tuple< Args... > tuple_type
Definition: cpp11_define_array.hpp:127
static void unpack(msgpack::object const &o, Tuple &t)
Definition: cpp11_define_array.hpp:114
define_array value_type
Definition: cpp11_define_array.hpp:157
Definition: cpp03_define_array.hpp:90