• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2001-2015 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 #include <boost/detail/lightweight_test.hpp>
8 #include <boost/spirit/home/x3.hpp>
9 #include <cstring>
10 #include <functional>
11 
12 #include "test.hpp"
13 
14 
15 namespace x3 = boost::spirit::x3;
16 
17 int x = 0;
18 
19 auto fun1 =
20     [](auto& ctx)
__anon47df67060102(auto& ctx) 21     {
22         x += x3::_attr(ctx);
23     }
24 ;
25 
26 struct fun_action
27 {
28     template <typename Context>
operator ()fun_action29     void operator()(Context const& ctx) const
30     {
31         x += x3::_attr(ctx);
32     }
33 };
34 
35 auto fail =
36     [](auto& ctx)
__anon47df67060202(auto& ctx) 37     {
38         x3::_pass(ctx) = false;
39     }
40 ;
41 
42 struct setnext
43 {
setnextsetnext44     setnext(char& next) : next(next) {}
45 
46     template <typename Context>
operator ()setnext47     void operator()(Context const& ctx) const
48     {
49         next = x3::_attr(ctx);
50     }
51 
52     char& next;
53 };
54 
55 
56 struct stationary : boost::noncopyable
57 {
stationarystationary58     explicit stationary(int i) : val{i} {}
operator =stationary59     stationary& operator=(int i) { val = i; return *this; }
60 
61     int val;
62 };
63 
64 
main()65 int main()
66 {
67     using spirit_test::test;
68     using spirit_test::test_attr;
69 
70     using x3::int_;
71 
72     BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(x3::int_type{}[std::true_type{}]);
73 
74     {
75         char const *s1 = "{42}", *e1 = s1 + std::strlen(s1);
76         x3::parse(s1, e1, '{' >> int_[fun1] >> '}');
77     }
78 
79 
80     {
81         char const *s1 = "{42}", *e1 = s1 + std::strlen(s1);
82         x3::parse(s1, e1, '{' >> int_[fun_action()] >> '}');
83     }
84 
85     {
86         using namespace std::placeholders;
87         char const *s1 = "{42}", *e1 = s1 + std::strlen(s1);
88         x3::parse(s1, e1, '{' >> int_[std::bind(fun_action(), _1)] >> '}');
89     }
90 
91     BOOST_TEST(x == (42*3));
92 
93     {
94        std::string input("1234 6543");
95        char next = '\0';
96        BOOST_TEST(x3::phrase_parse(input.begin(), input.end(),
97           x3::int_[fail] | x3::digit[setnext(next)], x3::space));
98        BOOST_TEST(next == '1');
99     }
100 
101     { // ensure no unneeded synthesization, copying and moving occurred
102         auto p = '{' >> int_ >> '}';
103 
104         stationary st { 0 };
105         BOOST_TEST(test_attr("{42}", p[([]{})], st));
106         BOOST_TEST_EQ(st.val, 42);
107     }
108 
109     return boost::report_errors();
110 }
111