diff --git a/include/msgpack/adaptor/cpp11/tuple.hpp b/include/msgpack/adaptor/cpp11/tuple.hpp new file mode 100644 index 00000000..b599b4c5 --- /dev/null +++ b/include/msgpack/adaptor/cpp11/tuple.hpp @@ -0,0 +1,121 @@ +// +// MessagePack for C++ static resolution routine +// +// Copyright (C) 2008-2014 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_CPP11_TUPLE_HPP +#define MSGPACK_CPP11_TUPLE_HPP + +#include + +#include "msgpack/object.hpp" +#include "msgpack/cpp_config.hpp" + +namespace msgpack { + +// --- Pack ( from tuple to packer stream --- +template +struct StdTuplePacker { + static void pack( + packer& o, + const Tuple& v) { + StdTuplePacker::pack(o, v); + o.pack(std::get(v)); + } +}; + +template +struct StdTuplePacker { + static void pack ( + packer& o, + const Tuple& v) { + o.pack(std::get<0>(v)); + } +}; + +template +const packer& operator<< ( + packer& o, + const std::tuple& v) { + o.pack_array(sizeof...(Args)); + StdTuplePacker::pack(o, v); + return o; +} + +// --- Convert from tuple to object --- + +template +struct StdTupleConverter { + static void convert( + object const& o, + Tuple& v) { + StdTupleConverter::convert(o, v); + o.via.array.ptr[N-1].convert(v))>::type>(std::get(v)); + } +}; + +template +struct StdTupleConverter { + static void convert ( + object const& o, + Tuple& v) { + o.via.array.ptr[0].convert(v))>::type>(std::get<0>(v)); + } +}; + +template +std::tuple& operator>> ( + object const& o, + std::tuple& v) { + if(o.type != type::ARRAY) { throw type_error(); } + if(o.via.array.size < sizeof...(Args)) { throw type_error(); } + StdTupleConverter::convert(o, v); + return v; +} + +// --- Convert from tuple to object with zone --- +template +struct StdTupleToObjectWithZone { + static void convert( + object::with_zone& o, + const Tuple& v) { + StdTupleToObjectWithZone::convert(o, v); + o.via.array.ptr[N-1] = object(std::get(v), o.zone); + } +}; + +template +struct StdTupleToObjectWithZone { + static void convert ( + object::with_zone& o, + const Tuple& v) { + o.via.array.ptr[0] = object(std::get<0>(v), o.zone); + } +}; + +template +inline void operator<< ( + object::with_zone& o, + std::tuple& v) { + o.type = type::ARRAY; + o.via.array.ptr = static_cast(o.zone->allocate_align(sizeof(object)*sizeof...(Args))); + o.via.array.size = sizeof...(Args); + StdTupleToObjectWithZone::convert(o, v); +} + +} // msgpack + +#endif // MSGPACK_CPP11_TUPLE_HPP + diff --git a/include/msgpack/adaptor/detail/cpp11_msgpack_tuple.hpp b/include/msgpack/adaptor/detail/cpp11_msgpack_tuple.hpp index 98041bb4..9f10ce7a 100644 --- a/include/msgpack/adaptor/detail/cpp11_msgpack_tuple.hpp +++ b/include/msgpack/adaptor/detail/cpp11_msgpack_tuple.hpp @@ -1,7 +1,7 @@ // // MessagePack for C++ static resolution routine // -// Copyright (C) 2008-2013 FURUHASHI Sadayuki and KONDO Takatoshi +// Copyright (C) 2008-2014 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. @@ -91,17 +91,17 @@ namespace type { // --- Pack ( from tuple to packer stream --- template -struct Packer { +struct MsgpackTuplePacker { static void pack( packer& o, const Tuple& v) { - Packer::pack(o, v); + MsgpackTuplePacker::pack(o, v); o.pack(type::get(v)); } }; template -struct Packer { +struct MsgpackTuplePacker { static void pack ( packer& o, const Tuple& v) { @@ -114,24 +114,24 @@ const packer& operator<< ( packer& o, const type::tuple& v) { o.pack_array(sizeof...(Args)); - Packer::pack(o, v); + MsgpackTuplePacker::pack(o, v); return o; } // --- Convert from tuple to object --- template -struct Converter { +struct MsgpackTupleConverter { static void convert( object const& o, Tuple& v) { - Converter::convert(o, v); + MsgpackTupleConverter::convert(o, v); o.via.array.ptr[N-1].convert(v))>::type>(type::get(v)); } }; template -struct Converter { +struct MsgpackTupleConverter { static void convert ( object const& o, Tuple& v) { @@ -145,23 +145,23 @@ type::tuple& operator>> ( type::tuple& v) { if(o.type != type::ARRAY) { throw type_error(); } if(o.via.array.size < sizeof...(Args)) { throw type_error(); } - Converter::convert(o, v); + MsgpackTupleConverter::convert(o, v); return v; } // --- Convert from tuple to object with zone --- template -struct TupleToObjectWithZone { +struct MsgpackTupleToObjectWithZone { static void convert( object::with_zone& o, const Tuple& v) { - TupleToObjectWithZone::convert(o, v); + MsgpackTupleToObjectWithZone::convert(o, v); o.via.array.ptr[N-1] = object(type::get(v), o.zone); } }; template -struct TupleToObjectWithZone { +struct MsgpackTupleToObjectWithZone { static void convert ( object::with_zone& o, const Tuple& v) { @@ -176,7 +176,7 @@ inline void operator<< ( o.type = type::ARRAY; o.via.array.ptr = static_cast(o.zone->allocate_align(sizeof(object)*sizeof...(Args))); o.via.array.size = sizeof...(Args); - TupleToObjectWithZone::convert(o, v); + MsgpackTupleToObjectWithZone::convert(o, v); } } // msgpack diff --git a/include/msgpack/type.hpp b/include/msgpack/type.hpp index 6a728623..b3da55d4 100644 --- a/include/msgpack/type.hpp +++ b/include/msgpack/type.hpp @@ -1,3 +1,4 @@ +#include "cpp_config.hpp" #include "adaptor/bool.hpp" #include "adaptor/deque.hpp" #include "adaptor/fixint.hpp" @@ -15,3 +16,10 @@ #include "adaptor/define.hpp" #include "adaptor/tr1/unordered_map.hpp" #include "adaptor/tr1/unordered_set.hpp" + +#if !defined(MSGPACK_USE_CPP03) + +#include "adaptor/cpp11/tuple.hpp" + +#endif // !defined(MSGPACK_USE_CPP03) + diff --git a/test/msgpack_test.cpp b/test/msgpack_test.cpp index 9673ed91..e3b67ee7 100644 --- a/test/msgpack_test.cpp +++ b/test/msgpack_test.cpp @@ -740,6 +740,26 @@ TEST(MSGPACK_TR1, simple_buffer_unordered_multiset) } #endif +#if !defined(MSGPACK_USE_CPP03) +// C++11 + +TEST(MSGPACK_CPP11, simple_tuple) +{ + msgpack::sbuffer sbuf; + std::tuple val1(true, "kzk", 12.3); + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, z, obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + std::tuple val2; + obj.convert(&val2); + EXPECT_EQ(val1, val2); +} + +#endif // !defined(MSGPACK_USE_CPP03) + // User-Defined Structures class TestClass