Ticket #4425: action_dispatch.hpp

File action_dispatch.hpp, 3.6 KB (added by anonymous, 12 years ago)
Line 
1/*=============================================================================
2 Copyright (c) 2001-2010 Joel de Guzman
3 Copyright (c) 2001-2010 Hartmut Kaiser
4 http://spirit.sourceforge.net/
5
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8=============================================================================*/
9#if !defined(BOOST_SPIRIT_ACTION_DISPATCH_APRIL_18_2008_0720AM)
10#define BOOST_SPIRIT_ACTION_DISPATCH_APRIL_18_2008_0720AM
11
12#if defined(_MSC_VER)
13#pragma once
14#endif
15
16#include <boost/spirit/home/phoenix/core/actor.hpp>
17#include <boost/spirit/home/support/attributes.hpp>
18
19namespace boost { namespace spirit { namespace traits
20{
21 template <typename Component>
22 struct action_dispatch
23 {
24 // general handler for everything not explicitly specialized below
25 template <typename F, typename Attribute, typename Context>
26 bool operator()(F const& f, Attribute& attr, Context& context)
27 {
28 bool pass = true;
29 f(attr, context, pass);
30 return pass;
31 }
32
33 // handler for phoenix actors
34
35 // If the component this action has to be invoked for is a tuple, we
36 // wrap any non-fusion tuple into a fusion tuple (done by pass_attribute)
37 // and pass through any fusion tuple.
38 template <typename Eval, typename Attribute, typename Context>
39 bool operator()(phoenix::actor<Eval> const& f
40 , Attribute& attr, Context& context)
41 {
42 bool pass = true;
43 typename pass_attribute<Component, Attribute>::type attr_wrap(attr);
44
45 typedef typename remove_reference<
46 typename Eval::template result<
47 phoenix::basic_environment<
48 typename remove_reference<Attribute>::type,
49 typename remove_reference<Context>::type,
50 typename remove_reference<bool>::type
51 >
52 >::type
53 >::type return_type;
54
55 return_type* ret = 0;
56
57 return call(f, attr_wrap, context, pass, ret);
58 }
59
60 template<typename Eval, typename Attribute, typename Context, typename Return>
61 inline bool call(phoenix::actor<Eval> const& f
62 , Attribute& attr, Context& context, bool& pass, Return)
63 const
64 {
65 f(attr, context, pass);
66 return pass;
67 }
68
69 template<typename Eval, typename Attribute, typename Context>
70 inline bool call(phoenix::actor<Eval> const& f
71 , Attribute& attr, Context& context, bool& pass, bool*)
72 const
73 {
74 bool ret = f(attr, context, pass);
75 return pass = pass && ret;
76 }
77
78
79 // specializations for plain function pointers taking different number of
80 // arguments
81 template <typename RT, typename A0, typename A1, typename A2
82 , typename Attribute, typename Context>
83 bool operator()(RT(*f)(A0, A1, A2), Attribute& attr, Context& context)
84 {
85 bool pass = true;
86 f(attr, context, pass);
87 return pass;
88 }
89
90 template <typename RT, typename A0, typename A1
91 , typename Attribute, typename Context>
92 bool operator()(RT(*f)(A0, A1), Attribute& attr, Context& context)
93 {
94 f(attr, context);
95 return true;
96 }
97
98 template <typename RT, typename A0, typename Attribute, typename Context>
99 bool operator()(RT(*f)(A0), Attribute& attr, Context&)
100 {
101 f(attr);
102 return true;
103 }
104
105 template <typename RT, typename Attribute, typename Context>
106 bool operator()(RT(*f)(), Attribute&, Context&)
107 {
108 f();
109 return true;
110 }
111 };
112
113}}}
114
115#endif