1/*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6=============================================================================*/
7
8#if defined(_MSC_VER)
9# pragma warning(disable: 4180) // qualifier applied to function type
10 // has no meaning; ignored
11#endif
12
13#include <boost/spirit/include/qi_action.hpp>
14
15#include <boost/detail/workaround.hpp>
16#include <boost/spirit/include/qi_operator.hpp>
17#include <boost/spirit/include/qi_numeric.hpp>
18#include <boost/spirit/include/qi_char.hpp>
19#include <boost/spirit/include/qi_parse.hpp>
20
21#include <boost/core/lightweight_test.hpp>
22#include <boost/lambda/lambda.hpp>
23#include <boost/bind/bind.hpp>
24#include <cstring>
25
26#ifdef _MSC_VER
27// bogus https://developercommunity.visualstudio.com/t/buggy-warning-c4709/471956
28# pragma warning(disable: 4709) // comma operator within array index expression
29#endif
30
31int x = 0;
32
33void fun1(int const& i)
34{
35 x += i;
36}
37
38void fun2(int i)
39{
40 x += i;
41}
42using boost::spirit::unused_type;
43
44struct fun_action
45{
46 void operator()(int const& i, unused_type, unused_type) const
47 {
48 x += i;
49 }
50};
51
52void fail (int, boost::spirit::unused_type, bool& pass)
53{
54 pass = false;
55}
56
57struct setnext
58{
59 setnext(char& next) : next(next) {}
60
61 void operator()(char c, unused_type, unused_type) const
62 {
63 next = c;
64 }
65
66 char& next;
67};
68
69int main()
70{
71 namespace qi = boost::spirit::qi;
72 using boost::spirit::int_;
73
74 {
75 char const *s1 = "{42}", *e1 = s1 + std::strlen(s: s1);
76 qi::parse(first&: s1, last: e1, expr: '{' >> int_[&fun1] >> '}');
77 }
78
79 {
80 char const *s1 = "{42}", *e1 = s1 + std::strlen(s: s1);
81 qi::parse(first&: s1, last: e1, expr: '{' >> int_[&fun2] >> '}');
82 }
83
84#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
85 {
86 char const *s1 = "{42}", *e1 = s1 + std::strlen(s: s1);
87 qi::parse(first&: s1, last: e1, expr: '{' >> int_[fun2] >> '}');
88 }
89#else
90 x += 42; // compensate for missing test case
91#endif
92
93 {
94 char const *s1 = "{42}", *e1 = s1 + std::strlen(s: s1);
95 qi::parse(first&: s1, last: e1, expr: '{' >> int_[fun_action()] >> '}');
96 }
97
98 {
99 using boost::placeholders::_1;
100 char const *s1 = "{42}", *e1 = s1 + std::strlen(s: s1);
101 qi::parse(first&: s1, last: e1, expr: '{' >> int_[boost::bind(f: &fun1, a1: _1)] >> '}');
102 }
103
104 {
105 namespace lambda = boost::lambda;
106 char const *s1 = "{42}", *e1 = s1 + std::strlen(s: s1);
107 qi::parse(first&: s1, last: e1, expr: '{' >> int_[lambda::var(t&: x) += lambda::_1] >> '}');
108 }
109 BOOST_TEST(x == (42*6));
110
111 {
112 std::string input("1234 6543");
113 char next = '\0';
114 BOOST_TEST(qi::phrase_parse(input.begin(), input.end(),
115 qi::int_[fail] | qi::digit[setnext(next)] , qi::space));
116 BOOST_TEST(next == '1');
117 }
118
119 return boost::report_errors();
120}
121
122
123
124
125

source code of boost/libs/spirit/test/qi/actions.cpp