fix doc example typo
[boost.git] / boost / xpressive / regex_actions.hpp
blob2f31f1ef406d305bbe71f634940e3619cd9b03a8
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)
9 #ifndef BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007
10 #define BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007
12 // MS compatible compilers support #pragma once
13 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
14 # pragma once
15 #endif
17 #include <boost/config.hpp>
18 #include <boost/ref.hpp>
19 #include <boost/mpl/if.hpp>
20 #include <boost/mpl/or.hpp>
21 #include <boost/mpl/int.hpp>
22 #include <boost/lexical_cast.hpp>
23 #include <boost/throw_exception.hpp>
24 #include <boost/utility/enable_if.hpp>
25 #include <boost/type_traits/is_const.hpp>
26 #include <boost/type_traits/is_integral.hpp>
27 #include <boost/type_traits/remove_cv.hpp>
28 #include <boost/type_traits/remove_reference.hpp>
29 #include <boost/xpressive/detail/detail_fwd.hpp>
30 #include <boost/xpressive/detail/core/state.hpp>
31 #include <boost/xpressive/detail/core/matcher/attr_matcher.hpp>
32 #include <boost/xpressive/detail/core/matcher/attr_end_matcher.hpp>
33 #include <boost/xpressive/detail/core/matcher/attr_begin_matcher.hpp>
34 #include <boost/xpressive/detail/core/matcher/predicate_matcher.hpp>
35 #include <boost/xpressive/detail/utility/ignore_unused.hpp>
37 // These are very often needed by client code.
38 #include <boost/typeof/std/map.hpp>
39 #include <boost/typeof/std/string.hpp>
41 // Doxygen can't handle proto :-(
42 #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
43 # include <boost/proto/transform/arg.hpp>
44 # include <boost/proto/transform/when.hpp>
45 # include <boost/xpressive/detail/core/matcher/action_matcher.hpp>
46 #endif
48 /// INTERNAL ONLY
49 ///
50 #define UNREF(x) typename remove_reference<x>::type
52 /// INTERNAL ONLY
53 ///
54 #define UNCVREF(x) typename remove_cv<typename remove_reference<x>::type>::type
56 #if BOOST_MSVC
57 #pragma warning(push)
58 #pragma warning(disable : 4510) // default constructor could not be generated
59 #pragma warning(disable : 4512) // assignment operator could not be generated
60 #pragma warning(disable : 4610) // can never be instantiated - user defined constructor required
61 #endif
63 namespace boost { namespace xpressive
66 namespace detail
68 template<typename T, typename U>
69 struct action_arg
71 typedef T type;
72 typedef typename add_reference<T>::type reference;
74 reference cast(void *pv) const
76 return *static_cast<UNREF(T) *>(pv);
80 template<typename T>
81 struct value_wrapper
83 value_wrapper()
84 : value()
87 value_wrapper(T const &t)
88 : value(t)
91 T value;
94 struct check_tag
95 {};
97 struct BindArg : proto::callable
99 typedef int result_type;
101 template<typename Data, typename Expr>
102 int operator ()(Data &data, Expr const &expr) const
104 data.let(expr);
105 return 0;
109 struct let_tag
112 struct BindArgs
113 : proto::when<
114 // let(_a = b, _c = d)
115 proto::function<
116 proto::terminal<let_tag>
117 , proto::vararg<proto::assign<proto::_, proto::_> >
119 , proto::function<
120 proto::_state // no-op
121 , proto::vararg<proto::call<BindArg(proto::_data, proto::_)> >
126 struct let_domain
127 : boost::proto::domain<boost::proto::pod_generator<let_> >
130 template<typename Expr>
131 struct let_
133 BOOST_PROTO_BASIC_EXTENDS(Expr, let_<Expr>, let_domain)
134 BOOST_PROTO_EXTENDS_FUNCTION()
137 template<typename Args, typename BidiIter>
138 void bind_args(let_<Args> const &args, match_results<BidiIter> &what)
140 BindArgs::impl<let_<Args> const &, int, match_results<BidiIter> &>()(
141 args
143 , what
147 template<typename BidiIter>
148 struct replacement_context
149 : proto::callable_context<replacement_context<BidiIter> const>
151 replacement_context(match_results<BidiIter> const &what)
152 : what_(what)
155 template<typename Sig>
156 struct result;
158 template<typename This>
159 struct result<This(proto::tag::terminal, mark_placeholder const &)>
161 typedef sub_match<BidiIter> const &type;
164 template<typename This>
165 struct result<This(proto::tag::terminal, any_matcher const &)>
167 typedef sub_match<BidiIter> const &type;
170 template<typename This, typename T>
171 struct result<This(proto::tag::terminal, reference_wrapper<T> const &)>
173 typedef T &type;
176 sub_match<BidiIter> const &operator ()(proto::tag::terminal, mark_placeholder m) const
178 return this->what_[m.mark_number_];
181 sub_match<BidiIter> const &operator ()(proto::tag::terminal, any_matcher) const
183 return this->what_[0];
186 template<typename T>
187 T &operator ()(proto::tag::terminal, reference_wrapper<T> r) const
189 return r;
191 private:
192 match_results<BidiIter> const &what_;
196 namespace op
198 struct push
200 typedef void result_type;
202 template<typename Sequence, typename Value>
203 void operator()(Sequence &seq, Value const &val) const
205 seq.push(val);
209 struct push_back
211 typedef void result_type;
213 template<typename Sequence, typename Value>
214 void operator()(Sequence &seq, Value const &val) const
216 seq.push_back(val);
220 struct push_front
222 typedef void result_type;
224 template<typename Sequence, typename Value>
225 void operator()(Sequence &seq, Value const &val) const
227 seq.push_front(val);
231 struct pop
233 typedef void result_type;
235 template<typename Sequence>
236 void operator()(Sequence &seq) const
238 seq.pop();
242 struct pop_back
244 typedef void result_type;
246 template<typename Sequence>
247 void operator()(Sequence &seq) const
249 seq.pop_back();
253 struct pop_front
255 typedef void result_type;
257 template<typename Sequence>
258 void operator()(Sequence &seq) const
260 seq.pop_front();
264 struct front
266 template<typename Sig>
267 struct result {};
269 template<typename This, typename Sequence>
270 struct result<This(Sequence)>
272 typedef UNREF(Sequence) sequence_type;
273 typedef
274 typename mpl::if_<
275 is_const<sequence_type>
276 , typename sequence_type::const_reference
277 , typename sequence_type::reference
278 >::type
279 type;
282 template<typename Sequence>
283 typename result<front(Sequence &)>::type operator()(Sequence &seq) const
285 return seq.front();
289 struct back
291 template<typename Sig>
292 struct result {};
294 template<typename This, typename Sequence>
295 struct result<This(Sequence)>
297 typedef UNREF(Sequence) sequence_type;
298 typedef
299 typename mpl::if_<
300 is_const<sequence_type>
301 , typename sequence_type::const_reference
302 , typename sequence_type::reference
303 >::type
304 type;
307 template<typename Sequence>
308 typename result<back(Sequence &)>::type operator()(Sequence &seq) const
310 return seq.back();
314 struct top
316 template<typename Sig>
317 struct result {};
319 template<typename This, typename Sequence>
320 struct result<This(Sequence)>
322 typedef UNREF(Sequence) sequence_type;
323 typedef
324 typename mpl::if_<
325 is_const<sequence_type>
326 , typename sequence_type::value_type const &
327 , typename sequence_type::value_type &
328 >::type
329 type;
332 template<typename Sequence>
333 typename result<top(Sequence &)>::type operator()(Sequence &seq) const
335 return seq.top();
339 struct first
341 template<typename Sig>
342 struct result {};
344 template<typename This, typename Pair>
345 struct result<This(Pair)>
347 typedef UNREF(Pair)::first_type type;
350 template<typename Pair>
351 typename Pair::first_type operator()(Pair const &p) const
353 return p.first;
357 struct second
359 template<typename Sig>
360 struct result {};
362 template<typename This, typename Pair>
363 struct result<This(Pair)>
365 typedef UNREF(Pair)::second_type type;
368 template<typename Pair>
369 typename Pair::second_type operator()(Pair const &p) const
371 return p.second;
375 struct matched
377 typedef bool result_type;
379 template<typename Sub>
380 bool operator()(Sub const &sub) const
382 return sub.matched;
386 struct length
388 template<typename Sig>
389 struct result {};
391 template<typename This, typename Sub>
392 struct result<This(Sub)>
394 typedef UNREF(Sub)::difference_type type;
397 template<typename Sub>
398 typename Sub::difference_type operator()(Sub const &sub) const
400 return sub.length();
404 struct str
406 template<typename Sig>
407 struct result {};
409 template<typename This, typename Sub>
410 struct result<This(Sub)>
412 typedef UNREF(Sub)::string_type type;
415 template<typename Sub>
416 typename Sub::string_type operator()(Sub const &sub) const
418 return sub.str();
422 // This codifies the return types of the various insert member
423 // functions found in sequence containers, the 2 flavors of
424 // associative containers, and strings.
425 struct insert
427 template<typename Sig, typename EnableIf = void>
428 struct result
431 // assoc containers
432 template<typename This, typename Cont, typename Value>
433 struct result<This(Cont, Value), void>
435 typedef UNREF(Cont) cont_type;
436 typedef UNREF(Value) value_type;
437 static cont_type &scont_;
438 static value_type &svalue_;
439 typedef char yes_type;
440 typedef char (&no_type)[2];
441 static yes_type check_insert_return(typename cont_type::iterator);
442 static no_type check_insert_return(std::pair<typename cont_type::iterator, bool>);
443 BOOST_STATIC_CONSTANT(bool, is_iterator = (sizeof(yes_type) == sizeof(check_insert_return(scont_.insert(svalue_)))));
444 typedef
445 typename mpl::if_c<
446 is_iterator
447 , typename cont_type::iterator
448 , std::pair<typename cont_type::iterator, bool>
449 >::type
450 type;
453 // sequence containers, assoc containers, strings
454 template<typename This, typename Cont, typename It, typename Value>
455 struct result<This(Cont, It, Value),
456 typename disable_if<mpl::or_<is_integral<UNCVREF(It)>, is_same<UNCVREF(It), UNCVREF(Value)> > >::type>
458 typedef UNREF(Cont)::iterator type;
461 // strings
462 template<typename This, typename Cont, typename Size, typename T>
463 struct result<This(Cont, Size, T),
464 typename enable_if<is_integral<UNCVREF(Size)> >::type>
466 typedef UNREF(Cont) &type;
469 // assoc containers
470 template<typename This, typename Cont, typename It>
471 struct result<This(Cont, It, It), void>
473 typedef void type;
476 // sequence containers, strings
477 template<typename This, typename Cont, typename It, typename Size, typename Value>
478 struct result<This(Cont, It, Size, Value),
479 typename disable_if<is_integral<UNCVREF(It)> >::type>
481 typedef void type;
484 // strings
485 template<typename This, typename Cont, typename Size, typename A0, typename A1>
486 struct result<This(Cont, Size, A0, A1),
487 typename enable_if<is_integral<UNCVREF(Size)> >::type>
489 typedef UNREF(Cont) &type;
492 /// operator()
494 template<typename Cont, typename A0>
495 typename result<insert(Cont &, A0 const &)>::type
496 operator()(Cont &cont, A0 const &a0) const
498 return cont.insert(a0);
501 /// \overload
503 template<typename Cont, typename A0, typename A1>
504 typename result<insert(Cont &, A0 const &, A1 const &)>::type
505 operator()(Cont &cont, A0 const &a0, A1 const &a1) const
507 return cont.insert(a0, a1);
510 /// \overload
512 template<typename Cont, typename A0, typename A1, typename A2>
513 typename result<insert(Cont &, A0 const &, A1 const &, A2 const &)>::type
514 operator()(Cont &cont, A0 const &a0, A1 const &a1, A2 const &a2) const
516 return cont.insert(a0, a1, a2);
520 struct make_pair
522 template<typename Sig>
523 struct result {};
525 template<typename This, typename First, typename Second>
526 struct result<This(First, Second)>
528 typedef std::pair<UNCVREF(First), UNCVREF(Second)> type;
531 template<typename First, typename Second>
532 std::pair<First, Second> operator()(First const &first, Second const &second) const
534 return std::make_pair(first, second);
538 template<typename T>
539 struct as
541 typedef T result_type;
543 template<typename Value>
544 T operator()(Value const &val) const
546 return lexical_cast<T>(val);
550 template<typename T>
551 struct static_cast_
553 typedef T result_type;
555 template<typename Value>
556 T operator()(Value const &val) const
558 return static_cast<T>(val);
562 template<typename T>
563 struct dynamic_cast_
565 typedef T result_type;
567 template<typename Value>
568 T operator()(Value const &val) const
570 return dynamic_cast<T>(val);
574 template<typename T>
575 struct const_cast_
577 typedef T result_type;
579 template<typename Value>
580 T operator()(Value const &val) const
582 return const_cast<T>(val);
586 template<typename T>
587 struct construct
589 typedef T result_type;
591 T operator()() const
593 return T();
596 template<typename A0>
597 T operator()(A0 const &a0) const
599 return T(a0);
602 template<typename A0, typename A1>
603 T operator()(A0 const &a0, A1 const &a1) const
605 return T(a0, a1);
608 template<typename A0, typename A1, typename A2>
609 T operator()(A0 const &a0, A1 const &a1, A2 const &a2) const
611 return T(a0, a1, a2);
615 template<typename Except>
616 struct throw_
618 typedef void result_type;
620 void operator()() const
622 BOOST_THROW_EXCEPTION(Except());
625 template<typename A0>
626 void operator()(A0 const &a0) const
628 BOOST_THROW_EXCEPTION(Except(a0));
631 template<typename A0, typename A1>
632 void operator()(A0 const &a0, A1 const &a1) const
634 BOOST_THROW_EXCEPTION(Except(a0, a1));
637 template<typename A0, typename A1, typename A2>
638 void operator()(A0 const &a0, A1 const &a1, A2 const &a2) const
640 BOOST_THROW_EXCEPTION(Except(a0, a1, a2));
645 template<typename Fun>
646 struct function
648 typedef typename proto::terminal<Fun>::type type;
651 function<op::push>::type const push = {{}};
652 function<op::push_back>::type const push_back = {{}};
653 function<op::push_front>::type const push_front = {{}};
654 function<op::pop>::type const pop = {{}};
655 function<op::pop_back>::type const pop_back = {{}};
656 function<op::pop_front>::type const pop_front = {{}};
657 function<op::top>::type const top = {{}};
658 function<op::back>::type const back = {{}};
659 function<op::front>::type const front = {{}};
660 function<op::first>::type const first = {{}};
661 function<op::second>::type const second = {{}};
662 function<op::matched>::type const matched = {{}};
663 function<op::length>::type const length = {{}};
664 function<op::str>::type const str = {{}};
665 function<op::insert>::type const insert = {{}};
666 function<op::make_pair>::type const make_pair = {{}};
668 template<typename T>
669 struct value
670 : proto::extends<typename proto::terminal<T>::type, value<T> >
672 typedef proto::extends<typename proto::terminal<T>::type, value<T> > base_type;
674 value()
675 : base_type()
678 explicit value(T const &t)
679 : base_type(base_type::proto_base_expr::make(t))
682 using base_type::operator =;
684 T &get()
686 return proto::value(*this);
689 T const &get() const
691 return proto::value(*this);
695 template<typename T>
696 struct reference
697 : proto::extends<typename proto::terminal<reference_wrapper<T> >::type, reference<T> >
699 typedef proto::extends<typename proto::terminal<reference_wrapper<T> >::type, reference<T> > base_type;
701 explicit reference(T &t)
702 : base_type(base_type::proto_base_expr::make(boost::ref(t)))
705 using base_type::operator =;
707 T &get() const
709 return proto::value(*this).get();
713 template<typename T>
714 struct local
715 : detail::value_wrapper<T>
716 , proto::terminal<reference_wrapper<T> >::type
718 typedef typename proto::terminal<reference_wrapper<T> >::type base_type;
720 local()
721 : detail::value_wrapper<T>()
722 , base_type(base_type::make(boost::ref(detail::value_wrapper<T>::value)))
725 explicit local(T const &t)
726 : detail::value_wrapper<T>(t)
727 , base_type(base_type::make(boost::ref(detail::value_wrapper<T>::value)))
730 using base_type::operator =;
732 T &get()
734 return proto::value(*this);
737 T const &get() const
739 return proto::value(*this);
742 private:
743 local(local const &);
746 /// as (a.k.a., lexical_cast)
748 BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
750 , as
751 , boost::proto::default_domain
752 , (boost::proto::tag::function)
753 , ((op::as)(typename))
756 /// static_cast_
758 BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
760 , static_cast_
761 , boost::proto::default_domain
762 , (boost::proto::tag::function)
763 , ((op::static_cast_)(typename))
766 /// dynamic_cast_
768 BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
770 , dynamic_cast_
771 , boost::proto::default_domain
772 , (boost::proto::tag::function)
773 , ((op::dynamic_cast_)(typename))
776 /// const_cast_
778 BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
780 , const_cast_
781 , boost::proto::default_domain
782 , (boost::proto::tag::function)
783 , ((op::const_cast_)(typename))
786 /// val()
788 template<typename T>
789 value<T> const val(T const &t)
791 return value<T>(t);
794 /// ref()
796 template<typename T>
797 reference<T> const ref(T &t)
799 return reference<T>(t);
802 /// cref()
804 template<typename T>
805 reference<T const> const cref(T const &t)
807 return reference<T const>(t);
810 /// check(), for testing custom assertions
812 proto::terminal<detail::check_tag>::type const check = {{}};
814 /// let(), for binding references to non-local variables
816 detail::let_<proto::terminal<detail::let_tag>::type> const let = {{{}}};
818 /// placeholder<T>, for defining a placeholder to stand in fo
819 /// a variable of type T in a semantic action.
821 template<typename T, int I, typename Dummy>
822 struct placeholder
824 typedef placeholder<T, I, Dummy> this_type;
825 typedef typename proto::terminal<detail::action_arg<T, mpl::int_<I> > >::type action_arg_type;
827 BOOST_PROTO_EXTENDS(action_arg_type, this_type, proto::default_domain)
830 /// Usage: construct\<Type\>(arg1, arg2)
832 BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE(
833 construct
834 , boost::proto::default_domain
835 , (boost::proto::tag::function)
836 , ((op::construct)(typename))
839 /// Usage: throw_\<Exception\>(arg1, arg2)
841 BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE(
842 throw_
843 , boost::proto::default_domain
844 , (boost::proto::tag::function)
845 , ((op::throw_)(typename))
848 namespace detail
850 inline void ignore_unused_regex_actions()
852 ignore_unused(xpressive::push);
853 ignore_unused(xpressive::push_back);
854 ignore_unused(xpressive::push_front);
855 ignore_unused(xpressive::pop);
856 ignore_unused(xpressive::pop_back);
857 ignore_unused(xpressive::pop_front);
858 ignore_unused(xpressive::top);
859 ignore_unused(xpressive::back);
860 ignore_unused(xpressive::front);
861 ignore_unused(xpressive::first);
862 ignore_unused(xpressive::second);
863 ignore_unused(xpressive::matched);
864 ignore_unused(xpressive::length);
865 ignore_unused(xpressive::str);
866 ignore_unused(xpressive::insert);
867 ignore_unused(xpressive::make_pair);
868 ignore_unused(xpressive::check);
869 ignore_unused(xpressive::let);
875 #undef UNREF
876 #undef UNCVREF
878 #if BOOST_MSVC
879 #pragma warning(pop)
880 #endif
882 #endif // BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007