]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/spirit/home/karma/auto/meta_create.hpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / boost / spirit / home / karma / auto / meta_create.hpp
CommitLineData
7c673cae
FG
1// Copyright (c) 2001-2011 Hartmut Kaiser
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#if !defined(BOOST_SPIRIT_KARMA_META_CREATE_NOV_21_2009_0425PM)
7#define BOOST_SPIRIT_KARMA_META_CREATE_NOV_21_2009_0425PM
8
9#if defined(_MSC_VER)
10#pragma once
11#endif
12
13#include <boost/spirit/home/karma/domain.hpp>
14#include <boost/spirit/home/support/common_terminals.hpp>
15#include <boost/spirit/home/support/auto/meta_create.hpp>
16
17#include <boost/utility/enable_if.hpp>
18#include <boost/variant.hpp>
19#include <boost/optional.hpp>
20#include <boost/config.hpp>
21#include <boost/mpl/not.hpp>
22#include <boost/mpl/fold.hpp>
23#include <boost/mpl/vector.hpp>
24#include <boost/mpl/push_back.hpp>
25#include <boost/fusion/include/as_vector.hpp>
f67539c2 26#include <boost/proto/tags.hpp>
7c673cae
FG
27#include <boost/type_traits/is_same.hpp>
28
29///////////////////////////////////////////////////////////////////////////////
30namespace boost { namespace spirit { namespace karma
31{
32 ///////////////////////////////////////////////////////////////////////////
33 // compatible STL containers
34 template <typename Container>
35 struct meta_create_container
36 {
37 typedef make_unary_proto_expr<
38 typename Container::value_type
39 , proto::tag::dereference, karma::domain
40 > make_proto_expr;
41
42 typedef typename make_proto_expr::type type;
43
44 static type call()
45 {
46 return make_proto_expr::call();
47 }
48 };
49
50 ///////////////////////////////////////////////////////////////////////////
51 // String types
52 template <typename String>
53 struct meta_create_string
54 {
55 typedef spirit::standard::string_type type;
56 static type const call() { return type(); }
57 };
58
59 template <>
60 struct meta_create_string<wchar_t*>
61 {
62 typedef spirit::standard_wide::string_type type;
63 static type const call() { return type(); }
64 };
65
66 template <>
67 struct meta_create_string<wchar_t const*>
68 {
69 typedef spirit::standard_wide::string_type type;
70 static type const call() { return type(); }
71 };
72
73 template <int N>
74 struct meta_create_string<wchar_t[N]>
75 {
76 typedef spirit::standard_wide::string_type type;
77 static type const call() { return type(); }
78 };
79
80 template <int N>
81 struct meta_create_string<wchar_t const[N]>
82 {
83 typedef spirit::standard_wide::string_type type;
84 static type const call() { return type(); }
85 };
86
87 template <int N>
88 struct meta_create_string<wchar_t(&)[N]>
89 {
90 typedef spirit::standard_wide::string_type type;
91 static type const call() { return type(); }
92 };
93
94 template <int N>
95 struct meta_create_string<wchar_t const(&)[N]>
96 {
97 typedef spirit::standard_wide::string_type type;
98 static type const call() { return type(); }
99 };
100
101 template <typename Traits, typename Allocator>
102 struct meta_create_string<std::basic_string<wchar_t, Traits, Allocator> >
103 {
104 typedef spirit::standard_wide::string_type type;
105 static type const call() { return type(); }
106 };
107
108 ///////////////////////////////////////////////////////////////////////////
109 // Fusion sequences
110 template <typename Sequence>
111 struct meta_create_sequence
112 {
113 // create a mpl sequence from the given fusion sequence
114 typedef typename mpl::fold<
115 typename fusion::result_of::as_vector<Sequence>::type
116 , mpl::vector<>, mpl::push_back<mpl::_, mpl::_>
117 >::type sequence_type;
118
119 typedef make_nary_proto_expr<
120 sequence_type, proto::tag::shift_left, karma::domain
121 > make_proto_expr;
122
123 typedef typename make_proto_expr::type type;
124
125 static type call()
126 {
127 return make_proto_expr::call();
128 }
129 };
130
131 ///////////////////////////////////////////////////////////////////////////
132 // the default is to use the standard streaming operator unless it's a
133 // STL container or a fusion sequence
134
135 // The default implementation will be chosen if no predefined mapping of
136 // the data type T to a Karma component is defined.
137 struct no_auto_mapping_exists {};
138
139 template <typename T, typename Enable = void>
140 struct meta_create_impl : mpl::identity<no_auto_mapping_exists> {};
141
142 template <typename T>
143 struct meta_create_impl<T
144 , typename enable_if<
145 mpl::and_<
146 traits::is_container<T>
147 , mpl::not_<traits::is_string<T> >
148 , mpl::not_<fusion::traits::is_sequence<T> >
149 > >::type>
150 : meta_create_container<T> {};
151
152 template <typename T>
153 struct meta_create_impl<T
154 , typename enable_if<traits::is_string<T> >::type>
155 : meta_create_string<T> {};
156
157 template <typename T>
158 struct meta_create_impl<T, typename enable_if<
159 spirit::detail::is_fusion_sequence_but_not_proto_expr<T>
160 >::type>
161 : meta_create_sequence<T> {};
162
163 template <typename T, typename Enable = void>
164 struct meta_create : meta_create_impl<T> {};
165
166 ///////////////////////////////////////////////////////////////////////////
167 // optional
168 template <typename T>
169 struct meta_create<boost::optional<T> >
170 {
171 typedef make_unary_proto_expr<
172 T, proto::tag::negate, karma::domain
173 > make_proto_expr;
174
175 typedef typename make_proto_expr::type type;
176
177 static type call()
178 {
179 return make_proto_expr::call();
180 }
181 };
182
183 ///////////////////////////////////////////////////////////////////////////
184 // alternatives
185 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
186 struct meta_create<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
187 {
188 typedef make_nary_proto_expr<
189 typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
190 , proto::tag::bitwise_or, karma::domain
191 > make_proto_expr;
192
193 typedef typename make_proto_expr::type type;
194
195 static type call()
196 {
197 return make_proto_expr::call();
198 }
199 };
200
201 ///////////////////////////////////////////////////////////////////////////
202 // predefined specializations for primitive components
203
204 // character generator
205 template <>
206 struct meta_create<char>
207 {
208 typedef spirit::standard::char_type type;
209 static type const call() { return type(); }
210 };
211 template <>
212 struct meta_create<signed char>
213 {
214 typedef spirit::standard::char_type type;
215 static type const call() { return type(); }
216 };
217 template <>
218 struct meta_create<wchar_t>
219 {
220 typedef spirit::standard_wide::char_type type;
221 static type const call() { return type(); }
222 };
223
224 template <>
225 struct meta_create<unsigned char>
226 {
227 typedef spirit::standard::char_type type;
228 static type const call() { return type(); }
229 };
230
231 // boolean generator
232 template <>
233 struct meta_create<bool>
234 {
235 typedef spirit::bool_type type;
236 static type call() { return type(); }
237 };
238
239 // integral generators
240 template <>
241 struct meta_create<int>
242 {
243 typedef spirit::int_type type;
244 static type call() { return type(); }
245 };
246 template <>
247 struct meta_create<short>
248 {
249 typedef spirit::short_type type;
250 static type call() { return type(); }
251 };
252 template <>
253 struct meta_create<long>
254 {
255 typedef spirit::long_type type;
256 static type call() { return type(); }
257 };
258 template <>
259 struct meta_create<unsigned int>
260 {
261 typedef spirit::uint_type type;
262 static type call() { return type(); }
263 };
264#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
265 template <>
266 struct meta_create<unsigned short>
267 {
268 typedef spirit::ushort_type type;
269 static type call() { return type(); }
270 };
271#endif
272 template <>
273 struct meta_create<unsigned long>
274 {
275 typedef spirit::ulong_type type;
276 static type call() { return type(); }
277 };
278
279#ifdef BOOST_HAS_LONG_LONG
280 template <>
281 struct meta_create<boost::long_long_type>
282 {
283 typedef spirit::long_long_type type;
284 static type call() { return type(); }
285 };
286 template <>
287 struct meta_create<boost::ulong_long_type>
288 {
289 typedef spirit::ulong_long_type type;
290 static type call() { return type(); }
291 };
292#endif
293
294 // floating point generators
295 template <>
296 struct meta_create<float>
297 {
298 typedef spirit::float_type type;
299 static type call() { return type(); }
300 };
301 template <>
302 struct meta_create<double>
303 {
304 typedef spirit::double_type type;
305 static type call() { return type(); }
306 };
307 template <>
308 struct meta_create<long double>
309 {
310 typedef spirit::long_double_type type;
311 static type call() { return type(); }
312 };
313}}}
314
315///////////////////////////////////////////////////////////////////////////////
316namespace boost { namespace spirit { namespace traits
317{
318 ///////////////////////////////////////////////////////////////////////////
319 // main customization point for create_generator
320 template <typename T, typename Enable = void>
321 struct create_generator : karma::meta_create<T> {};
322
323 ///////////////////////////////////////////////////////////////////////////
324 // dispatch this to the karma related specializations
325 template <typename T>
326 struct meta_create<karma::domain, T>
327 : create_generator<typename spirit::detail::remove_const_ref<T>::type> {};
328
329 ///////////////////////////////////////////////////////////////////////////
330 // Check whether a valid mapping exits for the given data type to a Karma
331 // component
332 template <typename T>
333 struct meta_create_exists<karma::domain, T>
334 : mpl::not_<is_same<
335 karma::no_auto_mapping_exists
336 , typename meta_create<karma::domain, T>::type
337 > > {};
338}}}
339
340#endif