1 /////////////////////////////////////////////////////////////////////////////// 2 /// \file regex_actions.hpp 3 /// Defines the syntax elements of xpressive's action expressions. 4 // 5 // Copyright 2008 Eric Niebler. Distributed under the Boost 6 // Software License, Version 1.0. (See accompanying file 7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 9 #ifndef BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007 10 #define BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007 11 12 // MS compatible compilers support #pragma once 13 #if defined(_MSC_VER) 14 # pragma once 15 #endif 16 17 #include <boost/config.hpp> 18 #include <boost/preprocessor/punctuation/comma_if.hpp> 19 #include <boost/ref.hpp> 20 #include <boost/mpl/if.hpp> 21 #include <boost/mpl/or.hpp> 22 #include <boost/mpl/int.hpp> 23 #include <boost/mpl/assert.hpp> 24 #include <boost/noncopyable.hpp> 25 #include <boost/lexical_cast.hpp> 26 #include <boost/throw_exception.hpp> 27 #include <boost/utility/enable_if.hpp> 28 #include <boost/type_traits/is_same.hpp> 29 #include <boost/type_traits/is_const.hpp> 30 #include <boost/type_traits/is_integral.hpp> 31 #include <boost/type_traits/decay.hpp> 32 #include <boost/type_traits/remove_cv.hpp> 33 #include <boost/type_traits/remove_reference.hpp> 34 #include <boost/range/iterator_range.hpp> 35 #include <boost/xpressive/detail/detail_fwd.hpp> 36 #include <boost/xpressive/detail/core/state.hpp> 37 #include <boost/xpressive/detail/core/matcher/attr_matcher.hpp> 38 #include <boost/xpressive/detail/core/matcher/attr_end_matcher.hpp> 39 #include <boost/xpressive/detail/core/matcher/attr_begin_matcher.hpp> 40 #include <boost/xpressive/detail/core/matcher/predicate_matcher.hpp> 41 #include <boost/xpressive/detail/utility/ignore_unused.hpp> 42 #include <boost/xpressive/detail/static/type_traits.hpp> 43 44 // These are very often needed by client code. 45 #include <boost/typeof/std/map.hpp> 46 #include <boost/typeof/std/string.hpp> 47 48 // Doxygen can't handle proto :-( 49 #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED 50 # include <boost/proto/core.hpp> 51 # include <boost/proto/transform.hpp> 52 # include <boost/xpressive/detail/core/matcher/action_matcher.hpp> 53 #endif 54 55 #if BOOST_MSVC 56 #pragma warning(push) 57 #pragma warning(disable : 4510) // default constructor could not be generated 58 #pragma warning(disable : 4512) // assignment operator could not be generated 59 #pragma warning(disable : 4610) // can never be instantiated - user defined constructor required 60 #endif 61 62 namespace boost { namespace xpressive 63 { 64 65 namespace detail 66 { 67 template<typename T, typename U> 68 struct action_arg 69 { 70 typedef T type; 71 typedef typename add_reference<T>::type reference; 72 castboost::xpressive::detail::action_arg73 reference cast(void *pv) const 74 { 75 return *static_cast<typename remove_reference<T>::type *>(pv); 76 } 77 }; 78 79 template<typename T> 80 struct value_wrapper 81 : private noncopyable 82 { value_wrapperboost::xpressive::detail::value_wrapper83 value_wrapper() 84 : value() 85 {} 86 value_wrapperboost::xpressive::detail::value_wrapper87 value_wrapper(T const &t) 88 : value(t) 89 {} 90 91 T value; 92 }; 93 94 struct check_tag 95 {}; 96 97 struct BindArg 98 { 99 BOOST_PROTO_CALLABLE() 100 template<typename Sig> 101 struct result {}; 102 103 template<typename This, typename MatchResults, typename Expr> 104 struct result<This(MatchResults, Expr)> 105 { 106 typedef Expr type; 107 }; 108 109 template<typename MatchResults, typename Expr> operator ()boost::xpressive::detail::BindArg110 Expr const & operator ()(MatchResults &what, Expr const &expr) const 111 { 112 what.let(expr); 113 return expr; 114 } 115 }; 116 117 struct let_tag 118 {}; 119 120 // let(_a = b, _c = d) 121 struct BindArgs 122 : proto::function< 123 proto::terminal<let_tag> 124 , proto::vararg< 125 proto::when< 126 proto::assign<proto::_, proto::_> 127 , proto::call<BindArg(proto::_data, proto::_)> 128 > 129 > 130 > 131 {}; 132 133 struct let_domain 134 : boost::proto::domain<boost::proto::pod_generator<let_> > 135 {}; 136 137 template<typename Expr> 138 struct let_ 139 { 140 BOOST_PROTO_BASIC_EXTENDS(Expr, let_<Expr>, let_domain) 141 BOOST_PROTO_EXTENDS_FUNCTION() 142 }; 143 144 template<typename Args, typename BidiIter> bind_args(let_<Args> const & args,match_results<BidiIter> & what)145 void bind_args(let_<Args> const &args, match_results<BidiIter> &what) 146 { 147 BindArgs()(args, 0, what); 148 } 149 150 typedef boost::proto::functional::make_expr<proto::tag::function, proto::default_domain> make_function; 151 } 152 153 namespace op 154 { 155 /// \brief \c at is a PolymorphicFunctionObject for indexing into a sequence 156 struct at 157 { 158 BOOST_PROTO_CALLABLE() 159 template<typename Sig> 160 struct result {}; 161 162 template<typename This, typename Cont, typename Idx> 163 struct result<This(Cont &, Idx)> 164 { 165 typedef typename Cont::reference type; 166 }; 167 168 template<typename This, typename Cont, typename Idx> 169 struct result<This(Cont const &, Idx)> 170 { 171 typedef typename Cont::const_reference type; 172 }; 173 174 template<typename This, typename Cont, typename Idx> 175 struct result<This(Cont, Idx)> 176 { 177 typedef typename Cont::const_reference type; 178 }; 179 180 /// \pre \c Cont is a model of RandomAccessSequence 181 /// \param c The RandomAccessSequence to index into 182 /// \param idx The index 183 /// \return <tt>c[idx]</tt> 184 template<typename Cont, typename Idx> operator ()boost::xpressive::op::at185 typename Cont::reference operator()(Cont &c, Idx idx BOOST_PROTO_DISABLE_IF_IS_CONST(Cont)) const 186 { 187 return c[idx]; 188 } 189 190 /// \overload 191 /// 192 template<typename Cont, typename Idx> operator ()boost::xpressive::op::at193 typename Cont::const_reference operator()(Cont const &c, Idx idx) const 194 { 195 return c[idx]; 196 } 197 }; 198 199 /// \brief \c push is a PolymorphicFunctionObject for pushing an element into a container. 200 struct push 201 { 202 BOOST_PROTO_CALLABLE() 203 typedef void result_type; 204 205 /// \param seq The sequence into which the value should be pushed. 206 /// \param val The value to push into the sequence. 207 /// \brief Equivalent to <tt>seq.push(val)</tt>. 208 /// \return \c void 209 template<typename Sequence, typename Value> operator ()boost::xpressive::op::push210 void operator()(Sequence &seq, Value const &val) const 211 { 212 seq.push(val); 213 } 214 }; 215 216 /// \brief \c push_back is a PolymorphicFunctionObject for pushing an element into the back of a container. 217 struct push_back 218 { 219 BOOST_PROTO_CALLABLE() 220 typedef void result_type; 221 222 /// \param seq The sequence into which the value should be pushed. 223 /// \param val The value to push into the sequence. 224 /// \brief Equivalent to <tt>seq.push_back(val)</tt>. 225 /// \return \c void 226 template<typename Sequence, typename Value> operator ()boost::xpressive::op::push_back227 void operator()(Sequence &seq, Value const &val) const 228 { 229 seq.push_back(val); 230 } 231 }; 232 233 /// \brief \c push_front is a PolymorphicFunctionObject for pushing an element into the front of a container. 234 struct push_front 235 { 236 BOOST_PROTO_CALLABLE() 237 typedef void result_type; 238 239 /// \param seq The sequence into which the value should be pushed. 240 /// \param val The value to push into the sequence. 241 /// \brief Equivalent to <tt>seq.push_front(val)</tt>. 242 /// \return \c void 243 template<typename Sequence, typename Value> operator ()boost::xpressive::op::push_front244 void operator()(Sequence &seq, Value const &val) const 245 { 246 seq.push_front(val); 247 } 248 }; 249 250 /// \brief \c pop is a PolymorphicFunctionObject for popping an element from a container. 251 struct pop 252 { 253 BOOST_PROTO_CALLABLE() 254 typedef void result_type; 255 256 /// \param seq The sequence from which to pop. 257 /// \brief Equivalent to <tt>seq.pop()</tt>. 258 /// \return \c void 259 template<typename Sequence> operator ()boost::xpressive::op::pop260 void operator()(Sequence &seq) const 261 { 262 seq.pop(); 263 } 264 }; 265 266 /// \brief \c pop_back is a PolymorphicFunctionObject for popping an element from the back of a container. 267 struct pop_back 268 { 269 BOOST_PROTO_CALLABLE() 270 typedef void result_type; 271 272 /// \param seq The sequence from which to pop. 273 /// \brief Equivalent to <tt>seq.pop_back()</tt>. 274 /// \return \c void 275 template<typename Sequence> operator ()boost::xpressive::op::pop_back276 void operator()(Sequence &seq) const 277 { 278 seq.pop_back(); 279 } 280 }; 281 282 /// \brief \c pop_front is a PolymorphicFunctionObject for popping an element from the front of a container. 283 struct pop_front 284 { 285 BOOST_PROTO_CALLABLE() 286 typedef void result_type; 287 288 /// \param seq The sequence from which to pop. 289 /// \brief Equivalent to <tt>seq.pop_front()</tt>. 290 /// \return \c void 291 template<typename Sequence> operator ()boost::xpressive::op::pop_front292 void operator()(Sequence &seq) const 293 { 294 seq.pop_front(); 295 } 296 }; 297 298 /// \brief \c front is a PolymorphicFunctionObject for fetching the front element of a container. 299 struct front 300 { 301 BOOST_PROTO_CALLABLE() 302 template<typename Sig> 303 struct result {}; 304 305 template<typename This, typename Sequence> 306 struct result<This(Sequence)> 307 { 308 typedef typename remove_reference<Sequence>::type sequence_type; 309 typedef 310 typename mpl::if_c< 311 is_const<sequence_type>::value 312 , typename sequence_type::const_reference 313 , typename sequence_type::reference 314 >::type 315 type; 316 }; 317 318 /// \param seq The sequence from which to fetch the front. 319 /// \return <tt>seq.front()</tt> 320 template<typename Sequence> operator ()boost::xpressive::op::front321 typename result<front(Sequence &)>::type operator()(Sequence &seq) const 322 { 323 return seq.front(); 324 } 325 }; 326 327 /// \brief \c back is a PolymorphicFunctionObject for fetching the back element of a container. 328 struct back 329 { 330 BOOST_PROTO_CALLABLE() 331 template<typename Sig> 332 struct result {}; 333 334 template<typename This, typename Sequence> 335 struct result<This(Sequence)> 336 { 337 typedef typename remove_reference<Sequence>::type sequence_type; 338 typedef 339 typename mpl::if_c< 340 is_const<sequence_type>::value 341 , typename sequence_type::const_reference 342 , typename sequence_type::reference 343 >::type 344 type; 345 }; 346 347 /// \param seq The sequence from which to fetch the back. 348 /// \return <tt>seq.back()</tt> 349 template<typename Sequence> operator ()boost::xpressive::op::back350 typename result<back(Sequence &)>::type operator()(Sequence &seq) const 351 { 352 return seq.back(); 353 } 354 }; 355 356 /// \brief \c top is a PolymorphicFunctionObject for fetching the top element of a stack. 357 struct top 358 { 359 BOOST_PROTO_CALLABLE() 360 template<typename Sig> 361 struct result {}; 362 363 template<typename This, typename Sequence> 364 struct result<This(Sequence)> 365 { 366 typedef typename remove_reference<Sequence>::type sequence_type; 367 typedef 368 typename mpl::if_c< 369 is_const<sequence_type>::value 370 , typename sequence_type::value_type const & 371 , typename sequence_type::value_type & 372 >::type 373 type; 374 }; 375 376 /// \param seq The sequence from which to fetch the top. 377 /// \return <tt>seq.top()</tt> 378 template<typename Sequence> operator ()boost::xpressive::op::top379 typename result<top(Sequence &)>::type operator()(Sequence &seq) const 380 { 381 return seq.top(); 382 } 383 }; 384 385 /// \brief \c first is a PolymorphicFunctionObject for fetching the first element of a pair. 386 struct first 387 { 388 BOOST_PROTO_CALLABLE() 389 template<typename Sig> 390 struct result {}; 391 392 template<typename This, typename Pair> 393 struct result<This(Pair)> 394 { 395 typedef typename remove_reference<Pair>::type::first_type type; 396 }; 397 398 /// \param p The pair from which to fetch the first element. 399 /// \return <tt>p.first</tt> 400 template<typename Pair> operator ()boost::xpressive::op::first401 typename Pair::first_type operator()(Pair const &p) const 402 { 403 return p.first; 404 } 405 }; 406 407 /// \brief \c second is a PolymorphicFunctionObject for fetching the second element of a pair. 408 struct second 409 { 410 BOOST_PROTO_CALLABLE() 411 template<typename Sig> 412 struct result {}; 413 414 template<typename This, typename Pair> 415 struct result<This(Pair)> 416 { 417 typedef typename remove_reference<Pair>::type::second_type type; 418 }; 419 420 /// \param p The pair from which to fetch the second element. 421 /// \return <tt>p.second</tt> 422 template<typename Pair> operator ()boost::xpressive::op::second423 typename Pair::second_type operator()(Pair const &p) const 424 { 425 return p.second; 426 } 427 }; 428 429 /// \brief \c matched is a PolymorphicFunctionObject for assessing whether a \c sub_match object 430 /// matched or not. 431 struct matched 432 { 433 BOOST_PROTO_CALLABLE() 434 typedef bool result_type; 435 436 /// \param sub The \c sub_match object. 437 /// \return <tt>sub.matched</tt> 438 template<typename Sub> operator ()boost::xpressive::op::matched439 bool operator()(Sub const &sub) const 440 { 441 return sub.matched; 442 } 443 }; 444 445 /// \brief \c length is a PolymorphicFunctionObject for fetching the length of \c sub_match. 446 struct length 447 { 448 BOOST_PROTO_CALLABLE() 449 template<typename Sig> 450 struct result {}; 451 452 template<typename This, typename Sub> 453 struct result<This(Sub)> 454 { 455 typedef typename remove_reference<Sub>::type::difference_type type; 456 }; 457 458 /// \param sub The \c sub_match object. 459 /// \return <tt>sub.length()</tt> 460 template<typename Sub> operator ()boost::xpressive::op::length461 typename Sub::difference_type operator()(Sub const &sub) const 462 { 463 return sub.length(); 464 } 465 }; 466 467 /// \brief \c str is a PolymorphicFunctionObject for turning a \c sub_match into an 468 /// equivalent \c std::string. 469 struct str 470 { 471 BOOST_PROTO_CALLABLE() 472 template<typename Sig> 473 struct result {}; 474 475 template<typename This, typename Sub> 476 struct result<This(Sub)> 477 { 478 typedef typename remove_reference<Sub>::type::string_type type; 479 }; 480 481 /// \param sub The \c sub_match object. 482 /// \return <tt>sub.str()</tt> 483 template<typename Sub> operator ()boost::xpressive::op::str484 typename Sub::string_type operator()(Sub const &sub) const 485 { 486 return sub.str(); 487 } 488 }; 489 490 // This codifies the return types of the various insert member 491 // functions found in sequence containers, the 2 flavors of 492 // associative containers, and strings. 493 // 494 /// \brief \c insert is a PolymorphicFunctionObject for inserting a value or a 495 /// sequence of values into a sequence container, an associative 496 /// container, or a string. 497 struct insert 498 { 499 BOOST_PROTO_CALLABLE() 500 501 /// INTERNAL ONLY 502 /// 503 struct detail 504 { 505 template<typename Sig, typename EnableIf = void> 506 struct result_detail 507 {}; 508 509 // assoc containers 510 template<typename This, typename Cont, typename Value> 511 struct result_detail<This(Cont, Value), void> 512 { 513 typedef typename remove_reference<Cont>::type cont_type; 514 typedef typename remove_reference<Value>::type value_type; 515 static cont_type &scont_; 516 static value_type &svalue_; 517 typedef char yes_type; 518 typedef char (&no_type)[2]; 519 static yes_type check_insert_return(typename cont_type::iterator); 520 static no_type check_insert_return(std::pair<typename cont_type::iterator, bool>); 521 BOOST_STATIC_CONSTANT(bool, is_iterator = (sizeof(yes_type) == sizeof(check_insert_return(scont_.insert(svalue_))))); 522 typedef 523 typename mpl::if_c< 524 is_iterator 525 , typename cont_type::iterator 526 , std::pair<typename cont_type::iterator, bool> 527 >::type 528 type; 529 }; 530 531 // sequence containers, assoc containers, strings 532 template<typename This, typename Cont, typename It, typename Value> 533 struct result_detail<This(Cont, It, Value), 534 typename disable_if< 535 mpl::or_< 536 is_integral<typename remove_cv<typename remove_reference<It>::type>::type> 537 , is_same< 538 typename remove_cv<typename remove_reference<It>::type>::type 539 , typename remove_cv<typename remove_reference<Value>::type>::type 540 > 541 > 542 >::type 543 > 544 { 545 typedef typename remove_reference<Cont>::type::iterator type; 546 }; 547 548 // strings 549 template<typename This, typename Cont, typename Size, typename T> 550 struct result_detail<This(Cont, Size, T), 551 typename enable_if< 552 is_integral<typename remove_cv<typename remove_reference<Size>::type>::type> 553 >::type 554 > 555 { 556 typedef typename remove_reference<Cont>::type &type; 557 }; 558 559 // assoc containers 560 template<typename This, typename Cont, typename It> 561 struct result_detail<This(Cont, It, It), void> 562 { 563 typedef void type; 564 }; 565 566 // sequence containers, strings 567 template<typename This, typename Cont, typename It, typename Size, typename Value> 568 struct result_detail<This(Cont, It, Size, Value), 569 typename disable_if< 570 is_integral<typename remove_cv<typename remove_reference<It>::type>::type> 571 >::type 572 > 573 { 574 typedef void type; 575 }; 576 577 // strings 578 template<typename This, typename Cont, typename Size, typename A0, typename A1> 579 struct result_detail<This(Cont, Size, A0, A1), 580 typename enable_if< 581 is_integral<typename remove_cv<typename remove_reference<Size>::type>::type> 582 >::type 583 > 584 { 585 typedef typename remove_reference<Cont>::type &type; 586 }; 587 588 // strings 589 template<typename This, typename Cont, typename Pos0, typename String, typename Pos1, typename Length> 590 struct result_detail<This(Cont, Pos0, String, Pos1, Length)> 591 { 592 typedef typename remove_reference<Cont>::type &type; 593 }; 594 }; 595 596 template<typename Sig> 597 struct result 598 { 599 typedef typename detail::result_detail<Sig>::type type; 600 }; 601 602 /// \overload 603 /// 604 template<typename Cont, typename A0> 605 typename result<insert(Cont &, A0 const &)>::type operator ()boost::xpressive::op::insert606 operator()(Cont &cont, A0 const &a0) const 607 { 608 return cont.insert(a0); 609 } 610 611 /// \overload 612 /// 613 template<typename Cont, typename A0, typename A1> 614 typename result<insert(Cont &, A0 const &, A1 const &)>::type operator ()boost::xpressive::op::insert615 operator()(Cont &cont, A0 const &a0, A1 const &a1) const 616 { 617 return cont.insert(a0, a1); 618 } 619 620 /// \overload 621 /// 622 template<typename Cont, typename A0, typename A1, typename A2> 623 typename result<insert(Cont &, A0 const &, A1 const &, A2 const &)>::type operator ()boost::xpressive::op::insert624 operator()(Cont &cont, A0 const &a0, A1 const &a1, A2 const &a2) const 625 { 626 return cont.insert(a0, a1, a2); 627 } 628 629 /// \param cont The container into which to insert the element(s) 630 /// \param a0 A value, iterator, or count 631 /// \param a1 A value, iterator, string, count, or character 632 /// \param a2 A value, iterator, or count 633 /// \param a3 A count 634 /// \return \li For the form <tt>insert()(cont, a0)</tt>, return <tt>cont.insert(a0)</tt>. 635 /// \li For the form <tt>insert()(cont, a0, a1)</tt>, return <tt>cont.insert(a0, a1)</tt>. 636 /// \li For the form <tt>insert()(cont, a0, a1, a2)</tt>, return <tt>cont.insert(a0, a1, a2)</tt>. 637 /// \li For the form <tt>insert()(cont, a0, a1, a2, a3)</tt>, return <tt>cont.insert(a0, a1, a2, a3)</tt>. 638 template<typename Cont, typename A0, typename A1, typename A2, typename A3> 639 typename result<insert(Cont &, A0 const &, A1 const &, A2 const &, A3 const &)>::type operator ()boost::xpressive::op::insert640 operator()(Cont &cont, A0 const &a0, A1 const &a1, A2 const &a2, A3 const &a3) const 641 { 642 return cont.insert(a0, a1, a2, a3); 643 } 644 }; 645 646 /// \brief \c make_pair is a PolymorphicFunctionObject for building a \c std::pair out of two parameters 647 struct make_pair 648 { 649 BOOST_PROTO_CALLABLE() 650 template<typename Sig> 651 struct result {}; 652 653 template<typename This, typename First, typename Second> 654 struct result<This(First, Second)> 655 { 656 /// \brief For exposition only 657 typedef typename decay<First>::type first_type; 658 /// \brief For exposition only 659 typedef typename decay<Second>::type second_type; 660 typedef std::pair<first_type, second_type> type; 661 }; 662 663 /// \param first The first element of the pair 664 /// \param second The second element of the pair 665 /// \return <tt>std::make_pair(first, second)</tt> 666 template<typename First, typename Second> operator ()boost::xpressive::op::make_pair667 std::pair<First, Second> operator()(First const &first, Second const &second) const 668 { 669 return std::make_pair(first, second); 670 } 671 }; 672 673 /// \brief \c as\<\> is a PolymorphicFunctionObject for lexically casting a parameter to a different type. 674 /// \tparam T The type to which to lexically cast the parameter. 675 template<typename T> 676 struct as 677 { 678 BOOST_PROTO_CALLABLE() 679 typedef T result_type; 680 681 /// \param val The value to lexically cast. 682 /// \return <tt>boost::lexical_cast\<T\>(val)</tt> 683 template<typename Value> operator ()boost::xpressive::op::as684 T operator()(Value const &val) const 685 { 686 return boost::lexical_cast<T>(val); 687 } 688 689 // Hack around some limitations in boost::lexical_cast 690 /// INTERNAL ONLY operator ()boost::xpressive::op::as691 T operator()(csub_match const &val) const 692 { 693 return val.matched 694 ? boost::lexical_cast<T>(boost::make_iterator_range(val.first, val.second)) 695 : boost::lexical_cast<T>(""); 696 } 697 698 #ifndef BOOST_XPRESSIVE_NO_WREGEX 699 /// INTERNAL ONLY operator ()boost::xpressive::op::as700 T operator()(wcsub_match const &val) const 701 { 702 return val.matched 703 ? boost::lexical_cast<T>(boost::make_iterator_range(val.first, val.second)) 704 : boost::lexical_cast<T>(""); 705 } 706 #endif 707 708 /// INTERNAL ONLY 709 template<typename BidiIter> operator ()boost::xpressive::op::as710 T operator()(sub_match<BidiIter> const &val) const 711 { 712 // If this assert fires, you're trying to coerce a sequences of non-characters 713 // to some other type. Xpressive doesn't know how to do that. 714 typedef typename iterator_value<BidiIter>::type char_type; 715 BOOST_MPL_ASSERT_MSG( 716 (xpressive::detail::is_char<char_type>::value) 717 , CAN_ONLY_CONVERT_FROM_CHARACTER_SEQUENCES 718 , (char_type) 719 ); 720 return this->impl(val, xpressive::detail::is_string_iterator<BidiIter>()); 721 } 722 723 private: 724 /// INTERNAL ONLY 725 template<typename RandIter> implboost::xpressive::op::as726 T impl(sub_match<RandIter> const &val, mpl::true_) const 727 { 728 return val.matched 729 ? boost::lexical_cast<T>(boost::make_iterator_range(&*val.first, &*val.first + (val.second - val.first))) 730 : boost::lexical_cast<T>(""); 731 } 732 733 /// INTERNAL ONLY 734 template<typename BidiIter> implboost::xpressive::op::as735 T impl(sub_match<BidiIter> const &val, mpl::false_) const 736 { 737 return boost::lexical_cast<T>(val.str()); 738 } 739 }; 740 741 /// \brief \c static_cast_\<\> is a PolymorphicFunctionObject for statically casting a parameter to a different type. 742 /// \tparam T The type to which to statically cast the parameter. 743 template<typename T> 744 struct static_cast_ 745 { 746 BOOST_PROTO_CALLABLE() 747 typedef T result_type; 748 749 /// \param val The value to statically cast. 750 /// \return <tt>static_cast\<T\>(val)</tt> 751 template<typename Value> operator ()boost::xpressive::op::static_cast_752 T operator()(Value const &val) const 753 { 754 return static_cast<T>(val); 755 } 756 }; 757 758 /// \brief \c dynamic_cast_\<\> is a PolymorphicFunctionObject for dynamically casting a parameter to a different type. 759 /// \tparam T The type to which to dynamically cast the parameter. 760 template<typename T> 761 struct dynamic_cast_ 762 { 763 BOOST_PROTO_CALLABLE() 764 typedef T result_type; 765 766 /// \param val The value to dynamically cast. 767 /// \return <tt>dynamic_cast\<T\>(val)</tt> 768 template<typename Value> operator ()boost::xpressive::op::dynamic_cast_769 T operator()(Value const &val) const 770 { 771 return dynamic_cast<T>(val); 772 } 773 }; 774 775 /// \brief \c const_cast_\<\> is a PolymorphicFunctionObject for const-casting a parameter to a cv qualification. 776 /// \tparam T The type to which to const-cast the parameter. 777 template<typename T> 778 struct const_cast_ 779 { 780 BOOST_PROTO_CALLABLE() 781 typedef T result_type; 782 783 /// \param val The value to const-cast. 784 /// \pre Types \c T and \c Value differ only in cv-qualification. 785 /// \return <tt>const_cast\<T\>(val)</tt> 786 template<typename Value> operator ()boost::xpressive::op::const_cast_787 T operator()(Value const &val) const 788 { 789 return const_cast<T>(val); 790 } 791 }; 792 793 /// \brief \c construct\<\> is a PolymorphicFunctionObject for constructing a new object. 794 /// \tparam T The type of the object to construct. 795 template<typename T> 796 struct construct 797 { 798 BOOST_PROTO_CALLABLE() 799 typedef T result_type; 800 801 /// \overload operator ()boost::xpressive::op::construct802 T operator()() const 803 { 804 return T(); 805 } 806 807 /// \overload 808 template<typename A0> operator ()boost::xpressive::op::construct809 T operator()(A0 const &a0) const 810 { 811 return T(a0); 812 } 813 814 /// \overload 815 template<typename A0, typename A1> operator ()boost::xpressive::op::construct816 T operator()(A0 const &a0, A1 const &a1) const 817 { 818 return T(a0, a1); 819 } 820 821 /// \param a0 The first argument to the constructor 822 /// \param a1 The second argument to the constructor 823 /// \param a2 The third argument to the constructor 824 /// \return <tt>T(a0,a1,...)</tt> 825 template<typename A0, typename A1, typename A2> operator ()boost::xpressive::op::construct826 T operator()(A0 const &a0, A1 const &a1, A2 const &a2) const 827 { 828 return T(a0, a1, a2); 829 } 830 }; 831 832 /// \brief \c throw_\<\> is a PolymorphicFunctionObject for throwing an exception. 833 /// \tparam Except The type of the object to throw. 834 template<typename Except> 835 struct throw_ 836 { 837 BOOST_PROTO_CALLABLE() 838 typedef void result_type; 839 840 /// \overload operator ()boost::xpressive::op::throw_841 void operator()() const 842 { 843 BOOST_THROW_EXCEPTION(Except()); 844 } 845 846 /// \overload 847 template<typename A0> operator ()boost::xpressive::op::throw_848 void operator()(A0 const &a0) const 849 { 850 BOOST_THROW_EXCEPTION(Except(a0)); 851 } 852 853 /// \overload 854 template<typename A0, typename A1> operator ()boost::xpressive::op::throw_855 void operator()(A0 const &a0, A1 const &a1) const 856 { 857 BOOST_THROW_EXCEPTION(Except(a0, a1)); 858 } 859 860 /// \param a0 The first argument to the constructor 861 /// \param a1 The second argument to the constructor 862 /// \param a2 The third argument to the constructor 863 /// \throw <tt>Except(a0,a1,...)</tt> 864 /// \note This function makes use of the \c BOOST_THROW_EXCEPTION macro 865 /// to actually throw the exception. See the documentation for the 866 /// Boost.Exception library. 867 template<typename A0, typename A1, typename A2> operator ()boost::xpressive::op::throw_868 void operator()(A0 const &a0, A1 const &a1, A2 const &a2) const 869 { 870 BOOST_THROW_EXCEPTION(Except(a0, a1, a2)); 871 } 872 }; 873 874 /// \brief \c unwrap_reference is a PolymorphicFunctionObject for unwrapping a <tt>boost::reference_wrapper\<\></tt>. 875 struct unwrap_reference 876 { 877 BOOST_PROTO_CALLABLE() 878 template<typename Sig> 879 struct result {}; 880 881 template<typename This, typename Ref> 882 struct result<This(Ref)> 883 { 884 typedef typename boost::unwrap_reference<Ref>::type &type; 885 }; 886 887 template<typename This, typename Ref> 888 struct result<This(Ref &)> 889 { 890 typedef typename boost::unwrap_reference<Ref>::type &type; 891 }; 892 893 /// \param r The <tt>boost::reference_wrapper\<T\></tt> to unwrap. 894 /// \return <tt>static_cast\<T &\>(r)</tt> 895 template<typename T> operator ()boost::xpressive::op::unwrap_reference896 T &operator()(boost::reference_wrapper<T> r) const 897 { 898 return static_cast<T &>(r); 899 } 900 }; 901 } 902 903 /// \brief A unary metafunction that turns an ordinary function object type into the type of 904 /// a deferred function object for use in xpressive semantic actions. 905 /// 906 /// Use \c xpressive::function\<\> to turn an ordinary polymorphic function object type 907 /// into a type that can be used to declare an object for use in xpressive semantic actions. 908 /// 909 /// For example, the global object \c xpressive::push_back can be used to create deferred actions 910 /// that have the effect of pushing a value into a container. It is defined with 911 /// \c xpressive::function\<\> as follows: 912 /// 913 /** \code 914 xpressive::function<xpressive::op::push_back>::type const push_back = {}; 915 \endcode 916 */ 917 /// 918 /// where \c op::push_back is an ordinary function object that pushes its second argument into 919 /// its first. Thus defined, \c xpressive::push_back can be used in semantic actions as follows: 920 /// 921 /** \code 922 namespace xp = boost::xpressive; 923 using xp::_; 924 std::list<int> result; 925 std::string str("1 23 456 7890"); 926 xp::sregex rx = (+_d)[ xp::push_back(xp::ref(result), xp::as<int>(_) ] 927 >> *(' ' >> (+_d)[ xp::push_back(xp::ref(result), xp::as<int>(_) ) ]); 928 \endcode 929 */ 930 template<typename PolymorphicFunctionObject> 931 struct function 932 { 933 typedef typename proto::terminal<PolymorphicFunctionObject>::type type; 934 }; 935 936 /// \brief \c at is a lazy PolymorphicFunctionObject for indexing into a sequence in an 937 /// xpressive semantic action. 938 function<op::at>::type const at = {{}}; 939 940 /// \brief \c push is a lazy PolymorphicFunctionObject for pushing a value into a container in an 941 /// xpressive semantic action. 942 function<op::push>::type const push = {{}}; 943 944 /// \brief \c push_back is a lazy PolymorphicFunctionObject for pushing a value into a container in an 945 /// xpressive semantic action. 946 function<op::push_back>::type const push_back = {{}}; 947 948 /// \brief \c push_front is a lazy PolymorphicFunctionObject for pushing a value into a container in an 949 /// xpressive semantic action. 950 function<op::push_front>::type const push_front = {{}}; 951 952 /// \brief \c pop is a lazy PolymorphicFunctionObject for popping the top element from a sequence in an 953 /// xpressive semantic action. 954 function<op::pop>::type const pop = {{}}; 955 956 /// \brief \c pop_back is a lazy PolymorphicFunctionObject for popping the back element from a sequence in an 957 /// xpressive semantic action. 958 function<op::pop_back>::type const pop_back = {{}}; 959 960 /// \brief \c pop_front is a lazy PolymorphicFunctionObject for popping the front element from a sequence in an 961 /// xpressive semantic action. 962 function<op::pop_front>::type const pop_front = {{}}; 963 964 /// \brief \c top is a lazy PolymorphicFunctionObject for accessing the top element from a stack in an 965 /// xpressive semantic action. 966 function<op::top>::type const top = {{}}; 967 968 /// \brief \c back is a lazy PolymorphicFunctionObject for fetching the back element of a sequence in an 969 /// xpressive semantic action. 970 function<op::back>::type const back = {{}}; 971 972 /// \brief \c front is a lazy PolymorphicFunctionObject for fetching the front element of a sequence in an 973 /// xpressive semantic action. 974 function<op::front>::type const front = {{}}; 975 976 /// \brief \c first is a lazy PolymorphicFunctionObject for accessing the first element of a \c std::pair\<\> in an 977 /// xpressive semantic action. 978 function<op::first>::type const first = {{}}; 979 980 /// \brief \c second is a lazy PolymorphicFunctionObject for accessing the second element of a \c std::pair\<\> in an 981 /// xpressive semantic action. 982 function<op::second>::type const second = {{}}; 983 984 /// \brief \c matched is a lazy PolymorphicFunctionObject for accessing the \c matched member of a \c xpressive::sub_match\<\> in an 985 /// xpressive semantic action. 986 function<op::matched>::type const matched = {{}}; 987 988 /// \brief \c length is a lazy PolymorphicFunctionObject for computing the length of a \c xpressive::sub_match\<\> in an 989 /// xpressive semantic action. 990 function<op::length>::type const length = {{}}; 991 992 /// \brief \c str is a lazy PolymorphicFunctionObject for converting a \c xpressive::sub_match\<\> to a \c std::basic_string\<\> in an 993 /// xpressive semantic action. 994 function<op::str>::type const str = {{}}; 995 996 /// \brief \c insert is a lazy PolymorphicFunctionObject for inserting a value or a range of values into a sequence in an 997 /// xpressive semantic action. 998 function<op::insert>::type const insert = {{}}; 999 1000 /// \brief \c make_pair is a lazy PolymorphicFunctionObject for making a \c std::pair\<\> in an 1001 /// xpressive semantic action. 1002 function<op::make_pair>::type const make_pair = {{}}; 1003 1004 /// \brief \c unwrap_reference is a lazy PolymorphicFunctionObject for unwrapping a \c boost::reference_wrapper\<\> in an 1005 /// xpressive semantic action. 1006 function<op::unwrap_reference>::type const unwrap_reference = {{}}; 1007 1008 /// \brief \c value\<\> is a lazy wrapper for a value that can be used in xpressive semantic actions. 1009 /// \tparam T The type of the value to store. 1010 /// 1011 /// Below is an example that shows where \c <tt>value\<\></tt> is useful. 1012 /// 1013 /** \code 1014 sregex good_voodoo(boost::shared_ptr<int> pi) 1015 { 1016 using namespace boost::xpressive; 1017 // Use val() to hold the shared_ptr by value: 1018 sregex rex = +( _d [ ++*val(pi) ] >> '!' ); 1019 // OK, rex holds a reference count to the integer. 1020 return rex; 1021 } 1022 \endcode 1023 */ 1024 /// 1025 /// In the above code, \c xpressive::val() is a function that returns a \c value\<\> object. Had 1026 /// \c val() not been used here, the operation <tt>++*pi</tt> would have been evaluated eagerly 1027 /// once, instead of lazily when the regex match happens. 1028 template<typename T> 1029 struct value 1030 : proto::extends<typename proto::terminal<T>::type, value<T> > 1031 { 1032 /// INTERNAL ONLY 1033 typedef proto::extends<typename proto::terminal<T>::type, value<T> > base_type; 1034 1035 /// \brief Store a default-constructed \c T valueboost::xpressive::value1036 value() 1037 : base_type() 1038 {} 1039 1040 /// \param t The initial value. 1041 /// \brief Store a copy of \c t. valueboost::xpressive::value1042 explicit value(T const &t) 1043 : base_type(base_type::proto_base_expr::make(t)) 1044 {} 1045 1046 using base_type::operator=; 1047 1048 /// \overload getboost::xpressive::value1049 T &get() 1050 { 1051 return proto::value(*this); 1052 } 1053 1054 /// \brief Fetch the stored value getboost::xpressive::value1055 T const &get() const 1056 { 1057 return proto::value(*this); 1058 } 1059 }; 1060 1061 /// \brief \c reference\<\> is a lazy wrapper for a reference that can be used in 1062 /// xpressive semantic actions. 1063 /// 1064 /// \tparam T The type of the referent. 1065 /// 1066 /// Here is an example of how to use \c reference\<\> to create a lazy reference to 1067 /// an existing object so it can be read and written in an xpressive semantic action. 1068 /// 1069 /** \code 1070 using namespace boost::xpressive; 1071 std::map<std::string, int> result; 1072 reference<std::map<std::string, int> > result_ref(result); 1073 1074 // Match a word and an integer, separated by =>, 1075 // and then stuff the result into a std::map<> 1076 sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) ) 1077 [ result_ref[s1] = as<int>(s2) ]; 1078 \endcode 1079 */ 1080 template<typename T> 1081 struct reference 1082 : proto::extends<typename proto::terminal<reference_wrapper<T> >::type, reference<T> > 1083 { 1084 /// INTERNAL ONLY 1085 typedef proto::extends<typename proto::terminal<reference_wrapper<T> >::type, reference<T> > base_type; 1086 1087 /// \param t Reference to object 1088 /// \brief Store a reference to \c t referenceboost::xpressive::reference1089 explicit reference(T &t) 1090 : base_type(base_type::proto_base_expr::make(boost::ref(t))) 1091 {} 1092 1093 using base_type::operator=; 1094 1095 /// \brief Fetch the stored value getboost::xpressive::reference1096 T &get() const 1097 { 1098 return proto::value(*this).get(); 1099 } 1100 }; 1101 1102 /// \brief \c local\<\> is a lazy wrapper for a reference to a value that is stored within the local itself. 1103 /// It is for use within xpressive semantic actions. 1104 /// 1105 /// \tparam T The type of the local variable. 1106 /// 1107 /// Below is an example of how to use \c local\<\> in semantic actions. 1108 /// 1109 /** \code 1110 using namespace boost::xpressive; 1111 local<int> i(0); 1112 std::string str("1!2!3?"); 1113 // count the exciting digits, but not the 1114 // questionable ones. 1115 sregex rex = +( _d [ ++i ] >> '!' ); 1116 regex_search(str, rex); 1117 assert( i.get() == 2 ); 1118 \endcode 1119 */ 1120 /// 1121 /// \note As the name "local" suggests, \c local\<\> objects and the regexes 1122 /// that refer to them should never leave the local scope. The value stored 1123 /// within the local object will be destroyed at the end of the \c local\<\>'s 1124 /// lifetime, and any regex objects still holding the \c local\<\> will be 1125 /// left with a dangling reference. 1126 template<typename T> 1127 struct local 1128 : detail::value_wrapper<T> 1129 , proto::terminal<reference_wrapper<T> >::type 1130 { 1131 /// INTERNAL ONLY 1132 typedef typename proto::terminal<reference_wrapper<T> >::type base_type; 1133 1134 /// \brief Store a default-constructed value of type \c T localboost::xpressive::local1135 local() 1136 : detail::value_wrapper<T>() 1137 , base_type(base_type::make(boost::ref(detail::value_wrapper<T>::value))) 1138 {} 1139 1140 /// \param t The initial value. 1141 /// \brief Store a default-constructed value of type \c T localboost::xpressive::local1142 explicit local(T const &t) 1143 : detail::value_wrapper<T>(t) 1144 , base_type(base_type::make(boost::ref(detail::value_wrapper<T>::value))) 1145 {} 1146 1147 using base_type::operator=; 1148 1149 /// Fetch the wrapped value. getboost::xpressive::local1150 T &get() 1151 { 1152 return proto::value(*this); 1153 } 1154 1155 /// \overload getboost::xpressive::local1156 T const &get() const 1157 { 1158 return proto::value(*this); 1159 } 1160 }; 1161 1162 /// \brief \c as() is a lazy funtion for lexically casting a parameter to a different type. 1163 /// \tparam T The type to which to lexically cast the parameter. 1164 /// \param a The lazy value to lexically cast. 1165 /// \return A lazy object that, when evaluated, lexically casts its argument to the desired type. 1166 template<typename T, typename A> 1167 typename detail::make_function::impl<op::as<T> const, A const &>::result_type const as(A const & a)1168 as(A const &a) 1169 { 1170 return detail::make_function::impl<op::as<T> const, A const &>()((op::as<T>()), a); 1171 } 1172 1173 /// \brief \c static_cast_ is a lazy funtion for statically casting a parameter to a different type. 1174 /// \tparam T The type to which to statically cast the parameter. 1175 /// \param a The lazy value to statically cast. 1176 /// \return A lazy object that, when evaluated, statically casts its argument to the desired type. 1177 template<typename T, typename A> 1178 typename detail::make_function::impl<op::static_cast_<T> const, A const &>::result_type const static_cast_(A const & a)1179 static_cast_(A const &a) 1180 { 1181 return detail::make_function::impl<op::static_cast_<T> const, A const &>()((op::static_cast_<T>()), a); 1182 } 1183 1184 /// \brief \c dynamic_cast_ is a lazy funtion for dynamically casting a parameter to a different type. 1185 /// \tparam T The type to which to dynamically cast the parameter. 1186 /// \param a The lazy value to dynamically cast. 1187 /// \return A lazy object that, when evaluated, dynamically casts its argument to the desired type. 1188 template<typename T, typename A> 1189 typename detail::make_function::impl<op::dynamic_cast_<T> const, A const &>::result_type const dynamic_cast_(A const & a)1190 dynamic_cast_(A const &a) 1191 { 1192 return detail::make_function::impl<op::dynamic_cast_<T> const, A const &>()((op::dynamic_cast_<T>()), a); 1193 } 1194 1195 /// \brief \c dynamic_cast_ is a lazy funtion for const-casting a parameter to a different type. 1196 /// \tparam T The type to which to const-cast the parameter. 1197 /// \param a The lazy value to const-cast. 1198 /// \return A lazy object that, when evaluated, const-casts its argument to the desired type. 1199 template<typename T, typename A> 1200 typename detail::make_function::impl<op::const_cast_<T> const, A const &>::result_type const const_cast_(A const & a)1201 const_cast_(A const &a) 1202 { 1203 return detail::make_function::impl<op::const_cast_<T> const, A const &>()((op::const_cast_<T>()), a); 1204 } 1205 1206 /// \brief Helper for constructing \c value\<\> objects. 1207 /// \return <tt>value\<T\>(t)</tt> 1208 template<typename T> val(T const & t)1209 value<T> const val(T const &t) 1210 { 1211 return value<T>(t); 1212 } 1213 1214 /// \brief Helper for constructing \c reference\<\> objects. 1215 /// \return <tt>reference\<T\>(t)</tt> 1216 template<typename T> ref(T & t)1217 reference<T> const ref(T &t) 1218 { 1219 return reference<T>(t); 1220 } 1221 1222 /// \brief Helper for constructing \c reference\<\> objects that 1223 /// store a reference to const. 1224 /// \return <tt>reference\<T const\>(t)</tt> 1225 template<typename T> cref(T const & t)1226 reference<T const> const cref(T const &t) 1227 { 1228 return reference<T const>(t); 1229 } 1230 1231 /// \brief For adding user-defined assertions to your regular expressions. 1232 /// 1233 /// \param t The UnaryPredicate object or Boolean semantic action. 1234 /// 1235 /// A \RefSect{user_s_guide.semantic_actions_and_user_defined_assertions.user_defined_assertions,user-defined assertion} 1236 /// is a kind of semantic action that evaluates 1237 /// a Boolean lambda and, if it evaluates to false, causes the match to 1238 /// fail at that location in the string. This will cause backtracking, 1239 /// so the match may ultimately succeed. 1240 /// 1241 /// To use \c check() to specify a user-defined assertion in a regex, use the 1242 /// following syntax: 1243 /// 1244 /** \code 1245 sregex s = (_d >> _d)[check( XXX )]; // XXX is a custom assertion 1246 \endcode 1247 */ 1248 /// 1249 /// The assertion is evaluated with a \c sub_match\<\> object that delineates 1250 /// what part of the string matched the sub-expression to which the assertion 1251 /// was attached. 1252 /// 1253 /// \c check() can be used with an ordinary predicate that takes a 1254 /// \c sub_match\<\> object as follows: 1255 /// 1256 /** \code 1257 // A predicate that is true IFF a sub-match is 1258 // either 3 or 6 characters long. 1259 struct three_or_six 1260 { 1261 bool operator()(ssub_match const &sub) const 1262 { 1263 return sub.length() == 3 || sub.length() == 6; 1264 } 1265 }; 1266 1267 // match words of 3 characters or 6 characters. 1268 sregex rx = (bow >> +_w >> eow)[ check(three_or_six()) ] ; 1269 \endcode 1270 */ 1271 /// 1272 /// Alternately, \c check() can be used to define inline custom 1273 /// assertions with the same syntax as is used to define semantic 1274 /// actions. The following code is equivalent to above: 1275 /// 1276 /** \code 1277 // match words of 3 characters or 6 characters. 1278 sregex rx = (bow >> +_w >> eow)[ check(length(_)==3 || length(_)==6) ] ; 1279 \endcode 1280 */ 1281 /// 1282 /// Within a custom assertion, \c _ is a placeholder for the \c sub_match\<\> 1283 /// That delineates the part of the string matched by the sub-expression to 1284 /// which the custom assertion was attached. 1285 #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful. 1286 template<typename T> 1287 detail::unspecified check(T const &t); 1288 #else 1289 proto::terminal<detail::check_tag>::type const check = {{}}; 1290 #endif 1291 1292 /// \brief For binding local variables to placeholders in semantic actions when 1293 /// constructing a \c regex_iterator or a \c regex_token_iterator. 1294 /// 1295 /// \param args A set of argument bindings, where each argument binding is an assignment 1296 /// expression, the left hand side of which must be an instance of \c placeholder\<X\> 1297 /// for some \c X, and the right hand side is an lvalue of type \c X. 1298 /// 1299 /// \c xpressive::let() serves the same purpose as <tt>match_results::let()</tt>; 1300 /// that is, it binds a placeholder to a local value. The purpose is to allow a 1301 /// regex with semantic actions to be defined that refers to objects that do not yet exist. 1302 /// Rather than referring directly to an object, a semantic action can refer to a placeholder, 1303 /// and the value of the placeholder can be specified later with a <em>let expression</em>. 1304 /// The <em>let expression</em> created with \c let() is passed to the constructor of either 1305 /// \c regex_iterator or \c regex_token_iterator. 1306 /// 1307 /// See the section \RefSect{user_s_guide.semantic_actions_and_user_defined_assertions.referring_to_non_local_variables, "Referring to Non-Local Variables"} 1308 /// in the Users' Guide for more discussion. 1309 /// 1310 /// \em Example: 1311 /// 1312 /** 1313 \code 1314 // Define a placeholder for a map object: 1315 placeholder<std::map<std::string, int> > _map; 1316 1317 // Match a word and an integer, separated by =>, 1318 // and then stuff the result into a std::map<> 1319 sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) ) 1320 [ _map[s1] = as<int>(s2) ]; 1321 1322 // The string to parse 1323 std::string str("aaa=>1 bbb=>23 ccc=>456"); 1324 1325 // Here is the actual map to fill in: 1326 std::map<std::string, int> result; 1327 1328 // Create a regex_iterator to find all the matches 1329 sregex_iterator it(str.begin(), str.end(), pair, let(_map=result)); 1330 sregex_iterator end; 1331 1332 // step through all the matches, and fill in 1333 // the result map 1334 while(it != end) 1335 ++it; 1336 1337 std::cout << result["aaa"] << '\n'; 1338 std::cout << result["bbb"] << '\n'; 1339 std::cout << result["ccc"] << '\n'; 1340 \endcode 1341 */ 1342 /// 1343 /// The above code displays: 1344 /// 1345 /** \code{.txt} 1346 1 1347 23 1348 456 1349 \endcode 1350 */ 1351 #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful. 1352 template<typename...ArgBindings> 1353 detail::unspecified let(ArgBindings const &...args); 1354 #else 1355 detail::let_<proto::terminal<detail::let_tag>::type> const let = {{{}}}; 1356 #endif 1357 1358 /// \brief For defining a placeholder to stand in for a variable a semantic action. 1359 /// 1360 /// Use \c placeholder\<\> to define a placeholder for use in semantic actions to stand 1361 /// in for real objects. The use of placeholders allows regular expressions with actions 1362 /// to be defined once and reused in many contexts to read and write from objects which 1363 /// were not available when the regex was defined. 1364 /// 1365 /// \tparam T The type of the object for which this placeholder stands in. 1366 /// \tparam I An optional identifier that can be used to distinguish this placeholder 1367 /// from others that may be used in the same semantic action that happen 1368 /// to have the same type. 1369 /// 1370 /// You can use \c placeholder\<\> by creating an object of type \c placeholder\<T\> 1371 /// and using that object in a semantic action exactly as you intend an object of 1372 /// type \c T to be used. 1373 /// 1374 /** 1375 \code 1376 placeholder<int> _i; 1377 placeholder<double> _d; 1378 1379 sregex rex = ( some >> regex >> here ) 1380 [ ++_i, _d *= _d ]; 1381 \endcode 1382 */ 1383 /// 1384 /// Then, when doing a pattern match with either \c regex_search(), 1385 /// \c regex_match() or \c regex_replace(), pass a \c match_results\<\> object that 1386 /// contains bindings for the placeholders used in the regex object's semantic actions. 1387 /// You can create the bindings by calling \c match_results::let as follows: 1388 /// 1389 /** 1390 \code 1391 int i = 0; 1392 double d = 3.14; 1393 1394 smatch what; 1395 what.let(_i = i) 1396 .let(_d = d); 1397 1398 if(regex_match("some string", rex, what)) 1399 // i and d mutated here 1400 \endcode 1401 */ 1402 /// 1403 /// If a semantic action executes that contains an unbound placeholder, a exception of 1404 /// type \c regex_error is thrown. 1405 /// 1406 /// See the discussion for \c xpressive::let() and the 1407 /// \RefSect{user_s_guide.semantic_actions_and_user_defined_assertions.referring_to_non_local_variables, "Referring to Non-Local Variables"} 1408 /// section in the Users' Guide for more information. 1409 /// 1410 /// <em>Example:</em> 1411 /// 1412 /** 1413 \code 1414 // Define a placeholder for a map object: 1415 placeholder<std::map<std::string, int> > _map; 1416 1417 // Match a word and an integer, separated by =>, 1418 // and then stuff the result into a std::map<> 1419 sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) ) 1420 [ _map[s1] = as<int>(s2) ]; 1421 1422 // Match one or more word/integer pairs, separated 1423 // by whitespace. 1424 sregex rx = pair >> *(+_s >> pair); 1425 1426 // The string to parse 1427 std::string str("aaa=>1 bbb=>23 ccc=>456"); 1428 1429 // Here is the actual map to fill in: 1430 std::map<std::string, int> result; 1431 1432 // Bind the _map placeholder to the actual map 1433 smatch what; 1434 what.let( _map = result ); 1435 1436 // Execute the match and fill in result map 1437 if(regex_match(str, what, rx)) 1438 { 1439 std::cout << result["aaa"] << '\n'; 1440 std::cout << result["bbb"] << '\n'; 1441 std::cout << result["ccc"] << '\n'; 1442 } 1443 \endcode 1444 */ 1445 #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful. 1446 template<typename T, int I = 0> 1447 struct placeholder 1448 { 1449 /// \param t The object to associate with this placeholder 1450 /// \return An object of unspecified type that records the association of \c t 1451 /// with \c *this. 1452 detail::unspecified operator=(T &t) const; 1453 /// \overload 1454 detail::unspecified operator=(T const &t) const; 1455 }; 1456 #else 1457 template<typename T, int I, typename Dummy> 1458 struct placeholder 1459 { 1460 typedef placeholder<T, I, Dummy> this_type; 1461 typedef 1462 typename proto::terminal<detail::action_arg<T, mpl::int_<I> > >::type 1463 action_arg_type; 1464 1465 BOOST_PROTO_EXTENDS(action_arg_type, this_type, proto::default_domain) 1466 }; 1467 #endif 1468 1469 /// \brief A lazy funtion for constructing objects objects of the specified type. 1470 /// \tparam T The type of object to construct. 1471 /// \param args The arguments to the constructor. 1472 /// \return A lazy object that, when evaluated, returns <tt>T(xs...)</tt>, where 1473 /// <tt>xs...</tt> is the result of evaluating the lazy arguments 1474 /// <tt>args...</tt>. 1475 #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED // A hack so Doxygen emits something more meaningful. 1476 template<typename T, typename ...Args> 1477 detail::unspecified construct(Args const &...args); 1478 #else 1479 /// INTERNAL ONLY 1480 #define BOOST_PROTO_LOCAL_MACRO(N, typename_A, A_const_ref, A_const_ref_a, a) \ 1481 template<typename X2_0 BOOST_PP_COMMA_IF(N) typename_A(N)> \ 1482 typename detail::make_function::impl< \ 1483 op::construct<X2_0> const \ 1484 BOOST_PP_COMMA_IF(N) A_const_ref(N) \ 1485 >::result_type const \ 1486 construct(A_const_ref_a(N)) \ 1487 { \ 1488 return detail::make_function::impl< \ 1489 op::construct<X2_0> const \ 1490 BOOST_PP_COMMA_IF(N) A_const_ref(N) \ 1491 >()((op::construct<X2_0>()) BOOST_PP_COMMA_IF(N) a(N)); \ 1492 } \ 1493 \ 1494 template<typename X2_0 BOOST_PP_COMMA_IF(N) typename_A(N)> \ 1495 typename detail::make_function::impl< \ 1496 op::throw_<X2_0> const \ 1497 BOOST_PP_COMMA_IF(N) A_const_ref(N) \ 1498 >::result_type const \ 1499 throw_(A_const_ref_a(N)) \ 1500 { \ 1501 return detail::make_function::impl< \ 1502 op::throw_<X2_0> const \ 1503 BOOST_PP_COMMA_IF(N) A_const_ref(N) \ 1504 >()((op::throw_<X2_0>()) BOOST_PP_COMMA_IF(N) a(N)); \ 1505 } \ 1506 /**/ 1507 1508 #define BOOST_PROTO_LOCAL_a BOOST_PROTO_a ///< INTERNAL ONLY 1509 #define BOOST_PROTO_LOCAL_LIMITS (0, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY)) ///< INTERNAL ONLY 1510 #include BOOST_PROTO_LOCAL_ITERATE() 1511 #endif 1512 1513 namespace detail 1514 { ignore_unused_regex_actions()1515 inline void ignore_unused_regex_actions() 1516 { 1517 detail::ignore_unused(xpressive::at); 1518 detail::ignore_unused(xpressive::push); 1519 detail::ignore_unused(xpressive::push_back); 1520 detail::ignore_unused(xpressive::push_front); 1521 detail::ignore_unused(xpressive::pop); 1522 detail::ignore_unused(xpressive::pop_back); 1523 detail::ignore_unused(xpressive::pop_front); 1524 detail::ignore_unused(xpressive::top); 1525 detail::ignore_unused(xpressive::back); 1526 detail::ignore_unused(xpressive::front); 1527 detail::ignore_unused(xpressive::first); 1528 detail::ignore_unused(xpressive::second); 1529 detail::ignore_unused(xpressive::matched); 1530 detail::ignore_unused(xpressive::length); 1531 detail::ignore_unused(xpressive::str); 1532 detail::ignore_unused(xpressive::insert); 1533 detail::ignore_unused(xpressive::make_pair); 1534 detail::ignore_unused(xpressive::unwrap_reference); 1535 detail::ignore_unused(xpressive::check); 1536 detail::ignore_unused(xpressive::let); 1537 } 1538 1539 struct mark_nbr 1540 { 1541 BOOST_PROTO_CALLABLE() 1542 typedef int result_type; 1543 operator ()boost::xpressive::detail::mark_nbr1544 int operator()(mark_placeholder m) const 1545 { 1546 return m.mark_number_; 1547 } 1548 }; 1549 1550 struct ReplaceAlgo 1551 : proto::or_< 1552 proto::when< 1553 proto::terminal<mark_placeholder> 1554 , op::at(proto::_data, proto::call<mark_nbr(proto::_value)>) 1555 > 1556 , proto::when< 1557 proto::terminal<any_matcher> 1558 , op::at(proto::_data, proto::size_t<0>) 1559 > 1560 , proto::when< 1561 proto::terminal<reference_wrapper<proto::_> > 1562 , op::unwrap_reference(proto::_value) 1563 > 1564 , proto::_default<ReplaceAlgo> 1565 > 1566 {}; 1567 } 1568 }} 1569 1570 #if BOOST_MSVC 1571 #pragma warning(pop) 1572 #endif 1573 1574 #endif // BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007 1575