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