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 #if !defined (MSGPACK_USE_CPP03)
20 #endif // #if !defined (MSGPACK_USE_CPP03)
21 
22 #include <boost/fusion/support/is_sequence.hpp>
23 #include <boost/fusion/sequence/intrinsic/size.hpp>
24 #include <boost/fusion/algorithm/iteration/for_each.hpp>
25 #include <boost/fusion/sequence/intrinsic/at.hpp>
26 #include <boost/fusion/include/mpl.hpp>
27 #include <boost/mpl/size.hpp>
28 
29 namespace msgpack {
30 
34 
35 namespace adaptor {
36 
37 #if !defined (MSGPACK_USE_CPP03)
38 
39 template <typename T>
40 struct as<
41  T,
42  typename msgpack::enable_if<
43  boost::fusion::traits::is_sequence<T>::value &&
44  boost::mpl::fold<
45  T,
46  boost::mpl::bool_<true>,
47  boost::mpl::if_ <
48  boost::mpl::or_<
49  boost::mpl::_1,
50  msgpack::has_as<boost::mpl::_2>
51  >,
52  boost::mpl::bool_<true>,
53  boost::mpl::bool_<false>
54  >
55  >::type::value
56  >::type
57 > {
58  T operator()(msgpack::object const& o) const {
59  if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
60  if (o.via.array.size != checked_get_container_size(boost::mpl::size<T>::value)) {
61  throw msgpack::type_error();
62  }
63  using tuple_t = decltype(to_tuple(std::declval<T>(), gen_seq<boost::mpl::size<T>::value>()));
64  return to_t(
65  o.as<tuple_t>(),
66  msgpack::gen_seq<boost::mpl::size<T>::value>());
67  }
68  template<std::size_t... Is, typename U>
69  static std::tuple<
70  typename std::remove_reference<
71  typename boost::fusion::result_of::at_c<T, Is>::type
72  >::type...>
73  to_tuple(U const& u, seq<Is...>) {
74  return std::make_tuple(boost::fusion::at_c<Is>(u)...);
75  }
76  template<std::size_t... Is, typename U>
77  static T to_t(U const& u, seq<Is...>) {
78  return T(std::get<Is>(u)...);
79  }
80 };
81 
82 #endif // !defined (MSGPACK_USE_CPP03)
83 
84 template <typename T>
85 struct convert<T, typename msgpack::enable_if<boost::fusion::traits::is_sequence<T>::value>::type > {
86  msgpack::object const& operator()(msgpack::object const& o, T& v) const {
87  if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
89  throw msgpack::type_error();
90  }
91  uint32_t index = 0;
92  boost::fusion::for_each(v, convert_imp(o, index));
93  return o;
94  }
95 private:
96  struct convert_imp {
97  convert_imp(msgpack::object const& obj, uint32_t& index):obj_(obj), index_(index) {}
98  template <typename U>
99  void operator()(U& v) const {
100  msgpack::adaptor::convert<U>()(obj_.via.array.ptr[index_++], v);
101  }
102  private:
103  msgpack::object const& obj_;
104  uint32_t& index_;
105  };
106 };
107 
108 template <typename T>
109 struct pack<T, typename msgpack::enable_if<boost::fusion::traits::is_sequence<T>::value>::type > {
110  template <typename Stream>
113  o.pack_array(size);
114  boost::fusion::for_each(v, pack_imp<Stream>(o));
115  return o;
116  }
117 private:
118  template <typename Stream>
119  struct pack_imp {
120  pack_imp(msgpack::packer<Stream>& stream):stream_(stream) {}
121  template <typename U>
122  void operator()(U const& v) const {
123  stream_.pack(v);
124  }
125  private:
126  msgpack::packer<Stream>& stream_;
127  };
128 };
129 
130 template <typename T>
131 struct object_with_zone<T, typename msgpack::enable_if<boost::fusion::traits::is_sequence<T>::value>::type > {
132  void operator()(msgpack::object::with_zone& o, const T& v) const {
135  o.via.array.ptr = static_cast<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object)*size));
136  o.via.array.size = size;
137  uint32_t count = 0;
138  boost::fusion::for_each(v, with_zone_imp(o, count));
139  }
140 private:
141  struct with_zone_imp {
142  with_zone_imp(msgpack::object::with_zone const& obj, uint32_t& count):obj_(obj), count_(count) {}
143  template <typename U>
144  void operator()(U const& v) const {
145  obj_.via.array.ptr[count_++] = msgpack::object(v, obj_.zone);
146  }
147  msgpack::object::with_zone const& obj_;
148  uint32_t& count_;
149  };
150 };
151 
152 } // namespace adaptor
153 
155 } // MSGPACK_API_VERSION_NAMESPACE(v1)
157 
158 } // namespace msgpack
159 
160 #endif // MSGPACK_V1_TYPE_BOOST_FUSION_HPP
uint32_t size
Definition: object_fwd.hpp:23
void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
Definition: cpp03_zone.hpp:236
uint32_t checked_get_container_size(T size)
Definition: check_container_size.hpp:55
Definition: object_fwd_decl.hpp:62
union_type via
Definition: object_fwd.hpp:93
std::enable_if< msgpack::has_as< T >::value, T >::type as() const
Get value as T.
Definition: object.hpp:588
msgpack::zone & zone
Definition: object.hpp:36
msgpack::object * ptr
Definition: object_fwd.hpp:24
packer< Stream > & pack_array(uint32_t n)
Packing array header and size.
Definition: pack.hpp:1160
Definition: adaptor_base.hpp:15
Definition: object.hpp:34
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, const T &v) const
Definition: fusion.hpp:111
Definition: adaptor_base.hpp:43
tuple make_tuple()
Definition: cpp03_msgpack_tuple.hpp:10408
Definition: object_fwd.hpp:236
Definition: adaptor_base.hpp:32
std::size_t size(T const &t)
Definition: size_equal_only.hpp:24
msgpack::object_array array
Definition: object_fwd.hpp:85
Definition: cpp_config_decl.hpp:56
Object class that corresponding to MessagePack format object.
Definition: object_fwd.hpp:75
msgpack::type::object_type type
Definition: object_fwd.hpp:92
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58
Definition: object_fwd_decl.hpp:41
msgpack::object const & operator()(msgpack::object const &o, T &v) const
Definition: fusion.hpp:86
The class template that supports continuous packing.
Definition: adaptor_base_decl.hpp:24
Definition: adaptor_base.hpp:27
Definition: meta.hpp:40