diff --git a/include/msgpack/adaptor/boost/msgpack_variant.hpp b/include/msgpack/adaptor/boost/msgpack_variant.hpp index 07a75392..10b7ca55 100644 --- a/include/msgpack/adaptor/boost/msgpack_variant.hpp +++ b/include/msgpack/adaptor/boost/msgpack_variant.hpp @@ -46,46 +46,10 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { namespace type { -typedef boost::make_recursive_variant< - nil, // NIL - bool, // BOOL - int64_t, // NEGATIVE_INTEGER - uint64_t, // POSITIVE_INTEGER - double, // FLOAT - std::string, // STR -#if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53 - boost::string_ref, // STR -#endif // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53 - std::vector, // BIN - msgpack::type::raw_ref, // BIN - ext, // EXT - ext_ref, // EXT - std::vector, // ARRAY - std::map, // MAP - std::multimap // MAP ->::type variant; +struct variant; namespace detail { -struct ref_tag { -#if defined(MSGPACK_USE_CPP03) -private: - ref_tag(); -#else // defined(MSGPACK_USE_CPP03) - ref_tag() = delete; -#endif // defined(MSGPACK_USE_CPP03) -public: - MSGPACK_DEFINE(); -}; - -inline bool operator<(ref_tag const& lhs, ref_tag const& rhs) { - return &lhs < &rhs; -} -inline bool operator==(ref_tag const& lhs, ref_tag const& rhs) { - return &lhs == &rhs; -} -} // namespace detail - -typedef boost::make_recursive_variant< +typedef boost::variant< nil, // NIL bool, // BOOL int64_t, // NEGATIVE_INTEGER @@ -99,17 +63,130 @@ typedef boost::make_recursive_variant< msgpack::type::raw_ref, // BIN ext, // EXT ext_ref, // EXT - std::vector, // ARRAY - std::map, // MAP - std::multimap, // MAP - detail::ref_tag ->::type variant_ref; + boost::recursive_wrapper >, // ARRAY + boost::recursive_wrapper >, // MAP + boost::recursive_wrapper >// MAP +> variant_imp; + +} // namespace detail + +struct variant : detail::variant_imp { + typedef detail::variant_imp base; + variant() {} + template + variant(T const& t):base(t) {} + variant(char const* p):base(std::string(p)) {} + variant(char v) { + int_init(v); + } + variant(signed char v) { + int_init(v); + } + variant(unsigned char v):base(uint64_t(v)) {} + variant(signed int v) { + int_init(v); + } + variant(unsigned int v):base(uint64_t(v)) {} + variant(signed long v) { + int_init(v); + } + variant(unsigned long v):base(uint64_t(v)) {} + variant(signed long long v) { + int_init(v); + } + variant(unsigned long long v):base(uint64_t(v)) {} +private: + template + void int_init(T v) { + if (v < 0) { + static_cast(*this) = int64_t(v); + } + else { + static_cast(*this) = uint64_t(v); + } + } +}; + +inline bool operator<(variant const& lhs, variant const& rhs) { + return static_cast(lhs) < static_cast(rhs); +} + +inline bool operator==(variant const& lhs, variant const& rhs) { + return static_cast(lhs) == static_cast(rhs); +} + +struct variant_ref; + +namespace detail { +typedef boost::variant< + nil, // NIL + bool, // BOOL + int64_t, // NEGATIVE_INTEGER + uint64_t, // POSITIVE_INTEGER + double, // FLOAT + std::string, // STR +#if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53 + boost::string_ref, // STR +#endif // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53 + std::vector, // BIN + msgpack::type::raw_ref, // BIN + ext, // EXT + ext_ref, // EXT + boost::recursive_wrapper >, // ARRAY + boost::recursive_wrapper >, // MAP + boost::recursive_wrapper >// MAP +> variant_ref_imp; + +} // namespace detail + +struct variant_ref : detail::variant_ref_imp { + typedef detail::variant_ref_imp base; + variant_ref() {} + template + variant_ref(T const& t):base(t) {} + variant_ref(char const* p):base(std::string(p)) {} + variant_ref(char v) { + int_init(v); + } + variant_ref(signed char v) { + int_init(v); + } + variant_ref(unsigned char v):base(uint64_t(v)) {} + variant_ref(signed int v) { + int_init(v); + } + variant_ref(unsigned int v):base(uint64_t(v)) {} + variant_ref(signed long v) { + int_init(v); + } + variant_ref(unsigned long v):base(uint64_t(v)) {} + variant_ref(signed long long v) { + int_init(v); + } + variant_ref(unsigned long long v):base(uint64_t(v)) {} +private: + template + void int_init(T v) { + if (v < 0) { + static_cast(*this) = int64_t(v); + } + else { + static_cast(*this) = uint64_t(v); + } + } +}; + +inline bool operator<(variant_ref const& lhs, variant_ref const& rhs) { + return static_cast(lhs) < static_cast(rhs); +} + +inline bool operator==(variant_ref const& lhs, variant_ref const& rhs) { + return static_cast(lhs) == static_cast(rhs); +} } // namespace type - - namespace adaptor { #if !defined (MSGPACK_USE_CPP03) diff --git a/test/boost_variant.cpp b/test/boost_variant.cpp index 109ae22c..50140f3b 100644 --- a/test/boost_variant.cpp +++ b/test/boost_variant.cpp @@ -113,7 +113,7 @@ TEST(MSGPACK_BOOST, object_with_zone_variant_bool) TEST(MSGPACK_BOOST, pack_convert_variant_positive_integer) { std::stringstream ss; - msgpack::type::variant val1 = uint64_t(123); + msgpack::type::variant val1 = 123; msgpack::pack(ss, val1); @@ -126,7 +126,7 @@ TEST(MSGPACK_BOOST, pack_convert_variant_positive_integer) TEST(MSGPACK_BOOST, object_variant_positive_integer) { - msgpack::type::variant val1 = uint64_t(123); + msgpack::type::variant val1 = 123; msgpack::object obj(val1); msgpack::type::variant val2 = obj.as(); EXPECT_NO_THROW(boost::get(val2)); @@ -136,7 +136,7 @@ TEST(MSGPACK_BOOST, object_variant_positive_integer) TEST(MSGPACK_BOOST, object_with_zone_variant_positive_integer) { msgpack::zone z; - msgpack::type::variant val1 = uint64_t(123); + msgpack::type::variant val1 = 123; msgpack::object obj(val1, z); msgpack::type::variant val2 = obj.as(); EXPECT_NO_THROW(boost::get(val2)); @@ -148,7 +148,7 @@ TEST(MSGPACK_BOOST, object_with_zone_variant_positive_integer) TEST(MSGPACK_BOOST, pack_convert_variant_negative_integer) { std::stringstream ss; - msgpack::type::variant val1 = int64_t(-123); + msgpack::type::variant val1 = -123; msgpack::pack(ss, val1); @@ -161,7 +161,7 @@ TEST(MSGPACK_BOOST, pack_convert_variant_negative_integer) TEST(MSGPACK_BOOST, object_variant_negative_integer) { - msgpack::type::variant val1 = int64_t(-123); + msgpack::type::variant val1 = -123; msgpack::object obj(val1); msgpack::type::variant val2 = obj.as(); EXPECT_NO_THROW(boost::get(val2)); @@ -171,7 +171,7 @@ TEST(MSGPACK_BOOST, object_variant_negative_integer) TEST(MSGPACK_BOOST, object_with_zone_variant_negative_integer) { msgpack::zone z; - msgpack::type::variant val1 = int64_t(-123); + msgpack::type::variant val1 = -123; msgpack::object obj(val1, z); msgpack::type::variant val2 = obj.as(); EXPECT_NO_THROW(boost::get(val2)); @@ -218,7 +218,7 @@ TEST(MSGPACK_BOOST, object_with_zone_variant_float) TEST(MSGPACK_BOOST, pack_convert_variant_str) { std::stringstream ss; - msgpack::type::variant val1 = std::string("ABC"); + msgpack::type::variant val1 = "ABC"; msgpack::pack(ss, val1); @@ -234,7 +234,7 @@ TEST(MSGPACK_BOOST, pack_convert_variant_str) TEST(MSGPACK_BOOST, object_with_zone_variant_str) { msgpack::zone z; - msgpack::type::variant val1 = std::string("ABC"); + msgpack::type::variant val1 = "ABC"; msgpack::object obj(val1, z); msgpack::type::variant val2 = obj.as(); EXPECT_NO_THROW(boost::get(val2)); @@ -319,10 +319,10 @@ TEST(MSGPACK_BOOST, pack_convert_variant_array) { std::stringstream ss; std::vector v; - v.push_back(msgpack::type::variant(uint64_t(1))); - v.push_back(msgpack::type::variant(int64_t(-1))); + v.push_back(msgpack::type::variant(1)); + v.push_back(msgpack::type::variant(-1)); v.push_back(msgpack::type::variant(23.4)); - v.push_back(msgpack::type::variant(std::string("ABC"))); + v.push_back(msgpack::type::variant("ABC")); msgpack::type::variant val1 = v; msgpack::pack(ss, val1); @@ -338,10 +338,10 @@ TEST(MSGPACK_BOOST, object_with_zone_variant_array) { msgpack::zone z; std::vector v; - v.push_back(msgpack::type::variant(uint64_t(1))); - v.push_back(msgpack::type::variant(int64_t(-1))); + v.push_back(msgpack::type::variant(1)); + v.push_back(msgpack::type::variant(-1)); v.push_back(msgpack::type::variant(23.4)); - v.push_back(msgpack::type::variant(std::string("ABC"))); + v.push_back(msgpack::type::variant("ABC")); msgpack::type::variant val1 = v; msgpack::object obj(val1, z); msgpack::type::variant val2 = obj.as(); @@ -356,8 +356,8 @@ TEST(MSGPACK_BOOST, pack_convert_variant_map) std::stringstream ss; typedef std::multimap multimap_t; multimap_t v; - v.insert(multimap_t::value_type(msgpack::type::variant(uint64_t(1)), msgpack::type::variant(int64_t(-1)))); - v.insert(multimap_t::value_type(msgpack::type::variant(23.4), msgpack::type::variant(std::string("ABC")))); + v.insert(multimap_t::value_type(msgpack::type::variant(1), msgpack::type::variant(-1))); + v.insert(multimap_t::value_type(msgpack::type::variant(23.4), msgpack::type::variant("ABC"))); msgpack::type::variant val1 = v; msgpack::pack(ss, val1); @@ -374,8 +374,8 @@ TEST(MSGPACK_BOOST, object_with_zone_variant_map) msgpack::zone z; typedef std::multimap multimap_t; multimap_t v; - v.insert(multimap_t::value_type(msgpack::type::variant(uint64_t(1)), msgpack::type::variant(int64_t(-1)))); - v.insert(multimap_t::value_type(msgpack::type::variant(23.4), msgpack::type::variant(std::string("ABC")))); + v.insert(multimap_t::value_type(msgpack::type::variant(1), msgpack::type::variant(-1))); + v.insert(multimap_t::value_type(msgpack::type::variant(23.4), msgpack::type::variant("ABC"))); msgpack::type::variant val1 = v; msgpack::object obj(val1, z); msgpack::type::variant val2 = obj.as(); @@ -489,7 +489,7 @@ TEST(MSGPACK_BOOST, object_with_zone_variant_ref_bool) TEST(MSGPACK_BOOST, pack_convert_variant_ref_positive_integer) { std::stringstream ss; - msgpack::type::variant_ref val1 = uint64_t(123); + msgpack::type::variant_ref val1 = 123; msgpack::pack(ss, val1); @@ -502,7 +502,7 @@ TEST(MSGPACK_BOOST, pack_convert_variant_ref_positive_integer) TEST(MSGPACK_BOOST, object_variant_ref_positive_integer) { - msgpack::type::variant_ref val1 = uint64_t(123); + msgpack::type::variant_ref val1 = 123; msgpack::object obj(val1); msgpack::type::variant_ref val2 = obj.as(); EXPECT_NO_THROW(boost::get(val2)); @@ -512,7 +512,7 @@ TEST(MSGPACK_BOOST, object_variant_ref_positive_integer) TEST(MSGPACK_BOOST, object_with_zone_variant_ref_positive_integer) { msgpack::zone z; - msgpack::type::variant_ref val1 = uint64_t(123); + msgpack::type::variant_ref val1 = 123; msgpack::object obj(val1, z); msgpack::type::variant_ref val2 = obj.as(); EXPECT_NO_THROW(boost::get(val2)); @@ -524,7 +524,7 @@ TEST(MSGPACK_BOOST, object_with_zone_variant_ref_positive_integer) TEST(MSGPACK_BOOST, pack_convert_variant_ref_negative_integer) { std::stringstream ss; - msgpack::type::variant_ref val1 = int64_t(-123); + msgpack::type::variant_ref val1 = -123; msgpack::pack(ss, val1); @@ -537,7 +537,7 @@ TEST(MSGPACK_BOOST, pack_convert_variant_ref_negative_integer) TEST(MSGPACK_BOOST, object_variant_ref_negative_integer) { - msgpack::type::variant_ref val1 = int64_t(-123); + msgpack::type::variant_ref val1 = -123; msgpack::object obj(val1); msgpack::type::variant_ref val2 = obj.as(); EXPECT_NO_THROW(boost::get(val2)); @@ -547,7 +547,7 @@ TEST(MSGPACK_BOOST, object_variant_ref_negative_integer) TEST(MSGPACK_BOOST, object_with_zone_variant_ref_negative_integer) { msgpack::zone z; - msgpack::type::variant_ref val1 = int64_t(-123); + msgpack::type::variant_ref val1 = -123; msgpack::object obj(val1, z); msgpack::type::variant_ref val2 = obj.as(); EXPECT_NO_THROW(boost::get(val2)); @@ -699,8 +699,8 @@ TEST(MSGPACK_BOOST, pack_convert_variant_ref_array) { std::stringstream ss; std::vector v; - v.push_back(msgpack::type::variant_ref(uint64_t(1))); - v.push_back(msgpack::type::variant_ref(int64_t(-1))); + v.push_back(msgpack::type::variant_ref(1)); + v.push_back(msgpack::type::variant_ref(-1)); v.push_back(msgpack::type::variant_ref(23.4)); std::string s("ABC"); v.push_back(msgpack::type::variant_ref(boost::string_ref(s))); @@ -719,8 +719,8 @@ TEST(MSGPACK_BOOST, object_with_zone_variant_ref_array) { msgpack::zone z; std::vector v; - v.push_back(msgpack::type::variant_ref(uint64_t(1))); - v.push_back(msgpack::type::variant_ref(int64_t(-1))); + v.push_back(msgpack::type::variant_ref(1)); + v.push_back(msgpack::type::variant_ref(-1)); v.push_back(msgpack::type::variant_ref(23.4)); std::string s("ABC"); v.push_back(msgpack::type::variant_ref(boost::string_ref(s))); @@ -738,7 +738,7 @@ TEST(MSGPACK_BOOST, pack_convert_variant_ref_map) std::stringstream ss; typedef std::multimap multimap_t; multimap_t v; - v.insert(multimap_t::value_type(msgpack::type::variant_ref(uint64_t(1)), msgpack::type::variant_ref(int64_t(-1)))); + v.insert(multimap_t::value_type(msgpack::type::variant_ref(1), msgpack::type::variant_ref(-1))); std::string s("ABC"); v.insert(multimap_t::value_type(msgpack::type::variant_ref(23.4), msgpack::type::variant_ref(boost::string_ref(s)))); msgpack::type::variant_ref val1 = v; @@ -757,7 +757,7 @@ TEST(MSGPACK_BOOST, object_with_zone_variant_ref_map) msgpack::zone z; typedef std::multimap multimap_t; multimap_t v; - v.insert(multimap_t::value_type(msgpack::type::variant_ref(uint64_t(1)), msgpack::type::variant_ref(int64_t(-1)))); + v.insert(multimap_t::value_type(msgpack::type::variant_ref(1), msgpack::type::variant_ref(-1))); std::string s("ABC"); v.insert(multimap_t::value_type(msgpack::type::variant_ref(23.4), msgpack::type::variant_ref(boost::string_ref(s)))); msgpack::type::variant_ref val1 = v;