// // MessagePack for C++ static resolution routine // // Copyright (C) 2008-2013 FURUHASHI Sadayuki and KONDO Takatoshi // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #ifndef MSGPACK_TYPE_DEFINE_HPP #define MSGPACK_TYPE_DEFINE_HPP #define MSGPACK_DEFINE(...) \ template \ void msgpack_pack(Packer& pk) const \ { \ msgpack::type::make_define(__VA_ARGS__).msgpack_pack(pk); \ } \ void msgpack_unpack(msgpack::object o) \ { \ msgpack::type::make_define(__VA_ARGS__).msgpack_unpack(o); \ }\ template \ void msgpack_object(MSGPACK_OBJECT* o, msgpack::zone* z) const \ { \ msgpack::type::make_define(__VA_ARGS__).msgpack_object(o, z); \ } // MSGPACK_ADD_ENUM must be used in the global namespace. #define MSGPACK_ADD_ENUM(enum) \ namespace msgpack { \ template <> \ inline enum& operator>> (object o, enum& v) \ { \ int tmp; \ o >> tmp; \ v = static_cast(tmp); \ return v; \ } \ template <> \ void operator<< (object::with_zone& o, const enum& v) \ { \ int tmp = static_cast(v); \ o << tmp; \ } \ namespace detail { \ template \ struct packer_serializer { \ static packer& pack(packer& o, const enum& v) { \ return o << static_cast(v); \ } \ }; \ } \ } namespace msgpack { namespace type { template struct define_imp { template static void pack(Packer& pk, Tuple const& t) { define_imp::pack(pk, t); pk.pack(std::get(t)); } static void unpack(msgpack::object o, Tuple& t) { define_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_imp::object(o, z, t); o->via.array.ptr[N-1] = msgpack::object(std::get(t), z); } }; template struct define_imp { template static void pack(Packer& pk, Tuple const& t) { pk.pack(std::get<0>(t)); } static void unpack(msgpack::object 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 { typedef define value_type; typedef tuple tuple_type; define(Args&... args) : a(args...) {} template void msgpack_pack(Packer& pk) const { pk.pack_array(sizeof...(Args)); define_imp, sizeof...(Args)>::pack(pk, a); } void msgpack_unpack(msgpack::object o) { if(o.type != type::ARRAY) { throw type_error(); } define_imp, sizeof...(Args)>::unpack(o, a); } void msgpack_object(msgpack::object* o, msgpack::zone* z) const { o->type = type::ARRAY; o->via.array.ptr = (object*)z->malloc(sizeof(object)*sizeof...(Args)); o->via.array.size = sizeof...(Args); define_imp, sizeof...(Args)>::object(o, z, a); } tuple a; }; template <> struct define<> { typedef define<> value_type; typedef tuple<> tuple_type; template void msgpack_pack(Packer& pk) const { pk.pack_array(0); } void msgpack_unpack(msgpack::object o) { if(o.type != type::ARRAY) { throw type_error(); } } void msgpack_object(msgpack::object* o, msgpack::zone* z) const { o->type = type::ARRAY; o->via.array.ptr = NULL; o->via.array.size = 0; } }; inline define<> make_define() { return define<>(); } template define make_define(Args&... args) { return define(args...); } } // namespace type } // namespace msgpack #endif /* msgpack/type/define.hpp */