MessagePack for C++
define_decl.hpp
Go to the documentation of this file.
1 //
2 // MessagePack for C++ static resolution routine
3 //
4 // Copyright (C) 2016 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_DEFINE_DECL_HPP
11 #define MSGPACK_DEFINE_DECL_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(BOOST_PP_VARIADICS)
18 #define BOOST_PP_VARIADICS
19 #endif
20 
21 #include <boost/preprocessor.hpp>
22 
23 #include "msgpack/versioning.hpp"
24 
25 // for MSGPACK_ADD_ENUM
26 #include "msgpack/adaptor/int.hpp"
27 
28 #define MSGPACK_DEFINE_ARRAY(...) \
29  template <typename Packer> \
30  void msgpack_pack(Packer& msgpack_pk) const \
31  { \
32  msgpack::type::make_define_array(__VA_ARGS__).msgpack_pack(msgpack_pk); \
33  } \
34  void msgpack_unpack(msgpack::object const& msgpack_o) \
35  { \
36  msgpack::type::make_define_array(__VA_ARGS__).msgpack_unpack(msgpack_o); \
37  }\
38  template <typename MSGPACK_OBJECT> \
39  void msgpack_object(MSGPACK_OBJECT* msgpack_o, msgpack::zone& msgpack_z) const \
40  { \
41  msgpack::type::make_define_array(__VA_ARGS__).msgpack_object(msgpack_o, msgpack_z); \
42  }
43 
44 #define MSGPACK_BASE_ARRAY(base) (*const_cast<base *>(static_cast<base const*>(this)))
45 #define MSGPACK_NVP(name, value) (name) (value)
46 
47 #define MSGPACK_DEFINE_MAP_EACH_PROC(r, data, elem) \
48  BOOST_PP_IF( \
49  BOOST_PP_IS_BEGIN_PARENS(elem), \
50  elem, \
51  (BOOST_PP_STRINGIZE(elem))(elem) \
52  )
53 
54 #define MSGPACK_DEFINE_MAP_IMPL(...) \
55  BOOST_PP_SEQ_TO_TUPLE( \
56  BOOST_PP_SEQ_FOR_EACH( \
57  MSGPACK_DEFINE_MAP_EACH_PROC, \
58  0, \
59  BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) \
60  ) \
61  )
62 
63 #define MSGPACK_DEFINE_MAP(...) \
64  template <typename Packer> \
65  void msgpack_pack(Packer& msgpack_pk) const \
66  { \
67  msgpack::type::make_define_map \
68  MSGPACK_DEFINE_MAP_IMPL(__VA_ARGS__) \
69  .msgpack_pack(msgpack_pk); \
70  } \
71  void msgpack_unpack(msgpack::object const& msgpack_o) \
72  { \
73  msgpack::type::make_define_map \
74  MSGPACK_DEFINE_MAP_IMPL(__VA_ARGS__) \
75  .msgpack_unpack(msgpack_o); \
76  }\
77  template <typename MSGPACK_OBJECT> \
78  void msgpack_object(MSGPACK_OBJECT* msgpack_o, msgpack::zone& msgpack_z) const \
79  { \
80  msgpack::type::make_define_map \
81  MSGPACK_DEFINE_MAP_IMPL(__VA_ARGS__) \
82  .msgpack_object(msgpack_o, msgpack_z); \
83  }
84 
85 #define MSGPACK_BASE_MAP(base) \
86  (BOOST_PP_STRINGIZE(base))(*const_cast<base *>(static_cast<base const*>(this)))
87 
88 // MSGPACK_ADD_ENUM must be used in the global namespace.
89 #define MSGPACK_ADD_ENUM(enum_name) \
90  namespace msgpack { \
91  \
92  MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) { \
93  \
94  namespace adaptor { \
95  template<> \
96  struct convert<enum_name> { \
97  msgpack::object const& operator()(msgpack::object const& msgpack_o, enum_name& msgpack_v) const { \
98  msgpack::underlying_type<enum_name>::type tmp; \
99  msgpack::operator>>(msgpack_o, tmp); \
100  msgpack_v = static_cast<enum_name>(tmp); \
101  return msgpack_o; \
102  } \
103  }; \
104  template<> \
105  struct object<enum_name> { \
106  void operator()(msgpack::object& msgpack_o, const enum_name& msgpack_v) const { \
107  msgpack::underlying_type<enum_name>::type tmp = static_cast<msgpack::underlying_type<enum_name>::type>(msgpack_v); \
108  msgpack::operator<<(msgpack_o, tmp); \
109  } \
110  }; \
111  template<> \
112  struct object_with_zone<enum_name> { \
113  void operator()(msgpack::object::with_zone& msgpack_o, const enum_name& msgpack_v) const { \
114  msgpack::underlying_type<enum_name>::type tmp = static_cast<msgpack::underlying_type<enum_name>::type>(msgpack_v); \
115  msgpack::operator<<(msgpack_o, tmp); \
116  } \
117  }; \
118  template <> \
119  struct pack<enum_name> { \
120  template <typename Stream> \
121  msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& msgpack_o, const enum_name& msgpack_v) const { \
122  return msgpack::operator<<(msgpack_o, static_cast<msgpack::underlying_type<enum_name>::type>(msgpack_v)); \
123  } \
124  }; \
125  } \
126  \
127  } \
128  \
129  }
130 
131 #if defined(MSGPACK_USE_DEFINE_MAP)
132 #define MSGPACK_DEFINE MSGPACK_DEFINE_MAP
133 #define MSGPACK_BASE MSGPACK_BASE_MAP
134 #else // defined(MSGPACK_USE_DEFINE_MAP)
135 #define MSGPACK_DEFINE MSGPACK_DEFINE_ARRAY
136 #define MSGPACK_BASE MSGPACK_BASE_ARRAY
137 #endif // defined(MSGPACK_USE_DEFINE_MAP)
138 
139 
143 
144 #endif // MSGPACK_DEFINE_DECL_HPP