PageRenderTime 45ms CodeModel.GetById 21ms app.highlight 20ms RepoModel.GetById 2ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/spirit/home/karma/auto/meta_create.hpp

http://hadesmem.googlecode.com/
C++ Header | 339 lines | 261 code | 43 blank | 35 comment | 0 complexity | 9cfcc7249c02fa325cf542638675c8e7 MD5 | raw file
  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