annotate DEPENDENCIES/generic/include/boost/spirit/home/support/terminal.hpp @ 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) 2001-2011 Joel de Guzman
Chris@16 3 Copyright (c) 2001-2011 Hartmut Kaiser
Chris@16 4 Copyright (c) 2011 Thomas Heller
Chris@16 5
Chris@16 6 Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 ==============================================================================*/
Chris@16 9 #if !defined(BOOST_SPIRIT_TERMINAL_NOVEMBER_04_2008_0906AM)
Chris@16 10 #define BOOST_SPIRIT_TERMINAL_NOVEMBER_04_2008_0906AM
Chris@16 11
Chris@16 12 #if defined(_MSC_VER)
Chris@16 13 #pragma once
Chris@16 14 #endif
Chris@16 15
Chris@16 16 #include <boost/spirit/include/phoenix_core.hpp>
Chris@16 17 #include <boost/spirit/include/phoenix_function.hpp>
Chris@16 18 #include <boost/proto/proto.hpp>
Chris@16 19 #include <boost/fusion/include/void.hpp>
Chris@16 20 #include <boost/spirit/home/support/meta_compiler.hpp>
Chris@16 21 #include <boost/spirit/home/support/detail/make_vector.hpp>
Chris@16 22 #include <boost/spirit/home/support/unused.hpp>
Chris@16 23 #include <boost/spirit/home/support/detail/is_spirit_tag.hpp>
Chris@16 24 #include <boost/preprocessor/tuple/elem.hpp>
Chris@16 25
Chris@16 26 #include <boost/spirit/home/support/terminal_expression.hpp>
Chris@16 27
Chris@16 28 namespace boost { namespace spirit
Chris@16 29 {
Chris@16 30 template <typename Terminal, typename Args>
Chris@16 31 struct terminal_ex
Chris@16 32 {
Chris@16 33 typedef Terminal terminal_type;
Chris@16 34 typedef Args args_type;
Chris@16 35
Chris@16 36 terminal_ex(Args const& args_)
Chris@16 37 : args(args_) {}
Chris@16 38 terminal_ex(Args const& args_, Terminal const& term_)
Chris@16 39 : args(args_), term(term_) {}
Chris@16 40
Chris@16 41 Args args; // Args is guaranteed to be a fusion::vectorN so you
Chris@16 42 // can use that template for detection and specialization
Chris@16 43 Terminal term;
Chris@16 44 };
Chris@16 45
Chris@16 46 template <typename Terminal, typename Actor, int Arity>
Chris@16 47 struct lazy_terminal
Chris@16 48 {
Chris@16 49 typedef Terminal terminal_type;
Chris@16 50 typedef Actor actor_type;
Chris@16 51 static int const arity = Arity;
Chris@16 52
Chris@16 53 lazy_terminal(Actor const& actor_)
Chris@16 54 : actor(actor_) {}
Chris@16 55 lazy_terminal(Actor const& actor_, Terminal const& term_)
Chris@16 56 : actor(actor_), term(term_) {}
Chris@16 57
Chris@16 58 Actor actor;
Chris@16 59 Terminal term;
Chris@16 60 };
Chris@16 61
Chris@16 62 template <typename Domain, typename Terminal, int Arity, typename Enable = void>
Chris@16 63 struct use_lazy_terminal : mpl::false_ {};
Chris@16 64
Chris@16 65 template <typename Domain, typename Terminal, int Arity, typename Enable = void>
Chris@16 66 struct use_lazy_directive : mpl::false_ {};
Chris@16 67
Chris@16 68 template <typename Terminal>
Chris@16 69 struct terminal;
Chris@16 70
Chris@16 71 template <typename Domain, typename Terminal>
Chris@16 72 struct use_terminal<Domain, terminal<Terminal> >
Chris@16 73 : use_terminal<Domain, Terminal> {};
Chris@16 74
Chris@16 75 template <typename Domain, typename Terminal, int Arity, typename Actor>
Chris@16 76 struct use_terminal<Domain, lazy_terminal<Terminal, Actor, Arity> >
Chris@16 77 : use_lazy_terminal<Domain, Terminal, Arity> {};
Chris@16 78
Chris@16 79 template <typename Domain, typename Terminal, int Arity, typename Actor>
Chris@16 80 struct use_directive<Domain, lazy_terminal<Terminal, Actor, Arity> >
Chris@16 81 : use_lazy_directive<Domain, Terminal, Arity> {};
Chris@16 82
Chris@16 83 template <
Chris@16 84 typename F
Chris@16 85 , typename A0 = unused_type
Chris@16 86 , typename A1 = unused_type
Chris@16 87 , typename A2 = unused_type
Chris@16 88 , typename Unused = unused_type
Chris@16 89 >
Chris@16 90 struct make_lazy;
Chris@16 91
Chris@16 92 template <typename F, typename A0>
Chris@16 93 struct make_lazy<F, A0>
Chris@16 94 {
Chris@16 95 typedef typename
Chris@16 96 proto::terminal<
Chris@16 97 lazy_terminal<
Chris@16 98 typename F::terminal_type
Chris@16 99 , typename phoenix::detail::expression::function_eval<F, A0>::type
Chris@16 100 , 1 // arity
Chris@16 101 >
Chris@16 102 >::type
Chris@16 103 result_type;
Chris@16 104 typedef result_type type;
Chris@16 105
Chris@16 106 result_type
Chris@16 107 operator()(F f, A0 const& _0_) const
Chris@16 108 {
Chris@16 109 typedef typename result_type::proto_child0 child_type;
Chris@16 110 return result_type::make(child_type(
Chris@16 111 phoenix::detail::expression::function_eval<F, A0>::make(f, _0_)
Chris@16 112 , f.proto_base().child0
Chris@16 113 ));
Chris@16 114 }
Chris@16 115 };
Chris@16 116
Chris@16 117 template <typename F, typename A0, typename A1>
Chris@16 118 struct make_lazy<F, A0, A1>
Chris@16 119 {
Chris@16 120 typedef typename
Chris@16 121 proto::terminal<
Chris@16 122 lazy_terminal<
Chris@16 123 typename F::terminal_type
Chris@16 124 , typename phoenix::detail::expression::function_eval<F, A0, A1>::type
Chris@16 125 , 2 // arity
Chris@16 126 >
Chris@16 127 >::type
Chris@16 128 result_type;
Chris@16 129 typedef result_type type;
Chris@16 130
Chris@16 131 result_type
Chris@16 132 operator()(F f, A0 const& _0_, A1 const& _1_) const
Chris@16 133 {
Chris@16 134 typedef typename result_type::proto_child0 child_type;
Chris@16 135 return result_type::make(child_type(
Chris@16 136 phoenix::detail::expression::function_eval<F, A0, A1>::make(f, _0_, _1_)
Chris@16 137 , f.proto_base().child0
Chris@16 138 ));
Chris@16 139 }
Chris@16 140 };
Chris@16 141
Chris@16 142 template <typename F, typename A0, typename A1, typename A2>
Chris@16 143 struct make_lazy<F, A0, A1, A2>
Chris@16 144 {
Chris@16 145 typedef typename
Chris@16 146 proto::terminal<
Chris@16 147 lazy_terminal<
Chris@16 148 typename F::terminal_type
Chris@16 149 , typename phoenix::detail::expression::function_eval<F, A0, A1, A2>::type
Chris@16 150 , 3 // arity
Chris@16 151 >
Chris@16 152 >::type
Chris@16 153 result_type;
Chris@16 154 typedef result_type type;
Chris@16 155
Chris@16 156 result_type
Chris@16 157 operator()(F f, A0 const& _0_, A1 const& _1_, A2 const& _2_) const
Chris@16 158 {
Chris@16 159 typedef typename result_type::proto_child0 child_type;
Chris@16 160 return result_type::make(child_type(
Chris@16 161 phoenix::detail::expression::function_eval<F, A0, A1, A2>::make(f, _0_, _1_, _2_)
Chris@16 162 , f.proto_base().child0
Chris@16 163 ));
Chris@16 164 }
Chris@16 165 };
Chris@16 166
Chris@16 167 namespace detail
Chris@16 168 {
Chris@16 169 // Helper struct for SFINAE purposes
Chris@16 170 template <bool C> struct bool_;
Chris@16 171
Chris@16 172 template <>
Chris@16 173 struct bool_<true> : mpl::bool_<true>
Chris@16 174 {
Chris@16 175 typedef bool_<true>* is_true;
Chris@16 176 };
Chris@16 177
Chris@16 178 template <>
Chris@16 179 struct bool_<false> : mpl::bool_<false>
Chris@16 180 {
Chris@16 181 typedef bool_<false>* is_false;
Chris@16 182 };
Chris@16 183
Chris@16 184 // Metafunction to detect if at least one arg is a Phoenix actor
Chris@16 185 template <
Chris@16 186 typename A0
Chris@16 187 , typename A1 = unused_type
Chris@16 188 , typename A2 = unused_type
Chris@16 189 >
Chris@16 190 struct contains_actor
Chris@16 191 : bool_<
Chris@16 192 phoenix::is_actor<A0>::value
Chris@16 193 || phoenix::is_actor<A1>::value
Chris@16 194 || phoenix::is_actor<A2>::value
Chris@16 195 >
Chris@16 196 {};
Chris@16 197
Chris@16 198 // to_lazy_arg: convert a terminal arg type to the type make_lazy needs
Chris@16 199 template <typename A>
Chris@16 200 struct to_lazy_arg
Chris@16 201 : phoenix::as_actor<A> // wrap A in a Phoenix actor if not already one
Chris@16 202 {};
Chris@16 203
Chris@16 204 template <typename A>
Chris@16 205 struct to_lazy_arg<const A>
Chris@16 206 : to_lazy_arg<A>
Chris@16 207 {};
Chris@16 208
Chris@16 209 template <typename A>
Chris@16 210 struct to_lazy_arg<A &>
Chris@16 211 : to_lazy_arg<A>
Chris@16 212 {};
Chris@16 213
Chris@16 214 template <>
Chris@16 215 struct to_lazy_arg<unused_type>
Chris@16 216 {
Chris@16 217 // unused arg: make_lazy wants unused_type
Chris@16 218 typedef unused_type type;
Chris@16 219 };
Chris@16 220
Chris@16 221 // to_nonlazy_arg: convert a terminal arg type to the type make_vector needs
Chris@16 222 template <typename A>
Chris@16 223 struct to_nonlazy_arg
Chris@16 224 {
Chris@16 225 // identity
Chris@16 226 typedef A type;
Chris@16 227 };
Chris@16 228
Chris@16 229 template <typename A>
Chris@16 230 struct to_nonlazy_arg<const A>
Chris@16 231 : to_nonlazy_arg<A>
Chris@16 232 {};
Chris@16 233
Chris@16 234 template <typename A>
Chris@16 235 struct to_nonlazy_arg<A &>
Chris@16 236 : to_nonlazy_arg<A>
Chris@16 237 {};
Chris@16 238
Chris@16 239 template <>
Chris@16 240 struct to_nonlazy_arg<unused_type>
Chris@16 241 {
Chris@16 242 // unused arg: make_vector wants fusion::void_
Chris@16 243 typedef fusion::void_ type;
Chris@16 244 };
Chris@16 245 }
Chris@16 246
Chris@16 247 template <typename Terminal>
Chris@16 248 struct terminal
Chris@16 249 : proto::extends<
Chris@16 250 typename proto::terminal<Terminal>::type
Chris@16 251 , terminal<Terminal>
Chris@16 252 >
Chris@16 253 {
Chris@16 254 typedef terminal<Terminal> this_type;
Chris@16 255 typedef Terminal terminal_type;
Chris@16 256
Chris@16 257 typedef proto::extends<
Chris@16 258 typename proto::terminal<Terminal>::type
Chris@16 259 , terminal<Terminal>
Chris@16 260 > base_type;
Chris@16 261
Chris@16 262 terminal() {}
Chris@16 263
Chris@16 264 terminal(Terminal const& t)
Chris@16 265 : base_type(proto::terminal<Terminal>::type::make(t))
Chris@16 266 {}
Chris@16 267
Chris@16 268 template <
Chris@16 269 bool Lazy
Chris@16 270 , typename A0
Chris@16 271 , typename A1
Chris@16 272 , typename A2
Chris@16 273 >
Chris@16 274 struct result_helper;
Chris@16 275
Chris@16 276 template <
Chris@16 277 typename A0
Chris@16 278 , typename A1
Chris@16 279 , typename A2
Chris@16 280 >
Chris@16 281 struct result_helper<false, A0, A1, A2>
Chris@16 282 {
Chris@16 283 typedef typename
Chris@16 284 proto::terminal<
Chris@16 285 terminal_ex<
Chris@16 286 Terminal
Chris@16 287 , typename detail::result_of::make_vector<
Chris@16 288 typename detail::to_nonlazy_arg<A0>::type
Chris@16 289 , typename detail::to_nonlazy_arg<A1>::type
Chris@16 290 , typename detail::to_nonlazy_arg<A2>::type>::type>
Chris@16 291 >::type
Chris@16 292 type;
Chris@16 293 };
Chris@16 294
Chris@16 295 template <
Chris@16 296 typename A0
Chris@16 297 , typename A1
Chris@16 298 , typename A2
Chris@16 299 >
Chris@16 300 struct result_helper<true, A0, A1, A2>
Chris@16 301 {
Chris@16 302 typedef typename
Chris@16 303 make_lazy<this_type
Chris@16 304 , typename detail::to_lazy_arg<A0>::type
Chris@16 305 , typename detail::to_lazy_arg<A1>::type
Chris@16 306 , typename detail::to_lazy_arg<A2>::type>::type
Chris@16 307 type;
Chris@16 308 };
Chris@16 309
Chris@16 310 // FIXME: we need to change this to conform to the result_of protocol
Chris@16 311 template <
Chris@16 312 typename A0
Chris@16 313 , typename A1 = unused_type
Chris@16 314 , typename A2 = unused_type // Support up to 3 args
Chris@16 315 >
Chris@16 316 struct result
Chris@16 317 {
Chris@16 318 typedef typename
Chris@16 319 result_helper<
Chris@16 320 detail::contains_actor<A0, A1, A2>::value
Chris@16 321 , A0, A1, A2
Chris@16 322 >::type
Chris@16 323 type;
Chris@16 324 };
Chris@16 325
Chris@16 326 template <typename This, typename A0>
Chris@16 327 struct result<This(A0)>
Chris@16 328 {
Chris@16 329 typedef typename
Chris@16 330 result_helper<
Chris@16 331 detail::contains_actor<A0, unused_type, unused_type>::value
Chris@16 332 , A0, unused_type, unused_type
Chris@16 333 >::type
Chris@16 334 type;
Chris@16 335 };
Chris@16 336
Chris@16 337 template <typename This, typename A0, typename A1>
Chris@16 338 struct result<This(A0, A1)>
Chris@16 339 {
Chris@16 340 typedef typename
Chris@16 341 result_helper<
Chris@16 342 detail::contains_actor<A0, A1, unused_type>::value
Chris@16 343 , A0, A1, unused_type
Chris@16 344 >::type
Chris@16 345 type;
Chris@16 346 };
Chris@16 347
Chris@16 348
Chris@16 349 template <typename This, typename A0, typename A1, typename A2>
Chris@16 350 struct result<This(A0, A1, A2)>
Chris@16 351 {
Chris@16 352 typedef typename
Chris@16 353 result_helper<
Chris@16 354 detail::contains_actor<A0, A1, A2>::value
Chris@16 355 , A0, A1, A2
Chris@16 356 >::type
Chris@16 357 type;
Chris@16 358 };
Chris@16 359
Chris@16 360 // Note: in the following overloads, SFINAE cannot
Chris@16 361 // be done on return type because of gcc bug #24915:
Chris@16 362 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24915
Chris@16 363 // Hence an additional, fake argument is used for SFINAE,
Chris@16 364 // using a type which can never be a real argument type.
Chris@16 365
Chris@16 366 // Non-lazy overloads. Only enabled when all
Chris@16 367 // args are immediates (no Phoenix actor).
Chris@16 368
Chris@16 369 template <typename A0>
Chris@16 370 typename result<A0>::type
Chris@16 371 operator()(A0 const& _0_
Chris@16 372 , typename detail::contains_actor<A0>::is_false = 0) const
Chris@16 373 {
Chris@16 374 typedef typename result<A0>::type result_type;
Chris@16 375 typedef typename result_type::proto_child0 child_type;
Chris@16 376 return result_type::make(
Chris@16 377 child_type(
Chris@16 378 detail::make_vector(_0_)
Chris@16 379 , this->proto_base().child0)
Chris@16 380 );
Chris@16 381 }
Chris@16 382
Chris@16 383 template <typename A0, typename A1>
Chris@16 384 typename result<A0, A1>::type
Chris@16 385 operator()(A0 const& _0_, A1 const& _1_
Chris@16 386 , typename detail::contains_actor<A0, A1>::is_false = 0) const
Chris@16 387 {
Chris@16 388 typedef typename result<A0, A1>::type result_type;
Chris@16 389 typedef typename result_type::proto_child0 child_type;
Chris@16 390 return result_type::make(
Chris@16 391 child_type(
Chris@16 392 detail::make_vector(_0_, _1_)
Chris@16 393 , this->proto_base().child0)
Chris@16 394 );
Chris@16 395 }
Chris@16 396
Chris@16 397 template <typename A0, typename A1, typename A2>
Chris@16 398 typename result<A0, A1, A2>::type
Chris@16 399 operator()(A0 const& _0_, A1 const& _1_, A2 const& _2_
Chris@16 400 , typename detail::contains_actor<A0, A1, A2>::is_false = 0) const
Chris@16 401 {
Chris@16 402 typedef typename result<A0, A1, A2>::type result_type;
Chris@16 403 typedef typename result_type::proto_child0 child_type;
Chris@16 404 return result_type::make(
Chris@16 405 child_type(
Chris@16 406 detail::make_vector(_0_, _1_, _2_)
Chris@16 407 , this->proto_base().child0)
Chris@16 408 );
Chris@16 409 }
Chris@16 410
Chris@16 411 // Lazy overloads. Enabled when at
Chris@16 412 // least one arg is a Phoenix actor.
Chris@16 413 template <typename A0>
Chris@16 414 typename result<A0>::type
Chris@16 415 operator()(A0 const& _0_
Chris@16 416 , typename detail::contains_actor<A0>::is_true = 0) const
Chris@16 417 {
Chris@16 418 return make_lazy<this_type
Chris@16 419 , typename phoenix::as_actor<A0>::type>()(*this
Chris@16 420 , phoenix::as_actor<A0>::convert(_0_));
Chris@16 421 }
Chris@16 422
Chris@16 423 template <typename A0, typename A1>
Chris@16 424 typename result<A0, A1>::type
Chris@16 425 operator()(A0 const& _0_, A1 const& _1_
Chris@16 426 , typename detail::contains_actor<A0, A1>::is_true = 0) const
Chris@16 427 {
Chris@16 428 return make_lazy<this_type
Chris@16 429 , typename phoenix::as_actor<A0>::type
Chris@16 430 , typename phoenix::as_actor<A1>::type>()(*this
Chris@16 431 , phoenix::as_actor<A0>::convert(_0_)
Chris@16 432 , phoenix::as_actor<A1>::convert(_1_));
Chris@16 433 }
Chris@16 434
Chris@16 435 template <typename A0, typename A1, typename A2>
Chris@16 436 typename result<A0, A1, A2>::type
Chris@16 437 operator()(A0 const& _0_, A1 const& _1_, A2 const& _2_
Chris@16 438 , typename detail::contains_actor<A0, A1, A2>::is_true = 0) const
Chris@16 439 {
Chris@16 440 return make_lazy<this_type
Chris@16 441 , typename phoenix::as_actor<A0>::type
Chris@16 442 , typename phoenix::as_actor<A1>::type
Chris@16 443 , typename phoenix::as_actor<A2>::type>()(*this
Chris@16 444 , phoenix::as_actor<A0>::convert(_0_)
Chris@16 445 , phoenix::as_actor<A1>::convert(_1_)
Chris@16 446 , phoenix::as_actor<A2>::convert(_2_));
Chris@16 447 }
Chris@16 448
Chris@16 449 private:
Chris@16 450 // silence MSVC warning C4512: assignment operator could not be generated
Chris@16 451 terminal& operator= (terminal const&);
Chris@16 452 };
Chris@16 453
Chris@16 454 ///////////////////////////////////////////////////////////////////////////
Chris@16 455 namespace result_of
Chris@16 456 {
Chris@16 457 // Calculate the type of the compound terminal if generated by one of
Chris@16 458 // the spirit::terminal::operator() overloads above
Chris@16 459
Chris@16 460 // The terminal type itself is passed through without modification
Chris@16 461 template <typename Tag>
Chris@16 462 struct terminal
Chris@16 463 {
Chris@16 464 typedef spirit::terminal<Tag> type;
Chris@16 465 };
Chris@16 466
Chris@16 467 template <typename Tag, typename A0>
Chris@16 468 struct terminal<Tag(A0)>
Chris@16 469 {
Chris@16 470 typedef typename spirit::terminal<Tag>::
Chris@16 471 template result<A0>::type type;
Chris@16 472 };
Chris@16 473
Chris@16 474 template <typename Tag, typename A0, typename A1>
Chris@16 475 struct terminal<Tag(A0, A1)>
Chris@16 476 {
Chris@16 477 typedef typename spirit::terminal<Tag>::
Chris@16 478 template result<A0, A1>::type type;
Chris@16 479 };
Chris@16 480
Chris@16 481 template <typename Tag, typename A0, typename A1, typename A2>
Chris@16 482 struct terminal<Tag(A0, A1, A2)>
Chris@16 483 {
Chris@16 484 typedef typename spirit::terminal<Tag>::
Chris@16 485 template result<A0, A1, A2>::type type;
Chris@16 486 };
Chris@16 487 }
Chris@16 488
Chris@16 489 ///////////////////////////////////////////////////////////////////////////
Chris@16 490 // support for stateful tag types
Chris@16 491 namespace tag
Chris@16 492 {
Chris@16 493 template <
Chris@16 494 typename Data, typename Tag
Chris@16 495 , typename DataTag1 = unused_type, typename DataTag2 = unused_type>
Chris@16 496 struct stateful_tag
Chris@16 497 {
Chris@16 498 BOOST_SPIRIT_IS_TAG()
Chris@16 499
Chris@16 500 typedef Data data_type;
Chris@16 501
Chris@16 502 stateful_tag() {}
Chris@16 503 stateful_tag(data_type const& data) : data_(data) {}
Chris@16 504
Chris@16 505 data_type data_;
Chris@16 506
Chris@16 507 private:
Chris@16 508 // silence MSVC warning C4512: assignment operator could not be generated
Chris@16 509 stateful_tag& operator= (stateful_tag const&);
Chris@16 510 };
Chris@16 511 }
Chris@16 512
Chris@16 513 template <
Chris@16 514 typename Data, typename Tag
Chris@16 515 , typename DataTag1 = unused_type, typename DataTag2 = unused_type>
Chris@16 516 struct stateful_tag_type
Chris@16 517 : spirit::terminal<tag::stateful_tag<Data, Tag, DataTag1, DataTag2> >
Chris@16 518 {
Chris@16 519 typedef tag::stateful_tag<Data, Tag, DataTag1, DataTag2> tag_type;
Chris@16 520
Chris@16 521 stateful_tag_type() {}
Chris@16 522 stateful_tag_type(Data const& data)
Chris@16 523 : spirit::terminal<tag_type>(data)
Chris@16 524 {}
Chris@16 525
Chris@16 526 private:
Chris@16 527 // silence MSVC warning C4512: assignment operator could not be generated
Chris@16 528 stateful_tag_type& operator= (stateful_tag_type const&);
Chris@16 529 };
Chris@16 530
Chris@16 531 namespace detail
Chris@16 532 {
Chris@16 533 // extract expression if this is a Tag
Chris@16 534 template <typename StatefulTag>
Chris@16 535 struct get_stateful_data
Chris@16 536 {
Chris@16 537 typedef typename StatefulTag::data_type data_type;
Chris@16 538
Chris@16 539 // is invoked if given tag is != Tag
Chris@16 540 template <typename Tag_>
Chris@16 541 static data_type call(Tag_) { return data_type(); }
Chris@16 542
Chris@16 543 // this is invoked if given tag is same as'Tag'
Chris@16 544 static data_type const& call(StatefulTag const& t) { return t.data_; }
Chris@16 545 };
Chris@16 546 }
Chris@16 547
Chris@16 548 }}
Chris@16 549
Chris@16 550 namespace boost { namespace phoenix
Chris@16 551 {
Chris@16 552 template <typename Tag>
Chris@16 553 struct is_custom_terminal<Tag, typename Tag::is_spirit_tag>
Chris@16 554 : mpl::true_
Chris@16 555 {};
Chris@16 556
Chris@16 557 template <typename Tag>
Chris@16 558 struct custom_terminal<Tag, typename Tag::is_spirit_tag>
Chris@16 559 {
Chris@101 560 #ifndef BOOST_PHOENIX_NO_SPECIALIZE_CUSTOM_TERMINAL
Chris@101 561 typedef void _is_default_custom_terminal; // fix for #7730
Chris@101 562 #endif
Chris@101 563
Chris@16 564 typedef spirit::terminal<Tag> result_type;
Chris@16 565
Chris@16 566 template <typename Context>
Chris@16 567 result_type operator()(Tag const & t, Context const &)
Chris@16 568 {
Chris@16 569 return spirit::terminal<Tag>(t);
Chris@16 570 }
Chris@16 571 };
Chris@16 572 }}
Chris@16 573
Chris@16 574 // Define a spirit terminal. This macro may be placed in any namespace.
Chris@16 575 // Common placeholders are placed in the main boost::spirit namespace
Chris@16 576 // (see common_terminals.hpp)
Chris@16 577
Chris@16 578 #define BOOST_SPIRIT_TERMINAL_X(x, y) ((x, y)) BOOST_SPIRIT_TERMINAL_Y
Chris@16 579 #define BOOST_SPIRIT_TERMINAL_Y(x, y) ((x, y)) BOOST_SPIRIT_TERMINAL_X
Chris@16 580 #define BOOST_SPIRIT_TERMINAL_X0
Chris@16 581 #define BOOST_SPIRIT_TERMINAL_Y0
Chris@16 582
Chris@16 583 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
Chris@16 584
Chris@16 585 #define BOOST_SPIRIT_TERMINAL_NAME(name, type_name) \
Chris@16 586 namespace tag { struct name { BOOST_SPIRIT_IS_TAG() }; } \
Chris@16 587 typedef boost::proto::terminal<tag::name>::type type_name; \
Chris@16 588 type_name const name = {{}}; \
Chris@16 589 inline void BOOST_PP_CAT(silence_unused_warnings_, name)() { (void) name; } \
Chris@16 590 /***/
Chris@16 591
Chris@16 592 #else
Chris@16 593
Chris@16 594 #define BOOST_SPIRIT_TERMINAL_NAME(name, type_name) \
Chris@16 595 namespace tag { struct name { BOOST_SPIRIT_IS_TAG() }; } \
Chris@16 596 typedef boost::proto::terminal<tag::name>::type type_name; \
Chris@16 597 /***/
Chris@16 598
Chris@16 599 #endif
Chris@16 600
Chris@16 601 #define BOOST_SPIRIT_TERMINAL(name) \
Chris@16 602 BOOST_SPIRIT_TERMINAL_NAME(name, name ## _type) \
Chris@16 603 /***/
Chris@16 604
Chris@16 605 #define BOOST_SPIRIT_DEFINE_TERMINALS_NAME_A(r, _, names) \
Chris@16 606 BOOST_SPIRIT_TERMINAL_NAME( \
Chris@16 607 BOOST_PP_TUPLE_ELEM(2, 0, names), \
Chris@16 608 BOOST_PP_TUPLE_ELEM(2, 1, names) \
Chris@16 609 ) \
Chris@16 610 /***/
Chris@16 611
Chris@16 612 #define BOOST_SPIRIT_DEFINE_TERMINALS_NAME(seq) \
Chris@16 613 BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEFINE_TERMINALS_NAME_A, _, \
Chris@16 614 BOOST_PP_CAT(BOOST_SPIRIT_TERMINAL_X seq, 0)) \
Chris@16 615 /***/
Chris@16 616
Chris@16 617 // Define a spirit extended terminal. This macro may be placed in any namespace.
Chris@16 618 // Common placeholders are placed in the main boost::spirit namespace
Chris@16 619 // (see common_terminals.hpp)
Chris@16 620
Chris@16 621 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
Chris@16 622
Chris@16 623 #define BOOST_SPIRIT_TERMINAL_NAME_EX(name, type_name) \
Chris@16 624 namespace tag { struct name { BOOST_SPIRIT_IS_TAG() }; } \
Chris@16 625 typedef boost::spirit::terminal<tag::name> type_name; \
Chris@16 626 type_name const name = type_name(); \
Chris@16 627 inline void BOOST_PP_CAT(silence_unused_warnings_, name)() { (void) name; } \
Chris@16 628 /***/
Chris@16 629
Chris@16 630 #else
Chris@16 631
Chris@16 632 #define BOOST_SPIRIT_TERMINAL_NAME_EX(name, type_name) \
Chris@16 633 namespace tag { struct name { BOOST_SPIRIT_IS_TAG() }; } \
Chris@16 634 typedef boost::spirit::terminal<tag::name> type_name; \
Chris@16 635 /***/
Chris@16 636
Chris@16 637 #endif
Chris@16 638
Chris@16 639 #define BOOST_SPIRIT_TERMINAL_EX(name) \
Chris@16 640 BOOST_SPIRIT_TERMINAL_NAME_EX(name, name ## _type) \
Chris@16 641 /***/
Chris@16 642
Chris@16 643 #define BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX_A(r, _, names) \
Chris@16 644 BOOST_SPIRIT_TERMINAL_NAME_EX( \
Chris@16 645 BOOST_PP_TUPLE_ELEM(2, 0, names), \
Chris@16 646 BOOST_PP_TUPLE_ELEM(2, 1, names) \
Chris@16 647 ) \
Chris@16 648 /***/
Chris@16 649
Chris@16 650 #define BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX(seq) \
Chris@16 651 BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX_A, _, \
Chris@16 652 BOOST_PP_CAT(BOOST_SPIRIT_TERMINAL_X seq, 0)) \
Chris@16 653 /***/
Chris@16 654
Chris@16 655 #endif
Chris@16 656
Chris@16 657