PageRenderTime 38ms CodeModel.GetById 21ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 1ms

/src/contrib/boost/spirit/home/qi/auto/meta_create.hpp

http://pythonocc.googlecode.com/
C++ Header | 260 lines | 194 code | 33 blank | 33 comment | 0 complexity | 71c5c2041cbc4bfbf5d99dd277296dfc MD5 | raw file
  1//  Copyright (c) 2001-2010 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_QI_META_CREATE_NOV_21_2009_0432PM)
  7#define BOOST_SPIRIT_QI_META_CREATE_NOV_21_2009_0432PM
  8
  9#if defined(_MSC_VER)
 10#pragma once
 11#endif
 12
 13#include <boost/spirit/home/qi/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/and.hpp>
 22#include <boost/mpl/not.hpp>
 23#include <boost/mpl/fold.hpp>
 24#include <boost/mpl/vector.hpp>
 25#include <boost/mpl/push_back.hpp>
 26#include <boost/type_traits/is_same.hpp>
 27#include <boost/fusion/include/as_vector.hpp>
 28
 29///////////////////////////////////////////////////////////////////////////////
 30namespace boost { namespace spirit { namespace qi
 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, qi::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    // Fusion sequences
 52    template <typename Sequence>
 53    struct meta_create_sequence
 54    {
 55        // create a mpl sequence from the given fusion sequence
 56        typedef typename mpl::fold<
 57            typename fusion::result_of::as_vector<Sequence>::type
 58          , mpl::vector<>, mpl::push_back<mpl::_, mpl::_>
 59        >::type sequence_type;
 60
 61        typedef make_nary_proto_expr<
 62            sequence_type, proto::tag::shift_right, qi::domain
 63        > make_proto_expr;
 64
 65        typedef typename make_proto_expr::type type;
 66
 67        static type call()
 68        {
 69            return make_proto_expr::call();
 70        }
 71    };
 72
 73    ///////////////////////////////////////////////////////////////////////////
 74    // the default is to use the standard streaming operator unless it's a
 75    // STL container or a fusion sequence
 76
 77    // The default implementation will be chosen if no predefined mapping of
 78    // the data type T to a Qi component is defined.
 79    struct no_auto_mapping_exists {};
 80
 81    template <typename T, typename Enable = void>
 82    struct meta_create_impl : mpl::identity<no_auto_mapping_exists> {};
 83
 84    template <typename T>
 85    struct meta_create_impl<T
 86          , typename enable_if<mpl::and_<
 87                traits::is_container<T>, mpl::not_<traits::is_string<T> > >
 88            >::type>
 89      : meta_create_container<T> {};
 90
 91    template <typename T>
 92    struct meta_create_impl<T
 93          , typename enable_if<fusion::traits::is_sequence<T> >::type>
 94      : meta_create_sequence<T> {};
 95
 96    template <typename T, typename Enable = void>
 97    struct meta_create : meta_create_impl<T> {};
 98
 99    ///////////////////////////////////////////////////////////////////////////
100    // optional
101    template <typename T>
102    struct meta_create<boost::optional<T> >
103    {
104        typedef make_unary_proto_expr<
105            T, proto::tag::negate, qi::domain
106        > make_proto_expr;
107
108        typedef typename make_proto_expr::type type;
109
110        static type call()
111        {
112            return make_proto_expr::call();
113        }
114    };
115
116    ///////////////////////////////////////////////////////////////////////////
117    // alternatives
118    template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
119    struct meta_create<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
120    {
121        typedef make_nary_proto_expr<
122            typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
123          , proto::tag::bitwise_or, qi::domain
124        > make_proto_expr;
125
126        typedef typename make_proto_expr::type type;
127
128        static type call()
129        {
130            return make_proto_expr::call();
131        }
132    };
133
134    ///////////////////////////////////////////////////////////////////////////
135    // predefined specializations for primitive components
136
137    // character generator
138    template <>
139    struct meta_create<char>
140    {
141        typedef spirit::standard::char_type type;
142        static type const& call() { return spirit::standard::char_; }
143    };
144    template <>
145    struct meta_create<wchar_t>
146    {
147        typedef spirit::standard_wide::char_type type;
148        static type const& call() { return spirit::standard_wide::char_; }
149    };
150
151    // boolean generator
152    template <>
153    struct meta_create<bool>
154    {
155        typedef spirit::bool__type type;
156        static type const& call() { return spirit::bool_; }
157    };
158
159    // integral generators
160    template <>
161    struct meta_create<int>
162    {
163        typedef spirit::int__type type;
164        static type const& call() { return spirit::int_; }
165    };
166    template <>
167    struct meta_create<short>
168    {
169        typedef spirit::short__type type;
170        static type const& call() { return spirit::short_; }
171    };
172    template <>
173    struct meta_create<long>
174    {
175        typedef spirit::long__type type;
176        static type const& call() { return spirit::long_; }
177    };
178    template <>
179    struct meta_create<unsigned int>
180    {
181        typedef spirit::uint__type type;
182        static type const& call() { return spirit::uint_; }
183    };
184#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
185    template <>
186    struct meta_create<unsigned short>
187    {
188        typedef spirit::ushort__type type;
189        static type const& call() { return spirit::ushort_; }
190    };
191#endif
192    template <>
193    struct meta_create<unsigned long>
194    {
195        typedef spirit::ulong__type type;
196        static type const& call() { return spirit::ulong_; }
197    };
198
199#ifdef BOOST_HAS_LONG_LONG
200    template <>
201    struct meta_create<boost::long_long_type>
202    {
203        typedef spirit::long_long_type type;
204        static type const& call() { return spirit::long_long; }
205    };
206    template <>
207    struct meta_create<boost::ulong_long_type>
208    {
209        typedef spirit::ulong_long_type type;
210        static type const& call() { return spirit::ulong_long; }
211    };
212#endif
213
214    // floating point generators
215    template <>
216    struct meta_create<float>
217    {
218        typedef spirit::float__type type;
219        static type const& call() { return spirit::float_; }
220    };
221    template <>
222    struct meta_create<double>
223    {
224        typedef spirit::double__type type;
225        static type const& call() { return spirit::double_; }
226    };
227    template <>
228    struct meta_create<long double>
229    {
230        typedef spirit::long_double_type type;
231        static type const& call() { return spirit::long_double; }
232    };
233}}}
234
235///////////////////////////////////////////////////////////////////////////////
236namespace boost { namespace spirit { namespace traits
237{
238    ///////////////////////////////////////////////////////////////////////////
239    // main customization point for create_parser
240    template <typename T, typename Enable = void>
241    struct create_parser : qi::meta_create<T> {};
242
243    ///////////////////////////////////////////////////////////////////////////
244    // dispatch this to the qi related specializations
245    template <typename T>
246    struct meta_create<qi::domain, T>
247      : create_parser<typename spirit::detail::remove_const_ref<T>::type> {};
248
249    ///////////////////////////////////////////////////////////////////////////
250    // Check whether a valid mapping exits for the given data type to a Karma
251    // component
252    template <typename T>
253    struct meta_create_exists<qi::domain, T>
254      : mpl::not_<is_same<
255            qi::no_auto_mapping_exists
256          , typename meta_create<qi::domain, T>::type
257        > > {};
258}}}
259
260#endif