1 ///////////////////////////////////////////////////////////////////////////////
2 /// \file regex_actions.hpp
3 /// Defines the syntax elements of xpressive's action expressions.
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)
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>
50 #define UNREF(x) typename remove_reference<x>::type
54 #define UNCVREF(x) typename remove_cv<typename remove_reference<x>::type>::type
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
63 namespace boost
{ namespace xpressive
68 template<typename T
, typename U
>
72 typedef typename add_reference
<T
>::type reference
;
74 reference
cast(void *pv
) const
76 return *static_cast<UNREF(T
) *>(pv
);
87 value_wrapper(T
const &t
)
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
114 // let(_a = b, _c = d)
116 proto::terminal
<let_tag
>
117 , proto::vararg
<proto::assign
<proto::_
, proto::_
> >
120 proto::_state
// no-op
121 , proto::vararg
<proto::call
<BindArg(proto::_data
, proto::_
)> >
127 : boost::proto::domain
<boost::proto::pod_generator
<let_
> >
130 template<typename Expr
>
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
> &>()(
147 template<typename BidiIter
>
148 struct replacement_context
149 : proto::callable_context
<replacement_context
<BidiIter
> const>
151 replacement_context(match_results
<BidiIter
> const &what
)
155 template<typename Sig
>
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 &)>
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];
187 T
&operator ()(proto::tag::terminal
, reference_wrapper
<T
> r
) const
192 match_results
<BidiIter
> const &what_
;
200 typedef void result_type
;
202 template<typename Sequence
, typename Value
>
203 void operator()(Sequence
&seq
, Value
const &val
) const
211 typedef void result_type
;
213 template<typename Sequence
, typename Value
>
214 void operator()(Sequence
&seq
, Value
const &val
) const
222 typedef void result_type
;
224 template<typename Sequence
, typename Value
>
225 void operator()(Sequence
&seq
, Value
const &val
) const
233 typedef void result_type
;
235 template<typename Sequence
>
236 void operator()(Sequence
&seq
) const
244 typedef void result_type
;
246 template<typename Sequence
>
247 void operator()(Sequence
&seq
) const
255 typedef void result_type
;
257 template<typename Sequence
>
258 void operator()(Sequence
&seq
) const
266 template<typename Sig
>
269 template<typename This
, typename Sequence
>
270 struct result
<This(Sequence
)>
272 typedef UNREF(Sequence
) sequence_type
;
275 is_const
<sequence_type
>
276 , typename
sequence_type::const_reference
277 , typename
sequence_type::reference
282 template<typename Sequence
>
283 typename result
<front(Sequence
&)>::type
operator()(Sequence
&seq
) const
291 template<typename Sig
>
294 template<typename This
, typename Sequence
>
295 struct result
<This(Sequence
)>
297 typedef UNREF(Sequence
) sequence_type
;
300 is_const
<sequence_type
>
301 , typename
sequence_type::const_reference
302 , typename
sequence_type::reference
307 template<typename Sequence
>
308 typename result
<back(Sequence
&)>::type
operator()(Sequence
&seq
) const
316 template<typename Sig
>
319 template<typename This
, typename Sequence
>
320 struct result
<This(Sequence
)>
322 typedef UNREF(Sequence
) sequence_type
;
325 is_const
<sequence_type
>
326 , typename
sequence_type::value_type
const &
327 , typename
sequence_type::value_type
&
332 template<typename Sequence
>
333 typename result
<top(Sequence
&)>::type
operator()(Sequence
&seq
) const
341 template<typename Sig
>
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
359 template<typename Sig
>
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
377 typedef bool result_type
;
379 template<typename Sub
>
380 bool operator()(Sub
const &sub
) const
388 template<typename Sig
>
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
406 template<typename Sig
>
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
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.
427 template<typename Sig
, typename EnableIf
= void>
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_
)))));
447 , typename
cont_type::iterator
448 , std::pair
<typename
cont_type::iterator
, bool>
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
;
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
;
470 template<typename This
, typename Cont
, typename It
>
471 struct result
<This(Cont
, It
, It
), void>
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
>
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
;
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
);
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
);
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
);
522 template<typename Sig
>
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
);
541 typedef T result_type
;
543 template<typename Value
>
544 T
operator()(Value
const &val
) const
546 return lexical_cast
<T
>(val
);
553 typedef T result_type
;
555 template<typename Value
>
556 T
operator()(Value
const &val
) const
558 return static_cast<T
>(val
);
565 typedef T result_type
;
567 template<typename Value
>
568 T
operator()(Value
const &val
) const
570 return dynamic_cast<T
>(val
);
577 typedef T result_type
;
579 template<typename Value
>
580 T
operator()(Value
const &val
) const
582 return const_cast<T
>(val
);
589 typedef T result_type
;
596 template<typename A0
>
597 T
operator()(A0
const &a0
) const
602 template<typename A0
, typename A1
>
603 T
operator()(A0
const &a0
, A1
const &a1
) const
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
>
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
>
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
= {{}};
670 : proto::extends
<typename
proto::terminal
<T
>::type
, value
<T
> >
672 typedef proto::extends
<typename
proto::terminal
<T
>::type
, value
<T
> > base_type
;
678 explicit value(T
const &t
)
679 : base_type(base_type::proto_base_expr::make(t
))
682 using base_type::operator =;
686 return proto::value(*this);
691 return proto::value(*this);
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 =;
709 return proto::value(*this).get();
715 : detail::value_wrapper
<T
>
716 , proto::terminal
<reference_wrapper
<T
> >::type
718 typedef typename
proto::terminal
<reference_wrapper
<T
> >::type base_type
;
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 =;
734 return proto::value(*this);
739 return proto::value(*this);
743 local(local
const &);
746 /// as (a.k.a., lexical_cast)
748 BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
751 , boost::proto::default_domain
752 , (boost::proto::tag::function
)
753 , ((op::as
)(typename
))
758 BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
761 , boost::proto::default_domain
762 , (boost::proto::tag::function
)
763 , ((op::static_cast_
)(typename
))
768 BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
771 , boost::proto::default_domain
772 , (boost::proto::tag::function
)
773 , ((op::dynamic_cast_
)(typename
))
778 BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
781 , boost::proto::default_domain
782 , (boost::proto::tag::function
)
783 , ((op::const_cast_
)(typename
))
789 value
<T
> const val(T
const &t
)
797 reference
<T
> const ref(T
&t
)
799 return reference
<T
>(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
>
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(
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(
843 , boost::proto::default_domain
844 , (boost::proto::tag::function
)
845 , ((op::throw_
)(typename
))
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
);
882 #endif // BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007