| // |
| // MessagePack for C++ static resolution routine |
| // |
| // Copyright (C) 2015 KONDO Takatoshi |
| // |
| // Distributed under the Boost Software License, Version 1.0. |
| // (See accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| // |
| #ifndef MSGPACK_CPP03_DEFINE_MAP_HPP |
| #define MSGPACK_CPP03_DEFINE_MAP_HPP |
| |
| // BOOST_PP_VARIADICS is defined in boost/preprocessor/config/config.hpp |
| // http://www.boost.org/libs/preprocessor/doc/ref/variadics.html |
| // However, supporting compiler detection is not complete. msgpack-c requires |
| // variadic macro arguments support. So BOOST_PP_VARIADICS is defined here explicitly. |
| #if !defined(MSGPACK_PP_VARIADICS) |
| #define MSGPACK_PP_VARIADICS |
| #endif |
| |
| #include <msgpack/preprocessor.hpp> |
| |
| #include "msgpack/versioning.hpp" |
| #include "msgpack/adaptor/msgpack_tuple.hpp" |
| #include "msgpack/adaptor/adaptor_base.hpp" |
| #include "msgpack/object_fwd.hpp" |
| |
| #define MSGPACK_DEFINE_MAP_EACH_PROC(r, data, elem) \ |
| MSGPACK_PP_IF( \ |
| MSGPACK_PP_IS_BEGIN_PARENS(elem), \ |
| elem, \ |
| (MSGPACK_PP_STRINGIZE(elem))(elem) \ |
| ) |
| |
| #define MSGPACK_DEFINE_MAP_IMPL(...) \ |
| MSGPACK_PP_SEQ_TO_TUPLE( \ |
| MSGPACK_PP_SEQ_FOR_EACH( \ |
| MSGPACK_DEFINE_MAP_EACH_PROC, \ |
| 0, \ |
| MSGPACK_PP_VARIADIC_TO_SEQ(__VA_ARGS__) \ |
| ) \ |
| ) |
| |
| #define MSGPACK_DEFINE_MAP(...) \ |
| template <typename Packer> \ |
| void msgpack_pack(Packer& pk) const \ |
| { \ |
| msgpack::type::make_define_map \ |
| MSGPACK_DEFINE_MAP_IMPL(__VA_ARGS__) \ |
| .msgpack_pack(pk); \ |
| } \ |
| void msgpack_unpack(msgpack::object const& o) \ |
| { \ |
| msgpack::type::make_define_map \ |
| MSGPACK_DEFINE_MAP_IMPL(__VA_ARGS__) \ |
| .msgpack_unpack(o); \ |
| }\ |
| template <typename MSGPACK_OBJECT> \ |
| void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone& z) const \ |
| { \ |
| msgpack::type::make_define_map \ |
| MSGPACK_DEFINE_MAP_IMPL(__VA_ARGS__) \ |
| .msgpack_object(o, z); \ |
| } |
| |
| #define MSGPACK_BASE_MAP(base) \ |
| (MSGPACK_PP_STRINGIZE(base))(*const_cast<base *>(static_cast<base const*>(this))) |
| |
| namespace msgpack { |
| /// @cond |
| MSGPACK_API_VERSION_NAMESPACE(v1) { |
| /// @endcond |
| namespace type { |
| |
| /// @cond |
| <% GENERATION_LIMIT = 31 %> |
| template <typename A0 = void<%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%> = void<%}%>> |
| struct define_map; |
| /// @endcond |
| |
| template <> |
| struct define_map<> { |
| template <typename Packer> |
| void msgpack_pack(Packer& pk) const |
| { |
| pk.pack_map(0); |
| } |
| void msgpack_unpack(msgpack::object const& o) const |
| { |
| if(o.type != msgpack::type::MAP) { throw msgpack::type_error(); } |
| } |
| void msgpack_object(msgpack::object* o, msgpack::zone&) const |
| { |
| o->type = msgpack::type::MAP; |
| o->via.map.ptr = nullptr; |
| o->via.map.size = 0; |
| } |
| }; |
| |
| /// @cond |
| <%1.step(GENERATION_LIMIT+1,2) {|i|%> |
| template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> |
| struct define_map<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> { |
| define_map(A0& _a0<%1.upto(i) {|j|%>, A<%=j%>& _a<%=j%><%}%>) : |
| a0(_a0)<%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {} |
| template <typename Packer> |
| void msgpack_pack(Packer& pk) const |
| { |
| pk.pack_map(<%=(i+1)/2%>); |
| <%0.upto(i) {|j|%> |
| pk.pack(a<%=j%>);<%}%> |
| } |
| void msgpack_unpack(msgpack::object const& o) const |
| { |
| if(o.type != msgpack::type::MAP) { throw msgpack::type_error(); } |
| std::map<std::string, msgpack::object const*> kvmap; |
| for (uint32_t i = 0; i < o.via.map.size; ++i) { |
| kvmap.insert( |
| std::map<std::string, msgpack::object const*>::value_type( |
| std::string( |
| o.via.map.ptr[i].key.via.str.ptr, |
| o.via.map.ptr[i].key.via.str.size), |
| &o.via.map.ptr[i].val |
| ) |
| ); |
| } |
| <%0.step(i,2) {|j|%> |
| { |
| std::map<std::string, msgpack::object const*>::const_iterator it = kvmap.find(a<%=j%>); |
| if (it != kvmap.end()) { |
| it->second->convert(a<%=j+1%>); |
| } |
| } |
| <%}%> |
| } |
| void msgpack_object(msgpack::object* o, msgpack::zone& z) const |
| { |
| o->type = msgpack::type::MAP; |
| o->via.map.ptr = static_cast<msgpack::object_kv*>(z.allocate_align(sizeof(msgpack::object_kv)*<%=(i+1)/2%>)); |
| o->via.map.size = <%=(i+1)/2%>; |
| <%0.step(i,2) {|j|%> |
| o->via.map.ptr[<%=j/2%>].key = msgpack::object(a<%=j%>, z); |
| o->via.map.ptr[<%=j/2%>].val = msgpack::object(a<%=j+1%>, z); |
| <%}%> |
| } |
| <%0.upto(i) {|j|%> |
| A<%=j%>& a<%=j%>;<%}%> |
| }; |
| <%}%> |
| /// @endcond |
| |
| inline define_map<> make_define_map() |
| { |
| return define_map<>(); |
| } |
| |
| /// @cond |
| <%0.upto(GENERATION_LIMIT) {|i|%> |
| template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> |
| inline define_map<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_define_map(A0& a0<%1.upto(i) {|j|%>, A<%=j%>& a<%=j%><%}%>) |
| { |
| return define_map<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>); |
| } |
| <%}%> |
| /// @endcond |
| |
| } // namespace type |
| /// @cond |
| } // MSGPACK_API_VERSION_NAMESPACE(v1) |
| /// @endcond |
| } // namespace msgpack |
| |
| #endif // MSGPACK_CPP03_DEFINE_MAP_HPP |