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(MSGPACK_PP_VARIADICS)
18 #define MSGPACK_PP_VARIADICS
19 #endif
20 
21 #include <msgpack/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& pk) const \
31  { \
32  msgpack::type::make_define_array(__VA_ARGS__).msgpack_pack(pk); \
33  } \
34  void msgpack_unpack(msgpack::object const& o) \
35  { \
36  msgpack::type::make_define_array(__VA_ARGS__).msgpack_unpack(o); \
37  }\
38  template <typename MSGPACK_OBJECT> \
39  void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone& z) const \
40  { \
41  msgpack::type::make_define_array(__VA_ARGS__).msgpack_object(o, z); \
42  }
43 
44 #define MSGPACK_BASE_ARRAY(base) (*const_cast<base *>(static_cast<base const*>(this)))
45 
46 #define MSGPACK_DEFINE_MAP_EACH_PROC(r, data, elem) \
47  MSGPACK_PP_IF( \
48  MSGPACK_PP_IS_BEGIN_PARENS(elem), \
49  elem, \
50  (MSGPACK_PP_STRINGIZE(elem))(elem) \
51  )
52 
53 #define MSGPACK_DEFINE_MAP_IMPL(...) \
54  MSGPACK_PP_SEQ_TO_TUPLE( \
55  MSGPACK_PP_SEQ_FOR_EACH( \
56  MSGPACK_DEFINE_MAP_EACH_PROC, \
57  0, \
58  MSGPACK_PP_VARIADIC_TO_SEQ(__VA_ARGS__) \
59  ) \
60  )
61 
62 #define MSGPACK_DEFINE_MAP(...) \
63  template <typename Packer> \
64  void msgpack_pack(Packer& pk) const \
65  { \
66  msgpack::type::make_define_map \
67  MSGPACK_DEFINE_MAP_IMPL(__VA_ARGS__) \
68  .msgpack_pack(pk); \
69  } \
70  void msgpack_unpack(msgpack::object const& o) \
71  { \
72  msgpack::type::make_define_map \
73  MSGPACK_DEFINE_MAP_IMPL(__VA_ARGS__) \
74  .msgpack_unpack(o); \
75  }\
76  template <typename MSGPACK_OBJECT> \
77  void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone& z) const \
78  { \
79  msgpack::type::make_define_map \
80  MSGPACK_DEFINE_MAP_IMPL(__VA_ARGS__) \
81  .msgpack_object(o, z); \
82  }
83 
84 #define MSGPACK_BASE_MAP(base) \
85  (MSGPACK_PP_STRINGIZE(base))(*const_cast<base *>(static_cast<base const*>(this)))
86 
87 // MSGPACK_ADD_ENUM must be used in the global namespace.
88 #define MSGPACK_ADD_ENUM(enum_name) \
89  namespace msgpack { \
90  \
91  MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) { \
92  \
93  namespace adaptor { \
94  template<> \
95  struct convert<enum_name> { \
96  msgpack::object const& operator()(msgpack::object const& o, enum_name& v) const { \
97  msgpack::underlying_type<enum_name>::type tmp; \
98  msgpack::operator>>(o, tmp); \
99  v = static_cast<enum_name>(tmp); \
100  return o; \
101  } \
102  }; \
103  template<> \
104  struct object<enum_name> { \
105  void operator()(msgpack::object& o, const enum_name& v) const { \
106  msgpack::underlying_type<enum_name>::type tmp = static_cast<msgpack::underlying_type<enum_name>::type>(v); \
107  msgpack::operator<<(o, tmp); \
108  } \
109  }; \
110  template<> \
111  struct object_with_zone<enum_name> { \
112  void operator()(msgpack::object::with_zone& o, const enum_name& v) const { \
113  msgpack::underlying_type<enum_name>::type tmp = static_cast<msgpack::underlying_type<enum_name>::type>(v); \
114  msgpack::operator<<(o, tmp); \
115  } \
116  }; \
117  template <> \
118  struct pack<enum_name> { \
119  template <typename Stream> \
120  msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const enum_name& v) const { \
121  return msgpack::operator<<(o, static_cast<msgpack::underlying_type<enum_name>::type>(v)); \
122  } \
123  }; \
124  } \
125  \
126  } \
127  \
128  }
129 
130 #if defined(MSGPACK_USE_DEFINE_MAP)
131 #define MSGPACK_DEFINE MSGPACK_DEFINE_MAP
132 #define MSGPACK_BASE MSGPACK_BASE_MAP
133 #else // defined(MSGPACK_USE_DEFINE_MAP)
134 #define MSGPACK_DEFINE MSGPACK_DEFINE_ARRAY
135 #define MSGPACK_BASE MSGPACK_BASE_ARRAY
136 #endif // defined(MSGPACK_USE_DEFINE_MAP)
137 
138 
141 
142 #endif // MSGPACK_DEFINE_DECL_HPP