MessagePack for C++
cpp11_define_map.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_MAP_HPP
11 #define MSGPACK_CPP11_DEFINE_MAP_HPP
12 
13 // BOOST_PP_VARIADICS is defined in boost/preprocessor/config/config.hpp
14 // http://www.boost.org/libs/preprocessor/doc/ref/variadics.html
15 // However, supporting compiler detection is not complete. msgpack-c requires
16 // variadic macro arguments support. So BOOST_PP_VARIADICS is defined here explicitly.
17 #if !defined(MSGPACK_PP_VARIADICS)
18 #define MSGPACK_PP_VARIADICS
19 #endif
20 
21 #include <msgpack/preprocessor.hpp>
22 
23 #include "msgpack/versioning.hpp"
25 
26 // for MSGPACK_ADD_ENUM
27 #include "msgpack/adaptor/int.hpp"
28 
29 #include <type_traits>
30 #include <tuple>
31 
32 #define MSGPACK_DEFINE_MAP_EACH_PROC(r, data, elem) \
33  MSGPACK_PP_IF( \
34  MSGPACK_PP_IS_BEGIN_PARENS(elem), \
35  elem, \
36  (MSGPACK_PP_STRINGIZE(elem))(elem) \
37  )
38 
39 #define MSGPACK_DEFINE_MAP_IMPL(...) \
40  MSGPACK_PP_SEQ_TO_TUPLE( \
41  MSGPACK_PP_SEQ_FOR_EACH( \
42  MSGPACK_DEFINE_MAP_EACH_PROC, \
43  0, \
44  MSGPACK_PP_VARIADIC_TO_SEQ(__VA_ARGS__) \
45  ) \
46  )
47 
48 #define MSGPACK_DEFINE_MAP(...) \
49  template <typename Packer> \
50  void msgpack_pack(Packer& pk) const \
51  { \
52  msgpack::type::make_define_map \
53  MSGPACK_DEFINE_MAP_IMPL(__VA_ARGS__) \
54  .msgpack_pack(pk); \
55  } \
56  void msgpack_unpack(msgpack::object const& o) \
57  { \
58  msgpack::type::make_define_map \
59  MSGPACK_DEFINE_MAP_IMPL(__VA_ARGS__) \
60  .msgpack_unpack(o); \
61  }\
62  template <typename MSGPACK_OBJECT> \
63  void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone& z) const \
64  { \
65  msgpack::type::make_define_map \
66  MSGPACK_DEFINE_MAP_IMPL(__VA_ARGS__) \
67  .msgpack_object(o, z); \
68  }
69 
70 #define MSGPACK_BASE_MAP(base) \
71  (MSGPACK_PP_STRINGIZE(base))(*const_cast<base *>(static_cast<base const*>(this)))
72 
73 namespace msgpack {
77 namespace type {
78 
79 template <typename Tuple, std::size_t N>
81  template <typename Packer>
82  static void pack(Packer& pk, Tuple const& t) {
84  pk.pack(std::get<N-1>(t));
85  }
86  static void unpack(
87  msgpack::object const& o, Tuple const& t,
88  std::map<std::string, msgpack::object const*> const& kvmap) {
90  auto it = kvmap.find(std::get<N-2>(t));
91  if (it != kvmap.end()) {
92  it->second->convert(std::get<N-1>(t));
93  }
94  }
95  static void object(msgpack::object* o, msgpack::zone& z, Tuple const& t) {
97  o->via.map.ptr[(N-1)/2].key = msgpack::object(std::get<N-2>(t), z);
98  o->via.map.ptr[(N-1)/2].val = msgpack::object(std::get<N-1>(t), z);
99  }
100 };
101 
102 template <typename Tuple>
103 struct define_map_imp<Tuple, 0> {
104  template <typename Packer>
105  static void pack(Packer&, Tuple const&) {}
106  static void unpack(
107  msgpack::object const&, Tuple const&,
108  std::map<std::string, msgpack::object const*> const&) {}
109  static void object(msgpack::object*, msgpack::zone&, Tuple const&) {}
110 };
111 
112 template <typename... Args>
113 struct define_map {
114  define_map(Args&... args) :
115  a(args...) {}
116  template <typename Packer>
117  void msgpack_pack(Packer& pk) const
118  {
119  static_assert(sizeof...(Args) % 2 == 0, "");
120  pk.pack_map(sizeof...(Args) / 2);
121 
122  define_map_imp<std::tuple<Args&...>, sizeof...(Args)>::pack(pk, a);
123  }
124  void msgpack_unpack(msgpack::object const& o) const
125  {
126  if(o.type != msgpack::type::MAP) { throw msgpack::type_error(); }
127  std::map<std::string, msgpack::object const*> kvmap;
128  for (uint32_t i = 0; i < o.via.map.size; ++i) {
129  kvmap.emplace(
130  std::string(
131  o.via.map.ptr[i].key.via.str.ptr,
132  o.via.map.ptr[i].key.via.str.size),
133  &o.via.map.ptr[i].val);
134  }
135  define_map_imp<std::tuple<Args&...>, sizeof...(Args)>::unpack(o, a, kvmap);
136  }
138  {
139  static_assert(sizeof...(Args) % 2 == 0, "");
141  o->via.map.ptr = static_cast<msgpack::object_kv*>(z.allocate_align(sizeof(msgpack::object_kv)*sizeof...(Args)/2));
142  o->via.map.size = sizeof...(Args) / 2;
143 
144  define_map_imp<std::tuple<Args&...>, sizeof...(Args)>::object(o, z, a);
145  }
146 
147  std::tuple<Args&...> a;
148 };
149 
150 
151 template <typename... Args>
152 define_map<Args...> make_define_map(Args&... args)
153 {
154  return define_map<Args...>(args...);
155 }
156 
157 } // namespace type
159 } // MSGPACK_API_VERSION_NAMESPACE(v1)
161 } // namespace msgpack
162 
163 #endif // MSGPACK_CPP11_DEFINE_MAP_HPP
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58
Definition: cpp11_define_map.hpp:80
msgpack::object_kv * ptr
Definition: object_fwd.hpp:56
static void unpack(msgpack::object const &, Tuple const &, std::map< std::string, msgpack::object const *> const &)
Definition: cpp11_define_map.hpp:106
std::tuple< Args &... > a
Definition: cpp11_define_map.hpp:147
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 const &t, std::map< std::string, msgpack::object const *> const &kvmap)
Definition: cpp11_define_map.hpp:86
void msgpack_pack(Packer &pk) const
Definition: cpp11_define_map.hpp:117
static void object(msgpack::object *o, msgpack::zone &z, Tuple const &t)
Definition: cpp11_define_map.hpp:95
union_type via
Definition: object_fwd.hpp:123
Definition: cpp11_define_map.hpp:113
msgpack::object val
Definition: object_fwd.hpp:257
Definition: adaptor_base.hpp:15
const char * ptr
Definition: object_fwd.hpp:61
Definition: cpp03_zone.hpp:34
Definition: object_fwd.hpp:255
static void pack(Packer &, Tuple const &)
Definition: cpp11_define_map.hpp:105
void msgpack_unpack(msgpack::object const &o) const
Definition: cpp11_define_map.hpp:124
Definition: object_fwd.hpp:253
void msgpack_object(msgpack::object *o, msgpack::zone &z) const
Definition: cpp11_define_map.hpp:137
msgpack::object_map map
Definition: object_fwd.hpp:116
define_map make_define_map()
Definition: cpp03_define_map.hpp:2584
msgpack::object_str str
Definition: object_fwd.hpp:117
Object class that corresponding to MessagePack format object.
Definition: object_fwd.hpp:106
static void object(msgpack::object *, msgpack::zone &, Tuple const &)
Definition: cpp11_define_map.hpp:109
msgpack::type::object_type type
Definition: object_fwd.hpp:122
msgpack::object key
Definition: object_fwd.hpp:256
uint32_t size
Definition: object_fwd.hpp:55
Definition: object_fwd.hpp:40
static void pack(Packer &pk, Tuple const &t)
Definition: cpp11_define_map.hpp:82
uint32_t size
Definition: object_fwd.hpp:60
define_map(Args &... args)
Definition: cpp11_define_map.hpp:114