]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/test/x3/rule3.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / spirit / test / x3 / rule3.cpp
1 /*=============================================================================
2 Copyright (c) 2001-2012 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 #include <boost/detail/lightweight_test.hpp>
9 #include <boost/spirit/home/x3.hpp>
10 #include <boost/fusion/include/adapt_struct.hpp>
11 #include <boost/fusion/include/std_pair.hpp>
12
13 #include <boost/variant.hpp>
14 #include <string>
15 #include <vector>
16 #include <cstring>
17 #include <iostream>
18 #include "test.hpp"
19
20 using boost::spirit::x3::_val;
21 namespace x3 = boost::spirit::x3;
22
23 struct f
24 {
25 template <typename Context>
26 void operator()(Context const& ctx) const
27 {
28 _val(ctx) += _attr(ctx);
29 }
30 };
31
32
33 struct stationary : boost::noncopyable
34 {
35 explicit stationary(int i) : val{i} {}
36 stationary& operator=(int i) { val = i; return *this; }
37
38 int val;
39 };
40
41
42 namespace check_stationary {
43
44 boost::spirit::x3::rule<class a_r, stationary> const a;
45 boost::spirit::x3::rule<class b_r, stationary> const b;
46
47 auto const a_def = '{' >> boost::spirit::x3::int_ >> '}';
48 auto const b_def = a;
49
50 BOOST_SPIRIT_DEFINE(a, b)
51
52 }
53
54 namespace check_recursive {
55
56 using node_t = boost::make_recursive_variant<
57 int,
58 std::vector<boost::recursive_variant_>
59 >::type;
60
61 boost::spirit::x3::rule<class grammar_r, node_t> const grammar;
62
63 auto const grammar_def = '[' >> grammar % ',' >> ']' | boost::spirit::x3::int_;
64
65 BOOST_SPIRIT_DEFINE(grammar)
66
67 }
68
69 struct recursive_tuple
70 {
71 int value;
72 std::vector<recursive_tuple> children;
73 };
74 BOOST_FUSION_ADAPT_STRUCT(recursive_tuple,
75 value, children)
76
77 // regression test for #461
78 namespace check_recursive_tuple {
79
80 x3::rule<class grammar_r, recursive_tuple> const grammar;
81 auto const grammar_def = x3::int_ >> ('{' >> grammar % ',' >> '}' | x3::eps);
82 BOOST_SPIRIT_DEFINE(grammar)
83
84 BOOST_SPIRIT_INSTANTIATE(decltype(grammar), char const*, x3::unused_type)
85
86 }
87
88
89 int main()
90 {
91 using spirit_test::test_attr;
92 using spirit_test::test;
93
94 using namespace boost::spirit::x3::ascii;
95 using boost::spirit::x3::rule;
96 using boost::spirit::x3::lit;
97 using boost::spirit::x3::eps;
98 using boost::spirit::x3::unused_type;
99
100
101 { // synth attribute value-init
102
103 std::string s;
104 typedef rule<class r, std::string> rule_type;
105
106 auto rdef = rule_type()
107 = alpha [f()]
108 ;
109
110 BOOST_TEST(test_attr("abcdef", +rdef, s));
111 BOOST_TEST(s == "abcdef");
112 }
113
114 { // synth attribute value-init
115
116 std::string s;
117 typedef rule<class r, std::string> rule_type;
118
119 auto rdef = rule_type() =
120 alpha /
121 [](auto& ctx)
122 {
123 _val(ctx) += _attr(ctx);
124 }
125 ;
126
127 BOOST_TEST(test_attr("abcdef", +rdef, s));
128 BOOST_TEST(s == "abcdef");
129 }
130
131 {
132 auto r = rule<class r, int>{} = eps[([] (auto& ctx) {
133 using boost::spirit::x3::_val;
134 static_assert(std::is_same<std::decay_t<decltype(_val(ctx))>, unused_type>::value,
135 "Attribute must not be synthesized");
136 })];
137 BOOST_TEST(test("", r));
138 }
139
140 { // ensure no unneeded synthesization, copying and moving occurred
141 stationary st { 0 };
142 BOOST_TEST(test_attr("{42}", check_stationary::b, st));
143 BOOST_TEST_EQ(st.val, 42);
144 }
145
146 {
147 using namespace check_recursive;
148 node_t v;
149 BOOST_TEST(test_attr("[4,2]", grammar, v));
150 BOOST_TEST((node_t{std::vector<node_t>{{4}, {2}}} == v));
151 }
152
153 return boost::report_errors();
154 }