Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:09:00

0001 /*=============================================================================
0002     Copyright (c) 2003 Hartmut Kaiser
0003     http://spirit.sourceforge.net/
0004 
0005   Distributed under the Boost Software License, Version 1.0. (See accompanying
0006   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 =============================================================================*/
0008 #ifndef BOOST_SPIRIT_SELECT_HPP
0009 #define BOOST_SPIRIT_SELECT_HPP
0010 
0011 #include <boost/preprocessor/repeat.hpp>
0012 #include <boost/preprocessor/enum.hpp>
0013 #include <boost/preprocessor/enum_params.hpp>
0014 #include <boost/preprocessor/enum_params_with_defaults.hpp>
0015 #include <boost/preprocessor/inc.hpp>
0016 #include <boost/preprocessor/cat.hpp>
0017 #include <boost/preprocessor/facilities/intercept.hpp>
0018 
0019 #include <boost/spirit/home/classic/namespace.hpp>
0020 #include <boost/spirit/home/classic/core/parser.hpp>
0021 
0022 #include <boost/spirit/home/classic/phoenix/tuples.hpp>
0023 
0024 ///////////////////////////////////////////////////////////////////////////////
0025 //
0026 //  Spirit predefined maximum number of possible embedded select_p parsers.
0027 //  It should NOT be greater than PHOENIX_LIMIT!
0028 //
0029 ///////////////////////////////////////////////////////////////////////////////
0030 #if !defined(BOOST_SPIRIT_SELECT_LIMIT)
0031 #define BOOST_SPIRIT_SELECT_LIMIT PHOENIX_LIMIT
0032 #endif // !defined(BOOST_SPIRIT_SELECT_LIMIT)
0033 
0034 ///////////////////////////////////////////////////////////////////////////////
0035 //
0036 // ensure   BOOST_SPIRIT_SELECT_LIMIT <= PHOENIX_LIMIT and 
0037 //          BOOST_SPIRIT_SELECT_LIMIT > 0
0038 //          BOOST_SPIRIT_SELECT_LIMIT <= 15
0039 //
0040 //  [Pushed this down a little to make CW happy with BOOST_STATIC_ASSERT]
0041 //  [Otherwise, it complains: 'boost_static_assert_test_42' redefined]
0042 //
0043 ///////////////////////////////////////////////////////////////////////////////
0044 BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT <= PHOENIX_LIMIT);
0045 BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT > 0);
0046 BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT <= 15);
0047 
0048 ///////////////////////////////////////////////////////////////////////////////
0049 //
0050 //  Calculate the required amount of tuple members rounded up to the nearest 
0051 //  integer dividable by 3
0052 //
0053 ///////////////////////////////////////////////////////////////////////////////
0054 #if BOOST_SPIRIT_SELECT_LIMIT > 12
0055 #define BOOST_SPIRIT_SELECT_LIMIT_A     15
0056 #elif BOOST_SPIRIT_SELECT_LIMIT > 9
0057 #define BOOST_SPIRIT_SELECT_LIMIT_A     12
0058 #elif BOOST_SPIRIT_SELECT_LIMIT > 6
0059 #define BOOST_SPIRIT_SELECT_LIMIT_A     9
0060 #elif BOOST_SPIRIT_SELECT_LIMIT > 3
0061 #define BOOST_SPIRIT_SELECT_LIMIT_A     6
0062 #else
0063 #define BOOST_SPIRIT_SELECT_LIMIT_A     3
0064 #endif
0065 
0066 ///////////////////////////////////////////////////////////////////////////////
0067 namespace boost { namespace spirit {
0068 
0069 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0070 
0071 ///////////////////////////////////////////////////////////////////////////////
0072 //
0073 //  The select_default_no_fail and select_default_fail structs are used to 
0074 //  distinguish two different behaviours for the select_parser in case that not
0075 //  any of the given sub-parsers match.
0076 //
0077 //  If the select_parser is used with the select_default_no_fail behaviour,
0078 //  then in case of no matching sub-parser the whole select_parser returns an
0079 //  empty match and the value -1.
0080 //
0081 //  If the select_parser is used with the select_default_fail behaviour, then
0082 //  in case of no matching sub-parser the whole select_parser fails to match at 
0083 //  all.
0084 //
0085 ///////////////////////////////////////////////////////////////////////////////
0086 struct select_default_no_fail {};
0087 struct select_default_fail {};
0088 
0089 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0090 
0091 }}  // namespace BOOST_SPIRIT_CLASSIC_NS
0092 
0093 ///////////////////////////////////////////////////////////////////////////////
0094 #include <boost/spirit/home/classic/dynamic/impl/select.ipp>
0095 
0096 ///////////////////////////////////////////////////////////////////////////////
0097 namespace boost { namespace spirit {
0098 
0099 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0100 
0101 ///////////////////////////////////////////////////////////////////////////////
0102 template <typename TupleT, typename BehaviourT, typename T>
0103 struct select_parser
0104 :   public parser<select_parser<TupleT, BehaviourT, T> >
0105 {
0106     typedef select_parser<TupleT, BehaviourT, T> self_t;
0107 
0108     select_parser(TupleT const &t_)
0109     :   t(t_)
0110     {}
0111     
0112     template <typename ScannerT>
0113     struct result
0114     {
0115         typedef typename match_result<ScannerT, T>::type type;
0116     };
0117 
0118     template <typename ScannerT>
0119     typename parser_result<self_t, ScannerT>::type
0120     parse(ScannerT const& scan) const
0121     {
0122         typedef typename parser_result<self_t, ScannerT>::type result_t;
0123         
0124         if (!scan.at_end()) {
0125             return impl::parse_tuple_element<
0126                 TupleT::length, result_t, TupleT, BehaviourT>::do_(t, scan);
0127         }
0128         return impl::select_match_gen<result_t, BehaviourT>::do_(scan);
0129     }
0130         
0131     TupleT const t;
0132 };
0133 
0134 ///////////////////////////////////////////////////////////////////////////////
0135 template <typename BehaviourT, typename T = int>
0136 struct select_parser_gen {
0137 
0138     ///////////////////////////////////////////////////////////////////////////
0139     //
0140     //  This generates different select_parser_gen::operator()() functions with 
0141     //  an increasing number of parser parameters:
0142     //
0143     //      template <typename ParserT0, ...>
0144     //      select_parser<
0145     //          ::phoenix::tuple<
0146     //              typename impl::as_embedded_parser<ParserT0>::type,
0147     //              ...
0148     //          >,
0149     //          BehaviourT,
0150     //          T
0151     //      >
0152     //      operator()(ParserT0 const &p0, ...) const
0153     //      {
0154     //          typedef impl::as_embedded_parser<ParserT0> parser_t0;
0155     //          ...
0156     //
0157     //          typedef ::phoenix::tuple< 
0158     //                  parser_t0::type,
0159     //                  ...
0160     //              > tuple_t; 
0161     //          typedef select_parser<tuple_t, BehaviourT, T> result_t;
0162     //
0163     //          return result_t(tuple_t(
0164     //                  parser_t0::convert(p0),
0165     //                  ...
0166     //              ));
0167     //      }
0168     //
0169     //  The number of generated functions depends on the maximum tuple member 
0170     //  limit defined by the PHOENIX_LIMIT pp constant. 
0171     //
0172     ///////////////////////////////////////////////////////////////////////////
0173     #define BOOST_SPIRIT_SELECT_EMBEDDED(z, N, _)                           \
0174         typename impl::as_embedded_parser<BOOST_PP_CAT(ParserT, N)>::type   \
0175         /**/
0176     #define BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF(z, N, _)                   \
0177         typedef impl::as_embedded_parser<BOOST_PP_CAT(ParserT, N)>          \
0178             BOOST_PP_CAT(parser_t, N);                                      \
0179         /**/
0180     #define BOOST_SPIRIT_SELECT_CONVERT(z, N, _)                            \
0181         BOOST_PP_CAT(parser_t, N)::convert(BOOST_PP_CAT(p, N))              \
0182         /**/
0183         
0184     #define BOOST_SPIRIT_SELECT_PARSER(z, N, _)                             \
0185         template <                                                          \
0186             BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ParserT)    \
0187         >                                                                   \
0188         select_parser<                                                      \
0189             ::phoenix::tuple<                                                 \
0190                 BOOST_PP_ENUM_ ## z(BOOST_PP_INC(N),                        \
0191                     BOOST_SPIRIT_SELECT_EMBEDDED, _)                        \
0192             >,                                                              \
0193             BehaviourT,                                                     \
0194             T                                                               \
0195         >                                                                   \
0196         operator()(                                                         \
0197             BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(N),               \
0198                 ParserT, const &p)                                          \
0199         ) const                                                             \
0200         {                                                                   \
0201             BOOST_PP_REPEAT_ ## z(BOOST_PP_INC(N),                          \
0202                 BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF, _)                    \
0203                                                                             \
0204             typedef ::phoenix::tuple<                                         \
0205                     BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(N),       \
0206                         typename parser_t, ::type BOOST_PP_INTERCEPT)       \
0207                 > tuple_t;                                                  \
0208             typedef select_parser<tuple_t, BehaviourT, T> result_t;         \
0209                                                                             \
0210             return result_t(tuple_t(                                        \
0211                     BOOST_PP_ENUM_ ## z(BOOST_PP_INC(N),                    \
0212                         BOOST_SPIRIT_SELECT_CONVERT, _)                     \
0213                 ));                                                         \
0214         }                                                                   \
0215         /**/
0216         
0217     BOOST_PP_REPEAT(BOOST_SPIRIT_SELECT_LIMIT_A, 
0218         BOOST_SPIRIT_SELECT_PARSER, _)
0219         
0220     #undef BOOST_SPIRIT_SELECT_PARSER
0221     #undef BOOST_SPIRIT_SELECT_CONVERT
0222     #undef BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF
0223     #undef BOOST_SPIRIT_SELECT_EMBEDDED
0224     ///////////////////////////////////////////////////////////////////////////
0225 };
0226 
0227 ///////////////////////////////////////////////////////////////////////////////
0228 //
0229 //  Predefined parser generator helper objects
0230 //
0231 ///////////////////////////////////////////////////////////////////////////////
0232 select_parser_gen<select_default_no_fail> const select_p = 
0233     select_parser_gen<select_default_no_fail>();
0234 
0235 select_parser_gen<select_default_fail> const select_fail_p = 
0236     select_parser_gen<select_default_fail>();
0237 
0238 #undef BOOST_SPIRIT_SELECT_LIMIT_A
0239 
0240 ///////////////////////////////////////////////////////////////////////////////
0241 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0242 
0243 }}  // namespace BOOST_SPIRIT_CLASSIC_NS
0244 
0245 #endif // BOOST_SPIRIT_SELECT_HPP