1 ///////////////////////////////////////////////////////////////////////////////
2 // as_modifier.hpp
3 //
4 //  Copyright 2008 Eric Niebler. Distributed under the Boost
5 //  Software License, Version 1.0. (See accompanying file
6 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 
8 #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_MODIFIER_HPP_EAN_04_05_2007
9 #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_MODIFIER_HPP_EAN_04_05_2007
10 
11 // MS compatible compilers support #pragma once
12 #if defined(_MSC_VER)
13 # pragma once
14 #endif
15 
16 #include <boost/mpl/sizeof.hpp>
17 #include <boost/xpressive/detail/detail_fwd.hpp>
18 #include <boost/xpressive/detail/static/static.hpp>
19 #include <boost/proto/core.hpp>
20 
21 #define UNCV(x) typename remove_const<x>::type
22 #define UNREF(x) typename remove_reference<x>::type
23 #define UNCVREF(x) UNCV(UNREF(x))
24 
25 namespace boost { namespace xpressive { namespace detail
26 {
27     ///////////////////////////////////////////////////////////////////////////////
28     // regex operator tags
29     struct modifier_tag
30     {};
31 
32 }}}
33 
34 namespace boost { namespace xpressive { namespace grammar_detail
35 {
36 
37     ///////////////////////////////////////////////////////////////////////////////
38     // as_modifier
39     template<typename Grammar, typename Callable = proto::callable>
40     struct as_modifier : proto::transform<as_modifier<Grammar, Callable> >
41     {
42         template<typename Expr, typename State, typename Data>
43         struct impl : proto::transform_impl<Expr, State, Data>
44         {
45             typedef
46                 typename proto::result_of::value<
47                     typename proto::result_of::left<typename impl::expr>::type
48                 >::type
49             modifier_type;
50 
51             typedef
52                 typename modifier_type::template apply<typename impl::data>::type
53             visitor_type;
54 
55             typedef
56                 typename proto::result_of::right<Expr>::type
57             expr_type;
58 
59             typedef
60                 typename Grammar::template impl<expr_type, State, visitor_type &>::result_type
61             result_type;
62 
operator ()boost::xpressive::grammar_detail::as_modifier::impl63             result_type operator ()(
64                 typename impl::expr_param expr
65               , typename impl::state_param state
66               , typename impl::data_param data
67             ) const
68             {
69                 visitor_type new_visitor(proto::value(proto::left(expr)).call(data));
70                 return typename Grammar::template impl<expr_type, State, visitor_type &>()(
71                     proto::right(expr)
72                   , state
73                   , new_visitor
74                 );
75             }
76         };
77     };
78 
79 }}}
80 
81 #undef UNCV
82 #undef UNREF
83 #undef UNCVREF
84 
85 #endif
86