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