// // MessagePack for C++ static resolution routine // // Copyright (C) 2015-2016 KONDO Takatoshi // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // #ifndef MSGPACK_V1_TYPE_BOOST_FUSION_HPP #define MSGPACK_V1_TYPE_BOOST_FUSION_HPP #include "rpc/msgpack/versioning.hpp" #include "rpc/msgpack/adaptor/adaptor_base.hpp" #include "rpc/msgpack/adaptor/check_container_size.hpp" #include "rpc/msgpack/meta.hpp" #include "rpc/msgpack/adaptor/pair.hpp" #if !defined (MSGPACK_USE_CPP03) #include "rpc/msgpack/adaptor/cpp11/tuple.hpp" #endif // #if !defined (MSGPACK_USE_CPP03) #include #include #include #include #include #include namespace clmdep_msgpack { /// @cond MSGPACK_API_VERSION_NAMESPACE(v1) { /// @endcond 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 clmdep_msgpack::enable_if< detail::is_seq_no_pair_no_tuple::value && boost::mpl::fold< T, boost::mpl::bool_, boost::mpl::if_ < boost::mpl::or_< boost::mpl::_1, clmdep_msgpack::has_as >, boost::mpl::bool_, boost::mpl::bool_ > >::type::value >::type > { T operator()(clmdep_msgpack::object const& o) const { if (o.type != clmdep_msgpack::type::ARRAY) { throw clmdep_msgpack::type_error(); } if (o.via.array.size != checked_get_container_size(boost::mpl::size::value)) { throw clmdep_msgpack::type_error(); } using tuple_t = decltype(to_tuple(std::declval(), gen_seq::value>())); return to_t( o.as(), clmdep_msgpack::gen_seq::value>()); } template static std::tuple< typename std::remove_reference< typename boost::fusion::result_of::at_c::type >::type...> to_tuple(U const& u, seq) { return std::make_tuple(boost::fusion::at_c(u)...); } template static T to_t(U const& u, seq) { return T(std::get(u)...); } }; #endif // !defined (MSGPACK_USE_CPP03) template struct convert::value>::type > { clmdep_msgpack::object const& operator()(clmdep_msgpack::object const& o, T& v) const { if (o.type != clmdep_msgpack::type::ARRAY) { throw clmdep_msgpack::type_error(); } if (o.via.array.size != checked_get_container_size(boost::fusion::size(v))) { throw clmdep_msgpack::type_error(); } uint32_t index = 0; boost::fusion::for_each(v, convert_imp(o, index)); return o; } private: struct convert_imp { convert_imp(clmdep_msgpack::object const& obj, uint32_t& index):obj_(obj), index_(index) {} template void operator()(U& v) const { clmdep_msgpack::adaptor::convert()(obj_.via.array.ptr[index_++], v); } private: clmdep_msgpack::object const& obj_; uint32_t& index_; }; }; template struct pack::value>::type > { template clmdep_msgpack::packer& operator()(clmdep_msgpack::packer& o, const T& v) const { uint32_t size = checked_get_container_size(boost::fusion::size(v)); o.pack_array(size); boost::fusion::for_each(v, pack_imp(o)); return o; } private: template struct pack_imp { pack_imp(clmdep_msgpack::packer& stream):stream_(stream) {} template void operator()(U const& v) const { stream_.pack(v); } private: clmdep_msgpack::packer& stream_; }; }; template struct object_with_zone::value>::type > { void operator()(clmdep_msgpack::object::with_zone& o, const T& v) const { uint32_t size = checked_get_container_size(boost::fusion::size(v)); o.type = clmdep_msgpack::type::ARRAY; o.via.array.ptr = static_cast(o.zone.allocate_align(sizeof(clmdep_msgpack::object)*size, MSGPACK_ZONE_ALIGNOF(clmdep_msgpack::object))); o.via.array.size = size; uint32_t count = 0; boost::fusion::for_each(v, with_zone_imp(o, count)); } private: struct with_zone_imp { with_zone_imp(clmdep_msgpack::object::with_zone const& obj, uint32_t& count):obj_(obj), count_(count) {} template void operator()(U const& v) const { obj_.via.array.ptr[count_++] = clmdep_msgpack::object(v, obj_.zone); } clmdep_msgpack::object::with_zone const& obj_; uint32_t& count_; }; }; } // namespace adaptor /// @cond } // MSGPACK_API_VERSION_NAMESPACE(v1) /// @endcond } // namespace clmdep_msgpack #endif // MSGPACK_V1_TYPE_BOOST_FUSION_HPP