MessagePack for C++
Loading...
Searching...
No Matches
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
15#include "msgpack/object.hpp"
17#include "msgpack/meta.hpp"
18
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
44namespace msgpack {
45
49
50namespace adaptor {
51
52namespace detail {
53
54template <typename T>
56 static bool const value = false;
57};
58
59template <typename T, typename U>
60struct is_std_pair<std::pair<T, U> > {
61 static bool const value = true;
62};
63
64#if !defined(MSGPACK_USE_CPP03)
65
66template <typename T>
68 static bool const value = false;
69};
70
71template <typename... Args>
72struct is_std_tuple<std::tuple<Args...>> {
73 static bool const value = true;
74};
75
76#endif // !defined(MSGPACK_USE_CPP03)
77
78template <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
95template <typename T>
96struct 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
140template <typename T>
141struct 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(); }
144 if (o.via.array.size != checked_get_container_size(boost::fusion::size(v))) {
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 }
151private:
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
164template <typename T>
165struct pack<T, typename msgpack::enable_if<detail::is_seq_no_pair_no_tuple<T>::value>::type > {
166 template <typename Stream>
168 uint32_t size = checked_get_container_size(boost::fusion::size(v));
169 o.pack_array(size);
170 boost::fusion::for_each(v, pack_imp<Stream>(o));
171 return o;
172 }
173private:
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:
183 };
184};
185
186template <typename T>
187struct 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 {
189 uint32_t size = checked_get_container_size(boost::fusion::size(v));
190 o.type = msgpack::type::ARRAY;
192 o.via.array.size = size;
193 uint32_t count = 0;
194 boost::fusion::for_each(v, with_zone_imp(o, count));
195 }
196private:
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:1195
Definition object_fwd.hpp:231
void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
Definition cpp03_zone.hpp:255
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
static bool const value
Definition fusion.hpp:80
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
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, const T &v) const
Definition fusion.hpp:167
Definition adaptor_base.hpp:32
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
Definition meta.hpp:37
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