annotate DEPENDENCIES/generic/include/boost/spirit/home/classic/dynamic/impl/switch.ipp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /*=============================================================================
Chris@16 2 Copyright (c) 2003 Hartmut Kaiser
Chris@16 3 http://spirit.sourceforge.net/
Chris@16 4
Chris@16 5 Use, modification and distribution is subject to the Boost Software
Chris@16 6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 =============================================================================*/
Chris@16 9 #ifndef BOOST_SPIRIT_SWITCH_IPP
Chris@16 10 #define BOOST_SPIRIT_SWITCH_IPP
Chris@16 11
Chris@16 12 #include <boost/mpl/if.hpp>
Chris@16 13 #include <boost/type_traits/is_same.hpp>
Chris@16 14 #include <boost/static_assert.hpp>
Chris@16 15
Chris@16 16 #include <boost/preprocessor/cat.hpp>
Chris@16 17 #include <boost/preprocessor/inc.hpp>
Chris@16 18 #include <boost/preprocessor/repeat.hpp>
Chris@16 19 #include <boost/preprocessor/repeat_from_to.hpp>
Chris@16 20
Chris@16 21 #include <boost/spirit/home/classic/core/parser.hpp>
Chris@16 22 #include <boost/spirit/home/classic/core/primitives/primitives.hpp>
Chris@16 23 #include <boost/spirit/home/classic/core/composite/composite.hpp>
Chris@16 24 #include <boost/spirit/home/classic/meta/as_parser.hpp>
Chris@16 25
Chris@16 26 #include <boost/spirit/home/classic/phoenix/actor.hpp>
Chris@16 27 #include <boost/spirit/home/classic/phoenix/tuples.hpp>
Chris@16 28
Chris@16 29 ///////////////////////////////////////////////////////////////////////////////
Chris@16 30 namespace boost { namespace spirit {
Chris@16 31
Chris@16 32 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
Chris@16 33
Chris@16 34 // forward declaration
Chris@16 35 template <int N, typename ParserT, bool IsDefault> struct case_parser;
Chris@16 36
Chris@16 37 ///////////////////////////////////////////////////////////////////////////////
Chris@16 38 namespace impl {
Chris@16 39
Chris@16 40 ///////////////////////////////////////////////////////////////////////////////
Chris@16 41 // parse helper functions
Chris@16 42 template <typename ParserT, typename ScannerT>
Chris@16 43 inline typename parser_result<ParserT, ScannerT>::type
Chris@16 44 delegate_parse(ParserT const &p, ScannerT const &scan,
Chris@16 45 typename ScannerT::iterator_t const save)
Chris@16 46 {
Chris@16 47 typedef typename parser_result<ParserT, ScannerT>::type result_t;
Chris@16 48
Chris@16 49 result_t result (p.subject().parse(scan));
Chris@16 50 if (!result)
Chris@16 51 scan.first = save;
Chris@16 52 return result;
Chris@16 53 }
Chris@16 54
Chris@16 55 ///////////////////////////////////////////////////////////////////////////////
Chris@16 56 // General default case handling (no default_p case branch given).
Chris@16 57 // First try to match the current parser node (if the condition value is
Chris@16 58 // matched) and, if that fails, return a no_match
Chris@16 59 template <int N, bool IsDefault, bool HasDefault>
Chris@16 60 struct default_delegate_parse {
Chris@16 61
Chris@16 62 template <
Chris@16 63 typename ParserT, typename DefaultT,
Chris@16 64 typename ValueT, typename ScannerT
Chris@16 65 >
Chris@16 66 static typename parser_result<ParserT, ScannerT>::type
Chris@16 67 parse (ValueT const &value, ParserT const &p, DefaultT const &,
Chris@16 68 ScannerT const &scan, typename ScannerT::iterator_t const save)
Chris@16 69 {
Chris@16 70 if (value == N)
Chris@16 71 return delegate_parse(p, scan, save);
Chris@16 72 return scan.no_match();
Chris@16 73 }
Chris@16 74 };
Chris@16 75
Chris@16 76 // The current case parser node is the default parser.
Chris@16 77 // Ignore the given case value and try to match the given default parser.
Chris@16 78 template <int N, bool HasDefault>
Chris@16 79 struct default_delegate_parse<N, true, HasDefault> {
Chris@16 80
Chris@16 81 template <
Chris@16 82 typename ParserT, typename DefaultT,
Chris@16 83 typename ValueT, typename ScannerT
Chris@16 84 >
Chris@16 85 static typename parser_result<ParserT, ScannerT>::type
Chris@16 86 parse (ValueT const& /*value*/, ParserT const &, DefaultT const &d,
Chris@16 87 ScannerT const &scan, typename ScannerT::iterator_t const save)
Chris@16 88 {
Chris@16 89 // Since there is a default_p case branch defined, the corresponding
Chris@16 90 // parser shouldn't be the nothing_parser
Chris@16 91 BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
Chris@16 92 return delegate_parse(d, scan, save);
Chris@16 93 }
Chris@16 94 };
Chris@16 95
Chris@16 96 // The current case parser node is not the default parser, but there is a
Chris@16 97 // default_p branch given inside the switch_p parser.
Chris@16 98 // First try to match the current parser node (if the condition value is
Chris@16 99 // matched) and, if that fails, match the given default_p parser.
Chris@16 100 template <int N>
Chris@16 101 struct default_delegate_parse<N, false, true> {
Chris@16 102
Chris@16 103 template <
Chris@16 104 typename ParserT, typename DefaultT,
Chris@16 105 typename ValueT, typename ScannerT
Chris@16 106 >
Chris@16 107 static typename parser_result<ParserT, ScannerT>::type
Chris@16 108 parse (ValueT const &value, ParserT const &p, DefaultT const &d,
Chris@16 109 ScannerT const &scan, typename ScannerT::iterator_t const save)
Chris@16 110 {
Chris@16 111 // Since there is a default_p case branch defined, the corresponding
Chris@16 112 // parser shouldn't be the nothing_parser
Chris@16 113 BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
Chris@16 114 if (value == N)
Chris@16 115 return delegate_parse(p, scan, save);
Chris@16 116
Chris@16 117 return delegate_parse(d, scan, save);
Chris@16 118 }
Chris@16 119 };
Chris@16 120
Chris@16 121 ///////////////////////////////////////////////////////////////////////////////
Chris@16 122 // Look through the case parser chain to test, if there is a default case
Chris@16 123 // branch defined (returned by 'value').
Chris@16 124 template <typename CaseT, bool IsSimple = CaseT::is_simple>
Chris@16 125 struct default_case;
Chris@16 126
Chris@16 127 ////////////////////////////////////////
Chris@16 128 template <typename ResultT, bool IsDefault>
Chris@16 129 struct get_default_parser {
Chris@16 130
Chris@16 131 template <typename ParserT>
Chris@16 132 static ResultT
Chris@16 133 get(parser<ParserT> const &p)
Chris@16 134 {
Chris@16 135 return default_case<typename ParserT::derived_t::left_t>::
Chris@16 136 get(p.derived().left());
Chris@16 137 }
Chris@16 138 };
Chris@16 139
Chris@16 140 template <typename ResultT>
Chris@16 141 struct get_default_parser<ResultT, true> {
Chris@16 142
Chris@16 143 template <typename ParserT>
Chris@16 144 static ResultT
Chris@16 145 get(parser<ParserT> const &p) { return p.derived().right(); }
Chris@16 146 };
Chris@16 147
Chris@16 148 ////////////////////////////////////////
Chris@16 149 template <typename CaseT, bool IsSimple>
Chris@16 150 struct default_case {
Chris@16 151
Chris@16 152 // The 'value' constant is true, if the current case_parser or one of its
Chris@16 153 // left siblings is a default_p generated case_parser.
Chris@16 154 BOOST_STATIC_CONSTANT(bool, value =
Chris@16 155 (CaseT::is_default || default_case<typename CaseT::left_t>::value));
Chris@16 156
Chris@16 157 // The 'is_epsilon' constant is true, if the current case_parser or one of
Chris@16 158 // its left siblings is a default_p generated parser with an attached
Chris@16 159 // epsilon_p (this is generated by the plain default_p).
Chris@16 160 BOOST_STATIC_CONSTANT(bool, is_epsilon = (
Chris@16 161 (CaseT::is_default && CaseT::is_epsilon) ||
Chris@16 162 default_case<typename CaseT::left_t>::is_epsilon
Chris@16 163 ));
Chris@16 164
Chris@16 165 // The computed 'type' represents the type of the default case branch
Chris@16 166 // parser (if there is one) or nothing_parser (if there isn't any default
Chris@16 167 // case branch).
Chris@16 168 typedef typename boost::mpl::if_c<
Chris@16 169 CaseT::is_default, typename CaseT::right_embed_t,
Chris@16 170 typename default_case<typename CaseT::left_t>::type
Chris@16 171 >::type type;
Chris@16 172
Chris@16 173 // The get function returns the parser attached to the default case branch
Chris@16 174 // (if there is one) or an instance of a nothing_parser (if there isn't
Chris@16 175 // any default case branch).
Chris@16 176 template <typename ParserT>
Chris@16 177 static type
Chris@16 178 get(parser<ParserT> const &p)
Chris@16 179 { return get_default_parser<type, CaseT::is_default>::get(p); }
Chris@16 180 };
Chris@16 181
Chris@16 182 ////////////////////////////////////////
Chris@16 183 template <typename ResultT, bool IsDefault>
Chris@16 184 struct get_default_parser_simple {
Chris@16 185
Chris@16 186 template <typename ParserT>
Chris@16 187 static ResultT
Chris@16 188 get(parser<ParserT> const &p) { return p.derived(); }
Chris@16 189 };
Chris@16 190
Chris@16 191 template <typename ResultT>
Chris@16 192 struct get_default_parser_simple<ResultT, false> {
Chris@16 193
Chris@16 194 template <typename ParserT>
Chris@16 195 static nothing_parser
Chris@16 196 get(parser<ParserT> const &) { return nothing_p; }
Chris@16 197 };
Chris@16 198
Chris@16 199 ////////////////////////////////////////
Chris@16 200 // Specialization of the default_case template for the last (leftmost) element
Chris@16 201 // of the case parser chain.
Chris@16 202 template <typename CaseT>
Chris@16 203 struct default_case<CaseT, true> {
Chris@16 204
Chris@16 205 // The 'value' and 'is_epsilon' constant, the 'type' type and the function
Chris@16 206 // 'get' are described above.
Chris@16 207
Chris@16 208 BOOST_STATIC_CONSTANT(bool, value = CaseT::is_default);
Chris@16 209 BOOST_STATIC_CONSTANT(bool, is_epsilon = (
Chris@16 210 CaseT::is_default && CaseT::is_epsilon
Chris@16 211 ));
Chris@16 212
Chris@16 213 typedef typename boost::mpl::if_c<
Chris@16 214 CaseT::is_default, CaseT, nothing_parser
Chris@16 215 >::type type;
Chris@16 216
Chris@16 217 template <typename ParserT>
Chris@16 218 static type
Chris@16 219 get(parser<ParserT> const &p)
Chris@16 220 { return get_default_parser_simple<type, value>::get(p); }
Chris@16 221 };
Chris@16 222
Chris@16 223 ///////////////////////////////////////////////////////////////////////////////
Chris@16 224 // The case_chain template calculates recursivly the depth of the left
Chris@16 225 // subchain of the given case branch node.
Chris@16 226 template <typename CaseT, bool IsSimple = CaseT::is_simple>
Chris@16 227 struct case_chain {
Chris@16 228
Chris@16 229 BOOST_STATIC_CONSTANT(int, depth = (
Chris@16 230 case_chain<typename CaseT::left_t>::depth + 1
Chris@16 231 ));
Chris@16 232 };
Chris@16 233
Chris@16 234 template <typename CaseT>
Chris@16 235 struct case_chain<CaseT, true> {
Chris@16 236
Chris@16 237 BOOST_STATIC_CONSTANT(int, depth = 0);
Chris@16 238 };
Chris@16 239
Chris@16 240 ///////////////////////////////////////////////////////////////////////////////
Chris@16 241 // The chain_parser template is used to extract the type and the instance of
Chris@16 242 // a left or a right parser, burried arbitrary deep inside the case parser
Chris@16 243 // chain.
Chris@16 244 template <int Depth, typename CaseT>
Chris@16 245 struct chain_parser {
Chris@16 246
Chris@16 247 typedef typename CaseT::left_t our_left_t;
Chris@16 248
Chris@16 249 typedef typename chain_parser<Depth-1, our_left_t>::left_t left_t;
Chris@16 250 typedef typename chain_parser<Depth-1, our_left_t>::right_t right_t;
Chris@16 251
Chris@16 252 static left_t
Chris@16 253 left(CaseT const &p)
Chris@16 254 { return chain_parser<Depth-1, our_left_t>::left(p.left()); }
Chris@16 255
Chris@16 256 static right_t
Chris@16 257 right(CaseT const &p)
Chris@16 258 { return chain_parser<Depth-1, our_left_t>::right(p.left()); }
Chris@16 259 };
Chris@16 260
Chris@16 261 template <typename CaseT>
Chris@16 262 struct chain_parser<1, CaseT> {
Chris@16 263
Chris@16 264 typedef typename CaseT::left_t left_t;
Chris@16 265 typedef typename CaseT::right_t right_t;
Chris@16 266
Chris@16 267 static left_t left(CaseT const &p) { return p.left(); }
Chris@16 268 static right_t right(CaseT const &p) { return p.right(); }
Chris@16 269 };
Chris@16 270
Chris@16 271 template <typename CaseT>
Chris@16 272 struct chain_parser<0, CaseT>; // shouldn't be instantiated
Chris@16 273
Chris@16 274 ///////////////////////////////////////////////////////////////////////////////
Chris@16 275 // Type computing meta function for calculating the type of the return value
Chris@16 276 // of the used conditional switch expression
Chris@16 277 template <typename TargetT, typename ScannerT>
Chris@16 278 struct condition_result {
Chris@16 279
Chris@16 280 typedef typename TargetT::template result<ScannerT>::type type;
Chris@16 281 };
Chris@16 282
Chris@16 283 ///////////////////////////////////////////////////////////////////////////////
Chris@16 284 template <typename LeftT, typename RightT, bool IsDefault>
Chris@16 285 struct compound_case_parser
Chris@16 286 : public binary<LeftT, RightT,
Chris@16 287 parser<compound_case_parser<LeftT, RightT, IsDefault> > >
Chris@16 288 {
Chris@16 289 typedef compound_case_parser<LeftT, RightT, IsDefault> self_t;
Chris@16 290 typedef binary_parser_category parser_category_t;
Chris@16 291 typedef binary<LeftT, RightT, parser<self_t> > base_t;
Chris@16 292
Chris@16 293 BOOST_STATIC_CONSTANT(int, value = RightT::value);
Chris@16 294 BOOST_STATIC_CONSTANT(bool, is_default = IsDefault);
Chris@16 295 BOOST_STATIC_CONSTANT(bool, is_simple = false);
Chris@16 296 BOOST_STATIC_CONSTANT(bool, is_epsilon = (
Chris@16 297 is_default &&
Chris@16 298 boost::is_same<typename RightT::subject_t, epsilon_parser>::value
Chris@16 299 ));
Chris@16 300
Chris@16 301 compound_case_parser(parser<LeftT> const &lhs, parser<RightT> const &rhs)
Chris@16 302 : base_t(lhs.derived(), rhs.derived())
Chris@16 303 {}
Chris@16 304
Chris@16 305 template <typename ScannerT>
Chris@16 306 struct result
Chris@16 307 {
Chris@16 308 typedef typename match_result<ScannerT, nil_t>::type type;
Chris@16 309 };
Chris@16 310
Chris@16 311 template <typename ScannerT, typename CondT>
Chris@16 312 typename parser_result<self_t, ScannerT>::type
Chris@16 313 parse(ScannerT const& scan, CondT const &cond) const;
Chris@16 314
Chris@16 315 template <int N1, typename ParserT1, bool IsDefault1>
Chris@16 316 compound_case_parser<
Chris@16 317 self_t, case_parser<N1, ParserT1, IsDefault1>, IsDefault1
Chris@16 318 >
Chris@16 319 operator, (case_parser<N1, ParserT1, IsDefault1> const &p) const
Chris@16 320 {
Chris@16 321 // If the following compile time assertion fires, you've probably used
Chris@16 322 // more than one default_p case inside the switch_p parser construct.
Chris@16 323 BOOST_STATIC_ASSERT(!default_case<self_t>::value || !IsDefault1);
Chris@16 324
Chris@16 325 // If this compile time assertion fires, you've probably want to use
Chris@16 326 // more case_p/default_p case branches, than possible.
Chris@16 327 BOOST_STATIC_ASSERT(
Chris@16 328 case_chain<self_t>::depth < BOOST_SPIRIT_SWITCH_CASE_LIMIT
Chris@16 329 );
Chris@16 330
Chris@16 331 typedef case_parser<N1, ParserT1, IsDefault1> right_t;
Chris@16 332 return compound_case_parser<self_t, right_t, IsDefault1>(*this, p);
Chris@16 333 }
Chris@16 334 };
Chris@16 335
Chris@16 336 ///////////////////////////////////////////////////////////////////////////////
Chris@16 337 // The parse_switch::do_ functions dispatch to the correct parser, which is
Chris@16 338 // selected through the given conditional switch value.
Chris@16 339 template <int Value, int Depth, bool IsDefault>
Chris@16 340 struct parse_switch;
Chris@16 341
Chris@16 342 ///////////////////////////////////////////////////////////////////////////////
Chris@16 343 //
Chris@16 344 // The following generates a couple of parse_switch template specializations
Chris@16 345 // with an increasing number of handled case branches (for 1..N).
Chris@16 346 //
Chris@16 347 // template <int Value, bool IsDefault>
Chris@16 348 // struct parse_switch<Value, N, IsDefault> {
Chris@16 349 //
Chris@16 350 // template <typename ParserT, typename ScannerT>
Chris@16 351 // static typename parser_result<ParserT, ScannerT>::type
Chris@16 352 // do_(ParserT const &p, ScannerT const &scan, long cond_value,
Chris@16 353 // typename ScannerT::iterator_t const &save)
Chris@16 354 // {
Chris@16 355 // typedef ParserT left_t0;
Chris@16 356 // typedef typename left_t0::left left_t1;
Chris@16 357 // ...
Chris@16 358 //
Chris@16 359 // switch (cond_value) {
Chris@16 360 // case left_tN::value:
Chris@16 361 // return delegate_parse(chain_parser<
Chris@16 362 // case_chain<ParserT>::depth, ParserT
Chris@16 363 // >::left(p), scan, save);
Chris@16 364 // ...
Chris@16 365 // case left_t1::value:
Chris@16 366 // return delegate_parse(chain_parser<
Chris@16 367 // 1, left_t1
Chris@16 368 // >::right(p.left()), scan, save);
Chris@16 369 //
Chris@16 370 // case left_t0::value:
Chris@16 371 // default:
Chris@16 372 // typedef default_case<ParserT> default_t;
Chris@16 373 // typedef default_delegate_parse<
Chris@16 374 // Value, IsDefault, default_t::value>
Chris@16 375 // default_parse_t;
Chris@16 376 //
Chris@16 377 // return default_parse_t::parse(cond_value, p.right(),
Chris@16 378 // default_t::get(p), scan, save);
Chris@16 379 // }
Chris@16 380 // }
Chris@16 381 // };
Chris@16 382 //
Chris@16 383 ///////////////////////////////////////////////////////////////////////////////
Chris@16 384 #define BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS(z, N, _) \
Chris@16 385 typedef typename BOOST_PP_CAT(left_t, N)::left_t \
Chris@16 386 BOOST_PP_CAT(left_t, BOOST_PP_INC(N)); \
Chris@16 387 /**/
Chris@16 388
Chris@16 389 #define BOOST_SPIRIT_PARSE_SWITCH_CASES(z, N, _) \
Chris@16 390 case (long)(BOOST_PP_CAT(left_t, N)::value): \
Chris@16 391 return delegate_parse(chain_parser<N, left_t1>::right(p.left()), \
Chris@16 392 scan, save); \
Chris@16 393 /**/
Chris@16 394
Chris@16 395 #define BOOST_SPIRIT_PARSE_SWITCHES(z, N, _) \
Chris@16 396 template <int Value, bool IsDefault> \
Chris@16 397 struct parse_switch<Value, BOOST_PP_INC(N), IsDefault> { \
Chris@16 398 \
Chris@16 399 template <typename ParserT, typename ScannerT> \
Chris@16 400 static typename parser_result<ParserT, ScannerT>::type \
Chris@16 401 do_(ParserT const &p, ScannerT const &scan, long cond_value, \
Chris@16 402 typename ScannerT::iterator_t const &save) \
Chris@16 403 { \
Chris@16 404 typedef ParserT left_t0; \
Chris@16 405 BOOST_PP_REPEAT_FROM_TO_ ## z(0, BOOST_PP_INC(N), \
Chris@16 406 BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS, _) \
Chris@16 407 \
Chris@16 408 switch (cond_value) { \
Chris@16 409 case (long)(BOOST_PP_CAT(left_t, BOOST_PP_INC(N))::value): \
Chris@16 410 return delegate_parse( \
Chris@16 411 chain_parser< \
Chris@16 412 case_chain<ParserT>::depth, ParserT \
Chris@101 413 >::left(p), scan, save); \
Chris@16 414 \
Chris@16 415 BOOST_PP_REPEAT_FROM_TO_ ## z(1, BOOST_PP_INC(N), \
Chris@16 416 BOOST_SPIRIT_PARSE_SWITCH_CASES, _) \
Chris@16 417 \
Chris@16 418 case (long)(left_t0::value): \
Chris@16 419 default: \
Chris@16 420 typedef default_case<ParserT> default_t; \
Chris@16 421 typedef \
Chris@16 422 default_delegate_parse<Value, IsDefault, default_t::value> \
Chris@16 423 default_parse_t; \
Chris@16 424 \
Chris@16 425 return default_parse_t::parse(cond_value, p.right(), \
Chris@16 426 default_t::get(p), scan, save); \
Chris@16 427 } \
Chris@16 428 } \
Chris@16 429 }; \
Chris@16 430 /**/
Chris@16 431
Chris@16 432 BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_SPIRIT_SWITCH_CASE_LIMIT),
Chris@16 433 BOOST_SPIRIT_PARSE_SWITCHES, _)
Chris@16 434
Chris@16 435 #undef BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS
Chris@16 436 #undef BOOST_SPIRIT_PARSE_SWITCH_CASES
Chris@16 437 #undef BOOST_SPIRIT_PARSE_SWITCHES
Chris@16 438 ///////////////////////////////////////////////////////////////////////////////
Chris@16 439
Chris@16 440 template <typename LeftT, typename RightT, bool IsDefault>
Chris@16 441 template <typename ScannerT, typename CondT>
Chris@16 442 inline typename parser_result<
Chris@16 443 compound_case_parser<LeftT, RightT, IsDefault>, ScannerT
Chris@16 444 >::type
Chris@16 445 compound_case_parser<LeftT, RightT, IsDefault>::
Chris@16 446 parse(ScannerT const& scan, CondT const &cond) const
Chris@16 447 {
Chris@16 448 scan.at_end(); // allow skipper to take effect
Chris@16 449 return parse_switch<value, case_chain<self_t>::depth, is_default>::
Chris@16 450 do_(*this, scan, cond(scan), scan.first);
Chris@16 451 }
Chris@16 452
Chris@16 453 ///////////////////////////////////////////////////////////////////////////////
Chris@16 454 // The switch condition is to be evaluated from a parser result value.
Chris@16 455 template <typename ParserT>
Chris@16 456 struct cond_functor {
Chris@16 457
Chris@16 458 typedef cond_functor<ParserT> self_t;
Chris@16 459
Chris@16 460 cond_functor(ParserT const &p_)
Chris@16 461 : p(p_)
Chris@16 462 {}
Chris@16 463
Chris@16 464 template <typename ScannerT>
Chris@16 465 struct result
Chris@16 466 {
Chris@16 467 typedef typename parser_result<ParserT, ScannerT>::type::attr_t type;
Chris@16 468 };
Chris@16 469
Chris@16 470 template <typename ScannerT>
Chris@16 471 typename condition_result<self_t, ScannerT>::type
Chris@16 472 operator()(ScannerT const &scan) const
Chris@16 473 {
Chris@16 474 typedef typename parser_result<ParserT, ScannerT>::type result_t;
Chris@16 475 typedef typename result_t::attr_t attr_t;
Chris@16 476
Chris@16 477 result_t result(p.parse(scan));
Chris@16 478 return !result ? attr_t() : result.value();
Chris@16 479 }
Chris@16 480
Chris@16 481 typename ParserT::embed_t p;
Chris@16 482 };
Chris@16 483
Chris@16 484 template <typename ParserT>
Chris@16 485 struct make_cond_functor {
Chris@16 486
Chris@16 487 typedef as_parser<ParserT> as_parser_t;
Chris@16 488
Chris@16 489 static cond_functor<typename as_parser_t::type>
Chris@16 490 do_(ParserT const &cond)
Chris@16 491 {
Chris@16 492 return cond_functor<typename as_parser_t::type>(
Chris@16 493 as_parser_t::convert(cond));
Chris@16 494 }
Chris@16 495 };
Chris@16 496
Chris@16 497 ///////////////////////////////////////////////////////////////////////////////
Chris@16 498 // The switch condition is to be evaluated from a phoenix actor
Chris@16 499 template <typename ActorT>
Chris@16 500 struct cond_actor {
Chris@16 501
Chris@16 502 typedef cond_actor<ActorT> self_t;
Chris@16 503
Chris@16 504 cond_actor(ActorT const &actor_)
Chris@16 505 : actor(actor_)
Chris@16 506 {}
Chris@16 507
Chris@16 508 template <typename ScannerT>
Chris@16 509 struct result
Chris@16 510 {
Chris@16 511 typedef typename ::phoenix::actor_result<ActorT, ::phoenix::tuple<> >::type
Chris@16 512 type;
Chris@16 513 };
Chris@16 514
Chris@16 515 template <typename ScannerT>
Chris@16 516 typename condition_result<self_t, ScannerT>::type
Chris@16 517 operator()(ScannerT const& /*scan*/) const
Chris@16 518 {
Chris@16 519 return actor();
Chris@16 520 }
Chris@16 521
Chris@16 522 ActorT const &actor;
Chris@16 523 };
Chris@16 524
Chris@16 525 template <typename ActorT>
Chris@16 526 struct make_cond_functor< ::phoenix::actor<ActorT> > {
Chris@16 527
Chris@16 528 static cond_actor< ::phoenix::actor<ActorT> >
Chris@16 529 do_(::phoenix::actor<ActorT> const &actor)
Chris@16 530 {
Chris@16 531 return cond_actor< ::phoenix::actor<ActorT> >(actor);
Chris@16 532 }
Chris@16 533 };
Chris@16 534
Chris@16 535 ///////////////////////////////////////////////////////////////////////////////
Chris@16 536 // The switch condition is to be taken directly from the input stream
Chris@16 537 struct get_next_token_cond {
Chris@16 538
Chris@16 539 typedef get_next_token_cond self_t;
Chris@16 540
Chris@16 541 template <typename ScannerT>
Chris@16 542 struct result
Chris@16 543 {
Chris@16 544 typedef typename ScannerT::value_t type;
Chris@16 545 };
Chris@16 546
Chris@16 547 template <typename ScannerT>
Chris@16 548 typename condition_result<self_t, ScannerT>::type
Chris@16 549 operator()(ScannerT const &scan) const
Chris@16 550 {
Chris@16 551 typename ScannerT::value_t val(*scan);
Chris@16 552 ++scan.first;
Chris@16 553 return val;
Chris@16 554 }
Chris@16 555 };
Chris@16 556
Chris@16 557 template <>
Chris@16 558 struct make_cond_functor<get_next_token_cond> {
Chris@16 559
Chris@16 560 static get_next_token_cond
Chris@16 561 do_(get_next_token_cond const &cond)
Chris@16 562 {
Chris@16 563 return cond;
Chris@16 564 }
Chris@16 565 };
Chris@16 566
Chris@16 567 ///////////////////////////////////////////////////////////////////////////////
Chris@16 568 } // namespace impl
Chris@16 569
Chris@16 570 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
Chris@16 571
Chris@16 572 }} // namespace boost::spirit
Chris@16 573
Chris@16 574 #endif // BOOST_SPIRIT_SWITCH_IPP