| // |
| // MessagePack for C++ static resolution routine |
| // |
| // Copyright (C) 2008-2009 FURUHASHI Sadayuki |
| // |
| // 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_ARRAY_HPP |
| #define MSGPACK_CPP03_DEFINE_ARRAY_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_ARRAY(...) \ |
| template <typename Packer> \ |
| void msgpack_pack(Packer& pk) const \ |
| { \ |
| msgpack::type::make_define_array(__VA_ARGS__).msgpack_pack(pk); \ |
| } \ |
| void msgpack_unpack(msgpack::object const& o) \ |
| { \ |
| msgpack::type::make_define_array(__VA_ARGS__).msgpack_unpack(o); \ |
| }\ |
| template <typename MSGPACK_OBJECT> \ |
| void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone& z) const \ |
| { \ |
| msgpack::type::make_define_array(__VA_ARGS__).msgpack_object(o, z); \ |
| } |
| |
| #define MSGPACK_BASE_ARRAY(base) (*const_cast<base *>(static_cast<base const*>(this))) |
| |
| // MSGPACK_ADD_ENUM must be used in the global namespace. |
| #define MSGPACK_ADD_ENUM(enum_name) \ |
| namespace msgpack { \ |
| /** @cond */ \ |
| MSGPACK_API_VERSION_NAMESPACE(v1) { \ |
| /** @endcond */ \ |
| namespace adaptor { \ |
| template<> \ |
| struct convert<enum_name> { \ |
| msgpack::object const& operator()(msgpack::object const& o, enum_name& v) const {\ |
| int tmp; \ |
| o >> tmp; \ |
| v = static_cast<enum_name>(tmp); \ |
| return o; \ |
| } \ |
| }; \ |
| template<> \ |
| struct object<enum_name> { \ |
| void operator()(msgpack::object& o, const enum_name& v) const {\ |
| o << static_cast<int>(v); \ |
| } \ |
| }; \ |
| template<> \ |
| struct object_with_zone<enum_name> { \ |
| void operator()(msgpack::object::with_zone& o, const enum_name& v) const { \ |
| o << static_cast<int>(v); \ |
| } \ |
| }; \ |
| template<> \ |
| struct pack<enum_name> { \ |
| template <typename Stream> \ |
| msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const enum_name& v) const { \ |
| return o << static_cast<int>(v); \ |
| } \ |
| }; \ |
| } \ |
| /** @cond */ \ |
| } \ |
| /** @endcond */ \ |
| } |
| |
| 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_array; |
| /// @endcond |
| |
| template <> |
| struct define_array<> { |
| typedef define_array<> value_type; |
| typedef tuple<> tuple_type; |
| template <typename Packer> |
| void msgpack_pack(Packer& pk) const |
| { |
| pk.pack_array(0); |
| } |
| void msgpack_unpack(msgpack::object const& o) |
| { |
| if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } |
| } |
| void msgpack_object(msgpack::object* o, msgpack::zone&) const |
| { |
| o->type = msgpack::type::ARRAY; |
| o->via.array.ptr = nullptr; |
| o->via.array.size = 0; |
| } |
| }; |
| |
| /// @cond |
| <%0.upto(GENERATION_LIMIT) {|i|%> |
| template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> |
| struct define_array<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> { |
| typedef define_array<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> value_type; |
| typedef tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> tuple_type; |
| define_array(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_array(<%=i+1%>); |
| <%0.upto(i) {|j|%> |
| pk.pack(a<%=j%>);<%}%> |
| } |
| void msgpack_unpack(msgpack::object const& o) |
| { |
| if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } |
| const size_t size = o.via.array.size; |
| if(size > 0) { |
| msgpack::object *ptr = o.via.array.ptr; |
| switch(size) { |
| default:<%(i).downto(0) {|j|%> |
| case <%=j+1%>: ptr[<%=j%>].convert(a<%=j%>);<%}%> |
| } |
| } |
| } |
| void msgpack_object(msgpack::object* o, msgpack::zone& z) const |
| { |
| o->type = msgpack::type::ARRAY; |
| o->via.array.ptr = static_cast<msgpack::object*>(z.allocate_align(sizeof(msgpack::object)*<%=i+1%>)); |
| o->via.array.size = <%=i+1%>; |
| <%0.upto(i) {|j|%> |
| o->via.array.ptr[<%=j%>] = msgpack::object(a<%=j%>, z);<%}%> |
| } |
| <%0.upto(i) {|j|%> |
| A<%=j%>& a<%=j%>;<%}%> |
| }; |
| <%}%> |
| /// @endcond |
| |
| inline define_array<> make_define_array() |
| { |
| return define_array<>(); |
| } |
| |
| /// @cond |
| <%0.upto(GENERATION_LIMIT) {|i|%> |
| template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> |
| inline define_array<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_define_array(A0& a0<%1.upto(i) {|j|%>, A<%=j%>& a<%=j%><%}%>) |
| { |
| return define_array<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_ARRAY_HPP |