EVOLUTION-MANAGER
Edit File: select.hpp
/*============================================================================= Copyright (c) 2003 Hartmut Kaiser http://spirit.sourceforge.net/ 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) =============================================================================*/ #ifndef BOOST_SPIRIT_SELECT_HPP #define BOOST_SPIRIT_SELECT_HPP #include <boost/preprocessor/repeat.hpp> #include <boost/preprocessor/enum.hpp> #include <boost/preprocessor/enum_params.hpp> #include <boost/preprocessor/enum_params_with_defaults.hpp> #include <boost/preprocessor/inc.hpp> #include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/facilities/intercept.hpp> #include <boost/spirit/home/classic/namespace.hpp> #include <boost/spirit/home/classic/core/parser.hpp> #include <boost/spirit/home/classic/phoenix/tuples.hpp> /////////////////////////////////////////////////////////////////////////////// // // Spirit predefined maximum number of possible embedded select_p parsers. // It should NOT be greater than PHOENIX_LIMIT! // /////////////////////////////////////////////////////////////////////////////// #if !defined(BOOST_SPIRIT_SELECT_LIMIT) #define BOOST_SPIRIT_SELECT_LIMIT PHOENIX_LIMIT #endif // !defined(BOOST_SPIRIT_SELECT_LIMIT) /////////////////////////////////////////////////////////////////////////////// // // ensure BOOST_SPIRIT_SELECT_LIMIT <= PHOENIX_LIMIT and // BOOST_SPIRIT_SELECT_LIMIT > 0 // BOOST_SPIRIT_SELECT_LIMIT <= 15 // // [Pushed this down a little to make CW happy with BOOST_STATIC_ASSERT] // [Otherwise, it complains: 'boost_static_assert_test_42' redefined] // /////////////////////////////////////////////////////////////////////////////// BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT <= PHOENIX_LIMIT); BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT > 0); BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT <= 15); /////////////////////////////////////////////////////////////////////////////// // // Calculate the required amount of tuple members rounded up to the nearest // integer dividable by 3 // /////////////////////////////////////////////////////////////////////////////// #if BOOST_SPIRIT_SELECT_LIMIT > 12 #define BOOST_SPIRIT_SELECT_LIMIT_A 15 #elif BOOST_SPIRIT_SELECT_LIMIT > 9 #define BOOST_SPIRIT_SELECT_LIMIT_A 12 #elif BOOST_SPIRIT_SELECT_LIMIT > 6 #define BOOST_SPIRIT_SELECT_LIMIT_A 9 #elif BOOST_SPIRIT_SELECT_LIMIT > 3 #define BOOST_SPIRIT_SELECT_LIMIT_A 6 #else #define BOOST_SPIRIT_SELECT_LIMIT_A 3 #endif /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN /////////////////////////////////////////////////////////////////////////////// // // The select_default_no_fail and select_default_fail structs are used to // distinguish two different behaviours for the select_parser in case that not // any of the given sub-parsers match. // // If the select_parser is used with the select_default_no_fail behaviour, // then in case of no matching sub-parser the whole select_parser returns an // empty match and the value -1. // // If the select_parser is used with the select_default_fail behaviour, then // in case of no matching sub-parser the whole select_parser fails to match at // all. // /////////////////////////////////////////////////////////////////////////////// struct select_default_no_fail {}; struct select_default_fail {}; BOOST_SPIRIT_CLASSIC_NAMESPACE_END }} // namespace BOOST_SPIRIT_CLASSIC_NS /////////////////////////////////////////////////////////////////////////////// #include <boost/spirit/home/classic/dynamic/impl/select.ipp> /////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN /////////////////////////////////////////////////////////////////////////////// template <typename TupleT, typename BehaviourT, typename T> struct select_parser : public parser<select_parser<TupleT, BehaviourT, T> > { typedef select_parser<TupleT, BehaviourT, T> self_t; select_parser(TupleT const &t_) : t(t_) {} template <typename ScannerT> struct result { typedef typename match_result<ScannerT, T>::type type; }; template <typename ScannerT> typename parser_result<self_t, ScannerT>::type parse(ScannerT const& scan) const { typedef typename parser_result<self_t, ScannerT>::type result_t; if (!scan.at_end()) { return impl::parse_tuple_element< TupleT::length, result_t, TupleT, BehaviourT>::do_(t, scan); } return impl::select_match_gen<result_t, BehaviourT>::do_(scan); } TupleT const t; }; /////////////////////////////////////////////////////////////////////////////// template <typename BehaviourT, typename T = int> struct select_parser_gen { /////////////////////////////////////////////////////////////////////////// // // This generates different select_parser_gen::operator()() functions with // an increasing number of parser parameters: // // template <typename ParserT0, ...> // select_parser< // ::phoenix::tuple< // typename impl::as_embedded_parser<ParserT0>::type, // ... // >, // BehaviourT, // T // > // operator()(ParserT0 const &p0, ...) const // { // typedef impl::as_embedded_parser<ParserT0> parser_t0; // ... // // typedef ::phoenix::tuple< // parser_t0::type, // ... // > tuple_t; // typedef select_parser<tuple_t, BehaviourT, T> result_t; // // return result_t(tuple_t( // parser_t0::convert(p0), // ... // )); // } // // The number of generated functions depends on the maximum tuple member // limit defined by the PHOENIX_LIMIT pp constant. // /////////////////////////////////////////////////////////////////////////// #define BOOST_SPIRIT_SELECT_EMBEDDED(z, N, _) \ typename impl::as_embedded_parser<BOOST_PP_CAT(ParserT, N)>::type \ /**/ #define BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF(z, N, _) \ typedef impl::as_embedded_parser<BOOST_PP_CAT(ParserT, N)> \ BOOST_PP_CAT(parser_t, N); \ /**/ #define BOOST_SPIRIT_SELECT_CONVERT(z, N, _) \ BOOST_PP_CAT(parser_t, N)::convert(BOOST_PP_CAT(p, N)) \ /**/ #define BOOST_SPIRIT_SELECT_PARSER(z, N, _) \ template < \ BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ParserT) \ > \ select_parser< \ ::phoenix::tuple< \ BOOST_PP_ENUM_ ## z(BOOST_PP_INC(N), \ BOOST_SPIRIT_SELECT_EMBEDDED, _) \ >, \ BehaviourT, \ T \ > \ operator()( \ BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(N), \ ParserT, const &p) \ ) const \ { \ BOOST_PP_REPEAT_ ## z(BOOST_PP_INC(N), \ BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF, _) \ \ typedef ::phoenix::tuple< \ BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(N), \ typename parser_t, ::type BOOST_PP_INTERCEPT) \ > tuple_t; \ typedef select_parser<tuple_t, BehaviourT, T> result_t; \ \ return result_t(tuple_t( \ BOOST_PP_ENUM_ ## z(BOOST_PP_INC(N), \ BOOST_SPIRIT_SELECT_CONVERT, _) \ )); \ } \ /**/ BOOST_PP_REPEAT(BOOST_SPIRIT_SELECT_LIMIT_A, BOOST_SPIRIT_SELECT_PARSER, _) #undef BOOST_SPIRIT_SELECT_PARSER #undef BOOST_SPIRIT_SELECT_CONVERT #undef BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF #undef BOOST_SPIRIT_SELECT_EMBEDDED /////////////////////////////////////////////////////////////////////////// }; /////////////////////////////////////////////////////////////////////////////// // // Predefined parser generator helper objects // /////////////////////////////////////////////////////////////////////////////// select_parser_gen<select_default_no_fail> const select_p = select_parser_gen<select_default_no_fail>(); select_parser_gen<select_default_fail> const select_fail_p = select_parser_gen<select_default_fail>(); #undef BOOST_SPIRIT_SELECT_LIMIT_A /////////////////////////////////////////////////////////////////////////////// BOOST_SPIRIT_CLASSIC_NAMESPACE_END }} // namespace BOOST_SPIRIT_CLASSIC_NS #endif // BOOST_SPIRIT_SELECT_HPP