diff --git a/include/msgpack/v1/adaptor/boost/fusion.hpp b/include/msgpack/v1/adaptor/boost/fusion.hpp index 9e46b1ab..69a11240 100644 --- a/include/msgpack/v1/adaptor/boost/fusion.hpp +++ b/include/msgpack/v1/adaptor/boost/fusion.hpp @@ -15,6 +15,8 @@ #include "msgpack/adaptor/check_container_size.hpp" #include "msgpack/meta.hpp" +#include "msgpack/adaptor/pair.hpp" + #if !defined (MSGPACK_USE_CPP03) #include "msgpack/adaptor/cpp11/tuple.hpp" #endif // #if !defined (MSGPACK_USE_CPP03) @@ -34,13 +36,54 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { namespace adaptor { +namespace detail { + +template +struct is_std_pair { + static bool const value = false; +}; + +template +struct is_std_pair > { + static bool const value = true; +}; + +#if !defined(MSGPACK_USE_CPP03) + +template +struct is_std_tuple { + static bool const value = false; +}; + +template +struct is_std_tuple> { + static bool const value = true; +}; + +#endif // !defined(MSGPACK_USE_CPP03) + +template +struct is_seq_no_pair_no_tuple { + static bool const value = + boost::fusion::traits::is_sequence::value + && + !is_std_pair::value +#if !defined (MSGPACK_USE_CPP03) + && + !is_std_tuple::value +#endif // !defined (MSGPACK_USE_CPP03) + ; +}; + +} // namespace detail + #if !defined (MSGPACK_USE_CPP03) template struct as< T, typename msgpack::enable_if< - boost::fusion::traits::is_sequence::value && + detail::is_seq_no_pair_no_tuple::value && boost::mpl::fold< T, boost::mpl::bool_, @@ -82,7 +125,7 @@ struct as< #endif // !defined (MSGPACK_USE_CPP03) template -struct convert::value>::type > { +struct convert::value>::type > { msgpack::object const& operator()(msgpack::object const& o, T& v) const { if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } if (o.via.array.size != checked_get_container_size(boost::fusion::size(v))) { @@ -106,7 +149,7 @@ private: }; template -struct pack::value>::type > { +struct pack::value>::type > { template msgpack::packer& operator()(msgpack::packer& o, const T& v) const { uint32_t size = checked_get_container_size(boost::fusion::size(v)); @@ -128,7 +171,7 @@ private: }; template -struct object_with_zone::value>::type > { +struct object_with_zone::value>::type > { void operator()(msgpack::object::with_zone& o, const T& v) const { uint32_t size = checked_get_container_size(boost::fusion::size(v)); o.type = msgpack::type::ARRAY; diff --git a/test/boost_fusion.cpp b/test/boost_fusion.cpp index da2eb13b..88c30e96 100644 --- a/test/boost_fusion.cpp +++ b/test/boost_fusion.cpp @@ -212,4 +212,35 @@ TEST(MSGPACK_BOOST, pack_convert_no_def_con_def_con) #endif // !defined(MSGPACK_USE_CPP03 +#include + +TEST(MSGPACK_BOOST, fusion_pack_unpack_convert_pair) +{ + std::stringstream ss; + std::pair val1(false, 42); + msgpack::pack(ss, val1); + msgpack::object_handle oh = + msgpack::unpack(ss.str().data(), ss.str().size()); + std::pair val2 = oh.get().as >(); + EXPECT_TRUE(val1.first == val2.first); + EXPECT_TRUE(val1.second == val2.second); +} + +#if !defined(MSGPACK_USE_CPP03) + +#include + +TEST(MSGPACK_BOOST, fusion_pack_unpack_convert_tuple) +{ + std::stringstream ss; + std::tuple val1(false, 42); + msgpack::pack(ss, val1); + msgpack::object_handle oh = + msgpack::unpack(ss.str().data(), ss.str().size()); + std::tuple val2 = oh.get().as >(); + EXPECT_TRUE(val1 == val2); +} + +#endif // !defined(MSGPACK_USE_CPP03) + #endif // defined(MSGPACK_USE_BOOST)