// // MessagePack for C++ static resolution routine // // Copyright (C) 2015 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_BOOST_MSGPACK_VARIANT_HPP #define MSGPACK_TYPE_BOOST_MSGPACK_VARIANT_HPP #if defined(MSGPACK_USE_BOOST) #include "msgpack/versioning.hpp" #include "msgpack/adaptor/adaptor_base.hpp" #include "msgpack/adaptor/check_container_size.hpp" #include "msgpack/adaptor/boost/string_ref.hpp" #include "msgpack/adaptor/nil.hpp" #include "msgpack/adaptor/bool.hpp" #include "msgpack/adaptor/int.hpp" #include "msgpack/adaptor/float.hpp" #include "msgpack/adaptor/string.hpp" #include "msgpack/adaptor/vector_char.hpp" #include "msgpack/adaptor/raw.hpp" #include "msgpack/adaptor/ext.hpp" #include "msgpack/adaptor/vector.hpp" #include "msgpack/adaptor/map.hpp" #include #include namespace msgpack { /// @cond MSGPACK_API_VERSION_NAMESPACE(v1) { /// @endcond namespace type { template struct basic_variant : 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, basic_variant > >, // MAP boost::recursive_wrapper, basic_variant > >// MAP >, private boost::totally_ordered > { 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, basic_variant > >, // MAP boost::recursive_wrapper, basic_variant > >// MAP > base; basic_variant() {} template basic_variant(T const& t):base(t) {} basic_variant(char const* p):base(std::string(p)) {} basic_variant(char v) { int_init(v); } basic_variant(signed char v) { int_init(v); } basic_variant(unsigned char v):base(uint64_t(v)) {} basic_variant(signed int v) { int_init(v); } basic_variant(unsigned int v):base(uint64_t(v)) {} basic_variant(signed long v) { int_init(v); } basic_variant(unsigned long v):base(uint64_t(v)) {} basic_variant(signed long long v) { int_init(v); } basic_variant(unsigned long long v):base(uint64_t(v)) {} bool is_nil() const { return boost::get(this); } bool is_bool() const { return boost::get(this); } bool is_int64_t() const { return boost::get(this); } bool is_uint64_t() const { return boost::get(this); } bool is_double() const { return boost::get(this); } bool is_string() const { return boost::get(this); } #if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53 bool is_boost_string_ref() const { return boost::get(this); } #endif // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53 bool is_vector_char() const { return boost::get >(this); } bool is_vector_char() { return boost::get >(this); } bool is_raw_ref() const { return boost::get(this); } bool is_ext() const { return boost::get(this); } bool is_ext_ref() const { return boost::get(this); } bool is_vector() const { return boost::get > >(this); } bool is_map() const { return boost::get, basic_variant > >(this); } bool is_multimap() const { return boost::get, basic_variant > >(this); } bool as_bool() const { return boost::get(*this); } int64_t as_int64_t() const { return boost::get(*this); } int64_t& as_int64_t() { return boost::get(*this); } uint64_t as_uint64_t() const { return boost::get(*this); } uint64_t& as_uint64_t() { return boost::get(*this); } double as_double() const { return boost::get(*this); } double& as_double() { return boost::get(*this); } std::string const& as_string() const { return boost::get(*this); } std::string& as_string() { return boost::get(*this); } #if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53 boost::string_ref const& as_boost_string_ref() const { return boost::get(*this); } boost::string_ref& as_boost_string_ref() { return boost::get(*this); } #endif // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53 std::vector const& as_vector_char() const { return boost::get >(*this); } std::vector& as_vector_char() { return boost::get >(*this); } raw_ref const& as_raw_ref() const { return boost::get(*this); } ext const& as_ext() const { return boost::get(*this); } ext& as_ext() { return boost::get(*this); } ext_ref const& as_ext_ref() const { return boost::get(*this); } std::vector > const& as_vector() const { return boost::get > >(*this); } std::vector >& as_vector() { return boost::get > >(*this); } std::map, basic_variant > const& as_map() const { return boost::get, basic_variant > >(*this); } std::map, basic_variant >& as_map() { return boost::get, basic_variant > >(*this); } std::multimap, basic_variant > const& as_multimap() const { return boost::get, basic_variant > >(*this); } std::multimap, basic_variant >& as_multimap() { return boost::get, basic_variant > >(*this); } private: template void int_init(T v) { if (v < 0) { static_cast(*this) = int64_t(v); } else { static_cast(*this) = uint64_t(v); } } }; template inline bool operator<(basic_variant const& lhs, basic_variant const& rhs) { return static_cast::base const&>(lhs) < static_cast::base const&>(rhs); } template inline bool operator==(basic_variant const& lhs, basic_variant const& rhs) { return static_cast::base const&>(lhs) == static_cast::base const&>(rhs); } typedef basic_variant, ext> variant; typedef basic_variant< #if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53 boost::string_ref, #else // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53 std::string, #endif // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53 raw_ref, ext_ref> variant_ref; } // namespace type namespace adaptor { #if !defined (MSGPACK_USE_CPP03) template struct as > { msgpack::type::basic_variant operator()(msgpack::object const& o) const { switch(o.type) { case type::NIL: return o.as(); case type::BOOLEAN: return o.as(); case type::POSITIVE_INTEGER: return o.as(); case type::NEGATIVE_INTEGER: return o.as(); case type::FLOAT: return o.as(); case type::STR: return o.as(); case type::BIN: return o.as(); case type::EXT: return o.as(); case type::ARRAY: return o.as > >(); case type::MAP: return o.as, msgpack::type::basic_variant > >(); default: break; } return msgpack::type::basic_variant(); } }; #endif // !defined (MSGPACK_USE_CPP03) template struct convert > { msgpack::object const& operator()( msgpack::object const& o, msgpack::type::basic_variant& v) const { switch(o.type) { case type::NIL: v = o.as(); break; case type::BOOLEAN: v = o.as(); break; case type::POSITIVE_INTEGER: v = o.as(); break; case type::NEGATIVE_INTEGER: v = o.as(); break; case type::FLOAT: v = o.as(); break; case type::STR: v = o.as(); break; case type::BIN: v = o.as(); break; case type::EXT: v = o.as(); break; case type::ARRAY: v = o.as > >(); break; case type::MAP: v = o.as, msgpack::type::basic_variant > >(); break; default: break; } return o; } }; namespace detail { template struct pack_imp : boost::static_visitor { template void operator()(T const& value) const { pack()(o_, value); } pack_imp(packer& o):o_(o) {} packer& o_; }; } // namespace detail template struct pack > { template msgpack::packer& operator()(msgpack::packer& o, const msgpack::type::basic_variant& v) const { boost::apply_visitor(detail::pack_imp(o), v); return o; } }; namespace detail { struct object_imp : boost::static_visitor { void operator()(msgpack::type::nil const& v) const { object()(o_, v); } void operator()(bool const& v) const { object()(o_, v); } void operator()(uint64_t const& v) const { object()(o_, v); } void operator()(int64_t const& v) const { object()(o_, v); } void operator()(double const& v) const { object()(o_, v); } template void operator()(T const&) const { throw msgpack::type_error(); } object_imp(msgpack::object& o):o_(o) {} msgpack::object& o_; }; } // namespace detail template struct object > { void operator()(msgpack::object& o, const msgpack::type::basic_variant& v) const { boost::apply_visitor(detail::object_imp(o), v); } }; namespace detail { struct object_with_zone_imp : boost::static_visitor { template void operator()(T const& v) const { object_with_zone()(o_, v); } object_with_zone_imp(msgpack::object::with_zone& o):o_(o) {} msgpack::object::with_zone& o_; }; } // namespace detail template struct object_with_zone > { void operator()(msgpack::object::with_zone& o, const msgpack::type::basic_variant& v) const { boost::apply_visitor(detail::object_with_zone_imp(o), v); } }; } // namespace adaptor /// @cond } // MSGPACK_API_VERSION_NAMESPACE(v1) /// @endcond } // namespace msgpack #endif // MSGPACK_USE_BOOST #endif // MSGPACK_TYPE_BOOST_MSGPACK_VARIANT_HPP