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 #if defined(__GNUC__)
25 #pragma GCC diagnostic push
26 #pragma GCC diagnostic ignored "-Wconversion"
27 #endif // defined(__GNUC__)
28 
29 #include <boost/fusion/support/is_sequence.hpp>
30 #include <boost/fusion/sequence/intrinsic/size.hpp>
31 #include <boost/fusion/algorithm/iteration/for_each.hpp>
32 #include <boost/fusion/sequence/intrinsic/at.hpp>
33 #include <boost/fusion/include/mpl.hpp>
34 
35 
36 #if defined(__GNUC__)
37 #pragma GCC diagnostic pop
38 #endif // defined(__GNUC__)
39 
40 
41 #include <boost/mpl/size.hpp>
42 
43 namespace msgpack {
44 
48 
49 namespace adaptor {
50 
51 namespace detail {
52 
53 template <typename T>
54 struct is_std_pair {
55  static bool const value = false;
56 };
57 
58 template <typename T, typename U>
59 struct is_std_pair<std::pair<T, U> > {
60  static bool const value = true;
61 };
62 
63 #if !defined(MSGPACK_USE_CPP03)
64 
65 template <typename T>
66 struct is_std_tuple {
67  static bool const value = false;
68 };
69 
70 template <typename... Args>
71 struct is_std_tuple<std::tuple<Args...>> {
72  static bool const value = true;
73 };
74 
75 #endif // !defined(MSGPACK_USE_CPP03)
76 
77 template <typename T>
79  static bool const value =
80  boost::fusion::traits::is_sequence<T>::value
81  &&
83 #if !defined (MSGPACK_USE_CPP03)
84  &&
86 #endif // !defined (MSGPACK_USE_CPP03)
87  ;
88 };
89 
90 } // namespace detail
91 
92 #if !defined (MSGPACK_USE_CPP03)
93 
94 template <typename T>
95 struct as<
96  T,
97  typename msgpack::enable_if<
98  detail::is_seq_no_pair_no_tuple<T>::value &&
99  boost::mpl::fold<
100  T,
101  boost::mpl::bool_<true>,
102  boost::mpl::if_ <
103  boost::mpl::or_<
104  boost::mpl::_1,
105  msgpack::has_as<boost::mpl::_2>
106  >,
107  boost::mpl::bool_<true>,
108  boost::mpl::bool_<false>
109  >
110  >::type::value
111  >::type
112 > {
113  T operator()(msgpack::object const& o) const {
114  if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
115  if (o.via.array.size != checked_get_container_size(boost::mpl::size<T>::value)) {
116  throw msgpack::type_error();
117  }
118  using tuple_t = decltype(to_tuple(std::declval<T>(), gen_seq<boost::mpl::size<T>::value>()));
119  return to_t(
120  o.as<tuple_t>(),
121  msgpack::gen_seq<boost::mpl::size<T>::value>());
122  }
123  template<std::size_t... Is, typename U>
124  static std::tuple<
125  typename std::remove_reference<
126  typename boost::fusion::result_of::at_c<T, static_cast<int>(Is)>::type
127  >::type...>
128  to_tuple(U const& u, seq<Is...>) {
129  return std::make_tuple(boost::fusion::at_c<Is>(u)...);
130  }
131  template<std::size_t... Is, typename U>
132  static T to_t(U const& u, seq<Is...>) {
133  return T(std::get<Is>(u)...);
134  }
135 };
136 
137 #endif // !defined (MSGPACK_USE_CPP03)
138 
139 template <typename T>
140 struct convert<T, typename msgpack::enable_if<detail::is_seq_no_pair_no_tuple<T>::value>::type > {
141  msgpack::object const& operator()(msgpack::object const& o, T& v) const {
142  if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
144  throw msgpack::type_error();
145  }
146  uint32_t index = 0;
147  boost::fusion::for_each(v, convert_imp(o, index));
148  return o;
149  }
150 private:
151  struct convert_imp {
152  convert_imp(msgpack::object const& obj, uint32_t& index):obj_(obj), index_(index) {}
153  template <typename U>
154  void operator()(U& v) const {
155  msgpack::adaptor::convert<U>()(obj_.via.array.ptr[index_++], v);
156  }
157  private:
158  msgpack::object const& obj_;
159  uint32_t& index_;
160  };
161 };
162 
163 template <typename T>
164 struct pack<T, typename msgpack::enable_if<detail::is_seq_no_pair_no_tuple<T>::value>::type > {
165  template <typename Stream>
168  o.pack_array(size);
169  boost::fusion::for_each(v, pack_imp<Stream>(o));
170  return o;
171  }
172 private:
173  template <typename Stream>
174  struct pack_imp {
175  pack_imp(msgpack::packer<Stream>& stream):stream_(stream) {}
176  template <typename U>
177  void operator()(U const& v) const {
178  stream_.pack(v);
179  }
180  private:
181  msgpack::packer<Stream>& stream_;
182  };
183 };
184 
185 template <typename T>
186 struct object_with_zone<T, typename msgpack::enable_if<detail::is_seq_no_pair_no_tuple<T>::value>::type > {
187  void operator()(msgpack::object::with_zone& o, const T& v) const {
191  o.via.array.size = size;
192  uint32_t count = 0;
193  boost::fusion::for_each(v, with_zone_imp(o, count));
194  }
195 private:
196  struct with_zone_imp {
197  with_zone_imp(msgpack::object::with_zone const& obj, uint32_t& count):obj_(obj), count_(count) {}
198  template <typename U>
199  void operator()(U const& v) const {
200  obj_.via.array.ptr[count_++] = msgpack::object(v, obj_.zone);
201  }
202  msgpack::object::with_zone const& obj_;
203  uint32_t& count_;
204  };
205 };
206 
207 } // namespace adaptor
208 
210 } // MSGPACK_API_VERSION_NAMESPACE(v1)
212 
213 } // namespace msgpack
214 
215 #endif // MSGPACK_V1_TYPE_BOOST_FUSION_HPP
The class template that supports continuous packing.
Definition: pack.hpp:33
packer< Stream > & pack_array(uint32_t n)
Packing array header and size.
Definition: pack.hpp:1195
Definition: object_fwd.hpp:231
void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
Definition: cpp03_zone.hpp:256
tuple make_tuple()
Definition: cpp03_msgpack_tuple.hpp:10408
std::size_t size(T const &t)
Definition: size_equal_only.hpp:24
@ ARRAY
Definition: object_fwd_decl.hpp:40
Definition: adaptor_base.hpp:15
uint32_t checked_get_container_size(T size)
Definition: check_container_size.hpp:55
Definition: object_fwd_decl.hpp:61
msgpack::object const & operator()(msgpack::object const &o, T &v) const
Definition: fusion.hpp:141
Definition: adaptor_base.hpp:27
msgpack::object const & operator()(msgpack::object const &o, T &v) const
Definition: object.hpp:641
static bool const value
Definition: fusion.hpp:79
Definition: fusion.hpp:54
static bool const value
Definition: fusion.hpp:55
static bool const value
Definition: fusion.hpp:67
void operator()(msgpack::object::with_zone &o, const T &v) const
Definition: fusion.hpp:187
Definition: adaptor_base.hpp:43
void operator()(msgpack::object::with_zone &o, T const &v) const
Definition: object.hpp:657
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, const T &v) const
Definition: fusion.hpp:166
Definition: adaptor_base.hpp:32
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, T const &v) const
Definition: object.hpp:650
Definition: meta.hpp:40
Definition: object.hpp:35
msgpack::zone & zone
Definition: object.hpp:37
uint32_t size
Definition: object_fwd.hpp:23
msgpack::object * ptr
Definition: object_fwd.hpp:24
Object class that corresponding to MessagePack format object.
Definition: object_fwd.hpp:75
std::enable_if< msgpack::has_as< T >::value, T >::type as() const
Get value as T.
Definition: object.hpp:1121
union_type via
Definition: object_fwd.hpp:93
msgpack::type::object_type type
Definition: object_fwd.hpp:92
msgpack::object_array array
Definition: object_fwd.hpp:85
#define MSGPACK_ZONE_ALIGNOF(type)
Definition: cpp03_zone_decl.hpp:30
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:66