// // MessagePack for C++ static resolution routine // // Copyright (C) 2008-2013 FURUHASHI Sadayuki and 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_CPP11_DEFINE_ARRAY_HPP #define MSGPACK_CPP11_DEFINE_ARRAY_HPP #include "msgpack/versioning.hpp" #include "msgpack/adaptor/adaptor_base.hpp" // for MSGPACK_ADD_ENUM #include "msgpack/adaptor/int.hpp" #include #include #define MSGPACK_DEFINE_ARRAY(...) \ template \ 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 \ 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(static_cast(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 { \ msgpack::object const& operator()(msgpack::object const& o, enum_name& v) const { \ std::underlying_type::type tmp; \ o >> tmp; \ v = static_cast(tmp); \ return o; \ } \ }; \ template<> \ struct object { \ void operator()(msgpack::object& o, const enum_name& v) const { \ auto tmp = static_cast::type>(v); \ o << tmp; \ } \ }; \ template<> \ struct object_with_zone { \ void operator()(msgpack::object::with_zone& o, const enum_name& v) const { \ auto tmp = static_cast::type>(v); \ o << tmp; \ } \ }; \ template <> \ struct pack { \ template \ msgpack::packer& operator()(msgpack::packer& o, const enum_name& v) const { \ return o << static_cast::type>(v); \ } \ }; \ } \ /** @cond */ \ } \ /** @endcond */ \ } namespace msgpack { /// @cond MSGPACK_API_VERSION_NAMESPACE(v1) { /// @endcond namespace type { template struct define_array_imp { template static void pack(Packer& pk, Tuple const& t) { define_array_imp::pack(pk, t); pk.pack(std::get(t)); } static void unpack(msgpack::object const& o, Tuple& t) { define_array_imp::unpack(o, t); const size_t size = o.via.array.size; if(size <= N-1) { return; } o.via.array.ptr[N-1].convert(std::get(t)); } static void object(msgpack::object* o, msgpack::zone& z, Tuple const& t) { define_array_imp::object(o, z, t); o->via.array.ptr[N-1] = msgpack::object(std::get(t), z); } }; template struct define_array_imp { template static void pack(Packer& pk, Tuple const& t) { pk.pack(std::get<0>(t)); } static void unpack(msgpack::object const& o, Tuple& t) { const size_t size = o.via.array.size; if(size <= 0) { return; } o.via.array.ptr[0].convert(std::get<0>(t)); } static void object(msgpack::object* o, msgpack::zone& z, Tuple const& t) { o->via.array.ptr[0] = msgpack::object(std::get<0>(t), z); } }; template struct define_array { typedef define_array value_type; typedef std::tuple tuple_type; define_array(Args&... args) : a(args...) {} template void msgpack_pack(Packer& pk) const { pk.pack_array(sizeof...(Args)); define_array_imp, sizeof...(Args)>::pack(pk, a); } void msgpack_unpack(msgpack::object const& o) { if(o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } define_array_imp, sizeof...(Args)>::unpack(o, a); } void msgpack_object(msgpack::object* o, msgpack::zone& z) const { o->type = msgpack::type::ARRAY; o->via.array.ptr = static_cast(z.allocate_align(sizeof(msgpack::object)*sizeof...(Args))); o->via.array.size = sizeof...(Args); define_array_imp, sizeof...(Args)>::object(o, z, a); } std::tuple a; }; template <> struct define_array<> { typedef define_array<> value_type; typedef std::tuple<> tuple_type; template 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 = NULL; o->via.array.size = 0; } }; inline define_array<> make_define_array() { return define_array<>(); } template inline define_array make_define_array(Args&... args) { return define_array(args...); } } // namespace type /// @cond } // MSGPACK_API_VERSION_NAMESPACE(v1) /// @endcond } // namespace msgpack #endif // MSGPACK_CPP11_DEFINE_ARRAY_HPP