1 /*=============================================================================
2 Copyright (c) 2001-2011 Hartmut Kaiser
3 Copyright (c) 2001-2011 Joel de Guzman
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8
9 #include <boost/config/warning_disable.hpp>
10 #include <boost/detail/lightweight_test.hpp>
11
12 #include <boost/spirit/include/karma_string.hpp>
13 #include <boost/spirit/include/karma_numeric.hpp>
14 #include <boost/spirit/include/karma_directive.hpp>
15 #include <boost/spirit/include/karma_operator.hpp>
16 #include <boost/spirit/include/karma_phoenix_attributes.hpp>
17
18 #include <boost/spirit/include/phoenix_core.hpp>
19 #include <boost/spirit/include/phoenix_operator.hpp>
20
21 #include "test.hpp"
22
23 using namespace spirit_test;
24
25 ///////////////////////////////////////////////////////////////////////////////
26 // special bool output policy allowing to spell false as true backwards (eurt)
27 struct special_bool_policy : boost::spirit::karma::bool_policies<>
28 {
29 template <typename CharEncoding, typename Tag
30 , typename OutputIterator>
generate_falsespecial_bool_policy31 static bool generate_false(OutputIterator& sink, bool)
32 {
33 // we want to spell the names of true and false backwards
34 return boost::spirit::karma::string_inserter<CharEncoding, Tag>::
35 call(sink, "eurt");
36 }
37 };
38
39 ///////////////////////////////////////////////////////////////////////////////
40 // special policy allowing to use any type as a boolean
41 struct test_bool_data
42 {
test_bool_datatest_bool_data43 explicit test_bool_data(bool b) : b(b) {}
44
45 bool b;
46
47 // we need to provide (safe) convertibility to bool
48 private:
true_test_bool_data::dummy49 struct dummy { void true_() {} };
50 typedef void (dummy::*safe_bool)();
51
52 public:
operator safe_booltest_bool_data53 operator safe_bool () const { return b ? &dummy::true_ : 0; }
54 };
55
56 struct test_bool_policy : boost::spirit::karma::bool_policies<>
57 {
58 template <typename Inserter, typename OutputIterator, typename Policies>
59 static bool
calltest_bool_policy60 call (OutputIterator& sink, test_bool_data b, Policies const& p)
61 {
62 // call the predefined inserter to do the job
63 return Inserter::call_n(sink, bool(b), p);
64 }
65 };
66
67
68 ///////////////////////////////////////////////////////////////////////////////
main()69 int main()
70 {
71 using boost::spirit::karma::bool_;
72 using boost::spirit::karma::false_;
73 using boost::spirit::karma::true_;
74 using boost::spirit::karma::lit;
75 using boost::spirit::karma::lower;
76 using boost::spirit::karma::upper;
77
78 // testing plain bool
79 {
80 BOOST_TEST(test("false", bool_, false));
81 BOOST_TEST(test("true", bool_, true));
82 BOOST_TEST(test("false", false_, false));
83 BOOST_TEST(test("true", true_, true));
84 BOOST_TEST(test("false", bool_(false)));
85 BOOST_TEST(test("true", bool_(true)));
86 BOOST_TEST(test("false", bool_(false), false));
87 BOOST_TEST(test("true", bool_(true), true));
88 BOOST_TEST(!test("", bool_(false), true));
89 BOOST_TEST(!test("", bool_(true), false));
90 BOOST_TEST(test("false", lit(false)));
91 BOOST_TEST(test("true", lit(true)));
92 }
93
94 // test optional attributes
95 {
96 boost::optional<bool> optbool;
97
98 BOOST_TEST(!test("", bool_, optbool));
99 BOOST_TEST(test("", -bool_, optbool));
100 optbool = false;
101 BOOST_TEST(test("false", bool_, optbool));
102 BOOST_TEST(test("false", -bool_, optbool));
103 optbool = true;
104 BOOST_TEST(test("true", bool_, optbool));
105 BOOST_TEST(test("true", -bool_, optbool));
106 }
107
108 // we support Phoenix attributes only starting with V2.2
109 #if SPIRIT_VERSION >= 0x2020
110 // test Phoenix expression attributes (requires to include
111 // karma_phoenix_attributes.hpp)
112 {
113 namespace phoenix = boost::phoenix;
114
115 BOOST_TEST(test("true", bool_, phoenix::val(true)));
116
117 bool b = false;
118 BOOST_TEST(test("false", bool_, phoenix::ref(b)));
119 BOOST_TEST(test("true", bool_, !phoenix::ref(b)));
120 }
121 #endif
122
123 {
124 BOOST_TEST(test("false", lower[bool_], false));
125 BOOST_TEST(test("true", lower[bool_], true));
126 BOOST_TEST(test("false", lower[bool_(false)]));
127 BOOST_TEST(test("true", lower[bool_(true)]));
128 BOOST_TEST(test("false", lower[bool_(false)], false));
129 BOOST_TEST(test("true", lower[bool_(true)], true));
130 BOOST_TEST(!test("", lower[bool_(false)], true));
131 BOOST_TEST(!test("", lower[bool_(true)], false));
132 BOOST_TEST(test("false", lower[lit(false)]));
133 BOOST_TEST(test("true", lower[lit(true)]));
134 }
135
136 {
137 BOOST_TEST(test("FALSE", upper[bool_], false));
138 BOOST_TEST(test("TRUE", upper[bool_], true));
139 BOOST_TEST(test("FALSE", upper[bool_(false)]));
140 BOOST_TEST(test("TRUE", upper[bool_(true)]));
141 BOOST_TEST(test("FALSE", upper[bool_(false)], false));
142 BOOST_TEST(test("TRUE", upper[bool_(true)], true));
143 BOOST_TEST(!test("", upper[bool_(false)], true));
144 BOOST_TEST(!test("", upper[bool_(true)], false));
145 BOOST_TEST(test("FALSE", upper[lit(false)]));
146 BOOST_TEST(test("TRUE", upper[lit(true)]));
147 }
148
149 {
150 typedef boost::spirit::karma::bool_generator<bool, special_bool_policy>
151 backwards_bool_type;
152 backwards_bool_type const backwards_bool = backwards_bool_type();
153
154 BOOST_TEST(test("eurt", backwards_bool, false));
155 BOOST_TEST(test("true", backwards_bool, true));
156 BOOST_TEST(test("eurt", backwards_bool(false)));
157 BOOST_TEST(test("true", backwards_bool(true)));
158 BOOST_TEST(test("eurt", backwards_bool(false), false));
159 BOOST_TEST(test("true", backwards_bool(true), true));
160 BOOST_TEST(!test("", backwards_bool(false), true));
161 BOOST_TEST(!test("", backwards_bool(true), false));
162 }
163
164 {
165 typedef boost::spirit::karma::bool_generator<
166 test_bool_data, test_bool_policy> test_bool_type;
167 test_bool_type const test_bool = test_bool_type();
168
169 test_bool_data const test_false = test_bool_data(false);
170 test_bool_data const test_true = test_bool_data(true);
171
172 BOOST_TEST(test("false", test_bool, test_false));
173 BOOST_TEST(test("true", test_bool, test_true));
174 BOOST_TEST(test("false", test_bool(test_false)));
175 BOOST_TEST(test("true", test_bool(test_true)));
176 BOOST_TEST(test("false", test_bool(test_false), test_false));
177 BOOST_TEST(test("true", test_bool(test_true), test_true));
178 BOOST_TEST(!test("", test_bool(test_false), test_true));
179 BOOST_TEST(!test("", test_bool(test_true), test_false));
180 }
181
182 return boost::report_errors();
183 }
184
185