MessagePack for C++
fusion.hpp
Go to the documentation of this file.
1 //
2 // MessagePack for C++ static resolution routine
3 //
4 // Copyright (C) 2015-2016 KONDO Takatoshi
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 //
10 #ifndef MSGPACK_V1_TYPE_BOOST_FUSION_HPP
11 #define MSGPACK_V1_TYPE_BOOST_FUSION_HPP
12 
13 #include "msgpack/versioning.hpp"
16 #include "msgpack/meta.hpp"
17 
18 #include "msgpack/adaptor/pair.hpp"
19 
20 #if !defined (MSGPACK_USE_CPP03)
22 #endif // #if !defined (MSGPACK_USE_CPP03)
23 
24 #include <boost/fusion/support/is_sequence.hpp>
25 #include <boost/fusion/sequence/intrinsic/size.hpp>
26 #include <boost/fusion/algorithm/iteration/for_each.hpp>
27 #include <boost/fusion/sequence/intrinsic/at.hpp>
28 #include <boost/fusion/include/mpl.hpp>
29 #include <boost/mpl/size.hpp>
30 
31 namespace msgpack {
32 
36 
37 namespace adaptor {
38 
39 namespace detail {
40 
41 template <typename T>
42 struct is_std_pair {
43  static bool const value = false;
44 };
45 
46 template <typename T, typename U>
47 struct is_std_pair<std::pair<T, U> > {
48  static bool const value = true;
49 };
50 
51 #if !defined(MSGPACK_USE_CPP03)
52 
53 template <typename T>
54 struct is_std_tuple {
55  static bool const value = false;
56 };
57 
58 template <typename... Args>
59 struct is_std_tuple<std::tuple<Args...>> {
60  static bool const value = true;
61 };
62 
63 #endif // !defined(MSGPACK_USE_CPP03)
64 
65 template <typename T>
67  static bool const value =
68  boost::fusion::traits::is_sequence<T>::value
69  &&
71 #if !defined (MSGPACK_USE_CPP03)
72  &&
74 #endif // !defined (MSGPACK_USE_CPP03)
75  ;
76 };
77 
78 } // namespace detail
79 
80 #if !defined (MSGPACK_USE_CPP03)
81 
82 template <typename T>
83 struct as<
84  T,
85  typename msgpack::enable_if<
86  detail::is_seq_no_pair_no_tuple<T>::value &&
87  boost::mpl::fold<
88  T,
89  boost::mpl::bool_<true>,
90  boost::mpl::if_ <
91  boost::mpl::or_<
92  boost::mpl::_1,
93  msgpack::has_as<boost::mpl::_2>
94  >,
95  boost::mpl::bool_<true>,
96  boost::mpl::bool_<false>
97  >
98  >::type::value
99  >::type
100 > {
101  T operator()(msgpack::object const& o) const {
102  if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
103  if (o.via.array.size != checked_get_container_size(boost::mpl::size<T>::value)) {
104  throw msgpack::type_error();
105  }
106  using tuple_t = decltype(to_tuple(std::declval<T>(), gen_seq<boost::mpl::size<T>::value>()));
107  return to_t(
108  o.as<tuple_t>(),
109  msgpack::gen_seq<boost::mpl::size<T>::value>());
110  }
111  template<std::size_t... Is, typename U>
112  static std::tuple<
113  typename std::remove_reference<
114  typename boost::fusion::result_of::at_c<T, Is>::type
115  >::type...>
116  to_tuple(U const& u, seq<Is...>) {
117  return std::make_tuple(boost::fusion::at_c<Is>(u)...);
118  }
119  template<std::size_t... Is, typename U>
120  static T to_t(U const& u, seq<Is...>) {
121  return T(std::get<Is>(u)...);
122  }
123 };
124 
125 #endif // !defined (MSGPACK_USE_CPP03)
126 
127 template <typename T>
128 struct convert<T, typename msgpack::enable_if<detail::is_seq_no_pair_no_tuple<T>::value>::type > {
129  msgpack::object const& operator()(msgpack::object const& o, T& v) const {
130  if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
132  throw msgpack::type_error();
133  }
134  uint32_t index = 0;
135  boost::fusion::for_each(v, convert_imp(o, index));
136  return o;
137  }
138 private:
139  struct convert_imp {
140  convert_imp(msgpack::object const& obj, uint32_t& index):obj_(obj), index_(index) {}
141  template <typename U>
142  void operator()(U& v) const {
143  msgpack::adaptor::convert<U>()(obj_.via.array.ptr[index_++], v);
144  }
145  private:
146  msgpack::object const& obj_;
147  uint32_t& index_;
148  };
149 };
150 
151 template <typename T>
152 struct pack<T, typename msgpack::enable_if<detail::is_seq_no_pair_no_tuple<T>::value>::type > {
153  template <typename Stream>
156  o.pack_array(size);
157  boost::fusion::for_each(v, pack_imp<Stream>(o));
158  return o;
159  }
160 private:
161  template <typename Stream>
162  struct pack_imp {
163  pack_imp(msgpack::packer<Stream>& stream):stream_(stream) {}
164  template <typename U>
165  void operator()(U const& v) const {
166  stream_.pack(v);
167  }
168  private:
169  msgpack::packer<Stream>& stream_;
170  };
171 };
172 
173 template <typename T>
174 struct object_with_zone<T, typename msgpack::enable_if<detail::is_seq_no_pair_no_tuple<T>::value>::type > {
175  void operator()(msgpack::object::with_zone& o, const T& v) const {
179  o.via.array.size = size;
180  uint32_t count = 0;
181  boost::fusion::for_each(v, with_zone_imp(o, count));
182  }
183 private:
184  struct with_zone_imp {
185  with_zone_imp(msgpack::object::with_zone const& obj, uint32_t& count):obj_(obj), count_(count) {}
186  template <typename U>
187  void operator()(U const& v) const {
188  obj_.via.array.ptr[count_++] = msgpack::object(v, obj_.zone);
189  }
190  msgpack::object::with_zone const& obj_;
191  uint32_t& count_;
192  };
193 };
194 
195 } // namespace adaptor
196 
198 } // MSGPACK_API_VERSION_NAMESPACE(v1)
200 
201 } // namespace msgpack
202 
203 #endif // MSGPACK_V1_TYPE_BOOST_FUSION_HPP
msgpack::adaptor::as< T, typename msgpack::enable_if< detail::is_seq_no_pair_no_tuple< T >::value &&boost::mpl::fold< T, boost::mpl::bool_< true >, boost::mpl::if_< boost::mpl::or_< boost::mpl::_1, msgpack::has_as< boost::mpl::_2 > >, boost::mpl::bool_< true >, boost::mpl::bool_< false > > >::type::value >::type >::to_t
static T to_t(U const &u, seq< Is... >)
Definition: fusion.hpp:120
msgpack::packer
The class template that supports continuous packing.
Definition: adaptor_base_decl.hpp:24
msgpack::zone::allocate_align
void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
Definition: cpp03_zone.hpp:246
msgpack::type::make_tuple
tuple make_tuple()
Definition: cpp03_msgpack_tuple.hpp:10408
tuple.hpp
msgpack::adaptor::object_with_zone
Definition: adaptor_base.hpp:43
msgpack
Definition: adaptor_base.hpp:15
MSGPACK_ZONE_ALIGNOF
#define MSGPACK_ZONE_ALIGNOF(type)
Definition: cpp03_zone_decl.hpp:30
msgpack::enable_if
Definition: cpp_config_decl.hpp:56
msgpack::adaptor::convert
Definition: adaptor_base.hpp:27
msgpack::seq< Is... >
msgpack::adaptor::detail::is_std_pair
Definition: fusion.hpp:42
msgpack::adaptor::pack< T, typename msgpack::enable_if< detail::is_seq_no_pair_no_tuple< T >::value >::type >::operator()
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, const T &v) const
Definition: fusion.hpp:154
msgpack::checked_get_container_size
uint32_t checked_get_container_size(T size)
Definition: check_container_size.hpp:55
MSGPACK_API_VERSION_NAMESPACE
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58
msgpack::object::via
union_type via
Definition: object_fwd.hpp:93
msgpack::object_array::ptr
msgpack::object * ptr
Definition: object_fwd.hpp:24
adaptor_base.hpp
msgpack::adaptor::as
Definition: object_fwd_decl.hpp:62
versioning.hpp
msgpack::type::size
std::size_t size(T const &t)
Definition: size_equal_only.hpp:24
meta.hpp
msgpack::gen_seq
Definition: meta.hpp:40
msgpack::object_array::size
uint32_t size
Definition: object_fwd.hpp:23
msgpack::object::union_type::array
msgpack::object_array array
Definition: object_fwd.hpp:85
msgpack::type::ARRAY
@ ARRAY
Definition: object_fwd_decl.hpp:41
msgpack::adaptor::object_with_zone< T, typename msgpack::enable_if< detail::is_seq_no_pair_no_tuple< T >::value >::type >::operator()
void operator()(msgpack::object::with_zone &o, const T &v) const
Definition: fusion.hpp:175
check_container_size.hpp
msgpack::type_error
Definition: object_fwd.hpp:236
msgpack::adaptor::pack
Definition: adaptor_base.hpp:32
msgpack::adaptor::detail::is_seq_no_pair_no_tuple
Definition: fusion.hpp:66
msgpack::adaptor::detail::is_std_tuple::value
static const bool value
Definition: fusion.hpp:55
msgpack::adaptor::as< T, typename msgpack::enable_if< detail::is_seq_no_pair_no_tuple< T >::value &&boost::mpl::fold< T, boost::mpl::bool_< true >, boost::mpl::if_< boost::mpl::or_< boost::mpl::_1, msgpack::has_as< boost::mpl::_2 > >, boost::mpl::bool_< true >, boost::mpl::bool_< false > > >::type::value >::type >::operator()
T operator()(msgpack::object const &o) const
Definition: fusion.hpp:101
msgpack::adaptor::pack::operator()
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, T const &v) const
Definition: object.hpp:650
msgpack::packer::pack_array
packer< Stream > & pack_array(uint32_t n)
Packing array header and size.
Definition: pack.hpp:1160
msgpack::object::as
std::enable_if< msgpack::has_as< T >::value, T >::type as() const
Get value as T.
Definition: object.hpp:1121
msgpack::adaptor::convert::operator()
msgpack::object const & operator()(msgpack::object const &o, T &v) const
Definition: object.hpp:641
pair.hpp
msgpack::adaptor::convert< T, typename msgpack::enable_if< detail::is_seq_no_pair_no_tuple< T >::value >::type >::operator()
msgpack::object const & operator()(msgpack::object const &o, T &v) const
Definition: fusion.hpp:129
msgpack::adaptor::as< T, typename msgpack::enable_if< detail::is_seq_no_pair_no_tuple< T >::value &&boost::mpl::fold< T, boost::mpl::bool_< true >, boost::mpl::if_< boost::mpl::or_< boost::mpl::_1, msgpack::has_as< boost::mpl::_2 > >, boost::mpl::bool_< true >, boost::mpl::bool_< false > > >::type::value >::type >::to_tuple
static std::tuple< typename std::remove_reference< typename boost::fusion::result_of::at_c< T, Is >::type >::type... > to_tuple(U const &u, seq< Is... >)
Definition: fusion.hpp:116
msgpack::object
Object class that corresponding to MessagePack format object.
Definition: object_fwd.hpp:75
v2::object::with_zone::zone
msgpack::zone & zone
Definition: object.hpp:37
v2::object::with_zone
Definition: object.hpp:35
msgpack::object::type
msgpack::type::object_type type
Definition: object_fwd.hpp:92
msgpack::adaptor::detail::is_std_pair::value
static const bool value
Definition: fusion.hpp:43
msgpack::adaptor::detail::is_seq_no_pair_no_tuple::value
static const bool value
Definition: fusion.hpp:67
msgpack::adaptor::detail::is_std_tuple
Definition: fusion.hpp:54
msgpack::adaptor::object_with_zone::operator()
void operator()(msgpack::object::with_zone &o, T const &v) const
Definition: object.hpp:657