/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
- // Copyright (c) 2001-2010 Hartmut Kaiser
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- #if !defined(BOOST_SPIRIT_QI_META_CREATE_NOV_21_2009_0432PM)
- #define BOOST_SPIRIT_QI_META_CREATE_NOV_21_2009_0432PM
- #if defined(_MSC_VER)
- #pragma once
- #endif
- #include <boost/spirit/home/qi/domain.hpp>
- #include <boost/spirit/home/support/common_terminals.hpp>
- #include <boost/spirit/home/support/auto/meta_create.hpp>
- #include <boost/utility/enable_if.hpp>
- #include <boost/variant.hpp>
- #include <boost/optional.hpp>
- #include <boost/config.hpp>
- #include <boost/mpl/and.hpp>
- #include <boost/mpl/not.hpp>
- #include <boost/mpl/fold.hpp>
- #include <boost/mpl/vector.hpp>
- #include <boost/mpl/push_back.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <boost/fusion/include/as_vector.hpp>
- ///////////////////////////////////////////////////////////////////////////////
- namespace boost { namespace spirit { namespace qi
- {
- ///////////////////////////////////////////////////////////////////////////
- // compatible STL containers
- template <typename Container>
- struct meta_create_container
- {
- typedef make_unary_proto_expr<
- typename Container::value_type
- , proto::tag::dereference, qi::domain
- > make_proto_expr;
- typedef typename make_proto_expr::type type;
- static type call()
- {
- return make_proto_expr::call();
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- // Fusion sequences
- template <typename Sequence>
- struct meta_create_sequence
- {
- // create a mpl sequence from the given fusion sequence
- typedef typename mpl::fold<
- typename fusion::result_of::as_vector<Sequence>::type
- , mpl::vector<>, mpl::push_back<mpl::_, mpl::_>
- >::type sequence_type;
- typedef make_nary_proto_expr<
- sequence_type, proto::tag::shift_right, qi::domain
- > make_proto_expr;
- typedef typename make_proto_expr::type type;
- static type call()
- {
- return make_proto_expr::call();
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- // the default is to use the standard streaming operator unless it's a
- // STL container or a fusion sequence
- // The default implementation will be chosen if no predefined mapping of
- // the data type T to a Qi component is defined.
- struct no_auto_mapping_exists {};
- template <typename T, typename Enable = void>
- struct meta_create_impl : mpl::identity<no_auto_mapping_exists> {};
- template <typename T>
- struct meta_create_impl<T
- , typename enable_if<mpl::and_<
- traits::is_container<T>, mpl::not_<traits::is_string<T> > >
- >::type>
- : meta_create_container<T> {};
- template <typename T>
- struct meta_create_impl<T
- , typename enable_if<fusion::traits::is_sequence<T> >::type>
- : meta_create_sequence<T> {};
- template <typename T, typename Enable = void>
- struct meta_create : meta_create_impl<T> {};
- ///////////////////////////////////////////////////////////////////////////
- // optional
- template <typename T>
- struct meta_create<boost::optional<T> >
- {
- typedef make_unary_proto_expr<
- T, proto::tag::negate, qi::domain
- > make_proto_expr;
- typedef typename make_proto_expr::type type;
- static type call()
- {
- return make_proto_expr::call();
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- // alternatives
- template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
- struct meta_create<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
- {
- typedef make_nary_proto_expr<
- typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
- , proto::tag::bitwise_or, qi::domain
- > make_proto_expr;
- typedef typename make_proto_expr::type type;
- static type call()
- {
- return make_proto_expr::call();
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- // predefined specializations for primitive components
- // character generator
- template <>
- struct meta_create<char>
- {
- typedef spirit::standard::char_type type;
- static type const& call() { return spirit::standard::char_; }
- };
- template <>
- struct meta_create<wchar_t>
- {
- typedef spirit::standard_wide::char_type type;
- static type const& call() { return spirit::standard_wide::char_; }
- };
- // boolean generator
- template <>
- struct meta_create<bool>
- {
- typedef spirit::bool__type type;
- static type const& call() { return spirit::bool_; }
- };
- // integral generators
- template <>
- struct meta_create<int>
- {
- typedef spirit::int__type type;
- static type const& call() { return spirit::int_; }
- };
- template <>
- struct meta_create<short>
- {
- typedef spirit::short__type type;
- static type const& call() { return spirit::short_; }
- };
- template <>
- struct meta_create<long>
- {
- typedef spirit::long__type type;
- static type const& call() { return spirit::long_; }
- };
- template <>
- struct meta_create<unsigned int>
- {
- typedef spirit::uint__type type;
- static type const& call() { return spirit::uint_; }
- };
- #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
- template <>
- struct meta_create<unsigned short>
- {
- typedef spirit::ushort__type type;
- static type const& call() { return spirit::ushort_; }
- };
- #endif
- template <>
- struct meta_create<unsigned long>
- {
- typedef spirit::ulong__type type;
- static type const& call() { return spirit::ulong_; }
- };
- #ifdef BOOST_HAS_LONG_LONG
- template <>
- struct meta_create<boost::long_long_type>
- {
- typedef spirit::long_long_type type;
- static type const& call() { return spirit::long_long; }
- };
- template <>
- struct meta_create<boost::ulong_long_type>
- {
- typedef spirit::ulong_long_type type;
- static type const& call() { return spirit::ulong_long; }
- };
- #endif
- // floating point generators
- template <>
- struct meta_create<float>
- {
- typedef spirit::float__type type;
- static type const& call() { return spirit::float_; }
- };
- template <>
- struct meta_create<double>
- {
- typedef spirit::double__type type;
- static type const& call() { return spirit::double_; }
- };
- template <>
- struct meta_create<long double>
- {
- typedef spirit::long_double_type type;
- static type const& call() { return spirit::long_double; }
- };
- }}}
- ///////////////////////////////////////////////////////////////////////////////
- namespace boost { namespace spirit { namespace traits
- {
- ///////////////////////////////////////////////////////////////////////////
- // main customization point for create_parser
- template <typename T, typename Enable = void>
- struct create_parser : qi::meta_create<T> {};
- ///////////////////////////////////////////////////////////////////////////
- // dispatch this to the qi related specializations
- template <typename T>
- struct meta_create<qi::domain, T>
- : create_parser<typename spirit::detail::remove_const_ref<T>::type> {};
- ///////////////////////////////////////////////////////////////////////////
- // Check whether a valid mapping exits for the given data type to a Karma
- // component
- template <typename T>
- struct meta_create_exists<qi::domain, T>
- : mpl::not_<is_same<
- qi::no_auto_mapping_exists
- , typename meta_create<qi::domain, T>::type
- > > {};
- }}}
- #endif