1 // Copyright (c) 2001-2011 Hartmut Kaiser 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #if !defined(BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM) 7 #define BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM 8 9 #include <cstring> 10 #include <string> 11 #include <iterator> 12 #include <iostream> 13 #include <iomanip> 14 #include <typeinfo> 15 16 #include <boost/foreach.hpp> 17 #include <boost/spirit/include/karma_generate.hpp> 18 #include <boost/spirit/include/karma_what.hpp> 19 20 namespace spirit_test 21 { 22 /////////////////////////////////////////////////////////////////////////// 23 struct display_type 24 { 25 template<typename T> operator ()spirit_test::display_type26 void operator()(T const &) const 27 { 28 std::cout << typeid(T).name() << std::endl; 29 } 30 31 template<typename T> printspirit_test::display_type32 static void print() 33 { 34 std::cout << typeid(T).name() << std::endl; 35 } 36 }; 37 38 display_type const display = {}; 39 40 /////////////////////////////////////////////////////////////////////////// 41 template <typename Char> 42 struct output_iterator 43 { 44 typedef std::basic_string<Char> string_type; 45 typedef std::back_insert_iterator<string_type> type; 46 }; 47 48 /////////////////////////////////////////////////////////////////////////// 49 template <typename Char, typename T> print_if_failed(char const * func,bool result,std::basic_string<Char> const & generated,T const & expected)50 void print_if_failed(char const* func, bool result 51 , std::basic_string<Char> const& generated, T const& expected) 52 { 53 if (!result) 54 std::cerr << "in " << func << ": result is false" << std::endl; 55 else if (generated != expected) 56 { 57 std::cerr << "in " << func << ": generated \""; 58 BOOST_FOREACH(typename boost::make_unsigned<Char>::type c, generated) { 59 if (c >= 32 && c < 127) 60 std::cerr << static_cast<char>(static_cast<unsigned char>(c)); 61 else 62 std::cerr << "\\x" << std::hex << +c; 63 } 64 std::cerr << "\"\n"; 65 } 66 } 67 68 /////////////////////////////////////////////////////////////////////////// 69 template <typename Char, typename T> print_binary_if_failed(char const * func,bool result,std::basic_string<Char> const & generated,T const & expected)70 void print_binary_if_failed(char const* func, bool result 71 , std::basic_string<Char> const& generated, T const& expected) 72 { 73 if (!result) 74 std::cerr << "in " << func << ": result is false" << std::endl; 75 else if (generated.size() != expected.size() || 76 std::memcmp(generated.c_str(), expected.c_str(), generated.size())) 77 { 78 std::cerr << "in " << func << ": generated \""; 79 BOOST_FOREACH(int c, generated) 80 std::cerr << "\\x" << std::hex << std::setfill('0') << std::setw(2) << c; 81 std::cerr << "\"" << std::endl; 82 } 83 } 84 85 /////////////////////////////////////////////////////////////////////////// 86 template <typename Char, typename Generator> test(Char const * expected,Generator const & g)87 inline bool test(Char const *expected, Generator const& g) 88 { 89 namespace karma = boost::spirit::karma; 90 typedef std::basic_string<Char> string_type; 91 92 // we don't care about the result of the "what" function. 93 // we only care that all generators have it: 94 karma::what(g); 95 96 string_type generated; 97 std::back_insert_iterator<string_type> outit(generated); 98 bool result = karma::generate(outit, g); 99 100 print_if_failed("test", result, generated, expected); 101 return result && generated == expected; 102 } 103 104 template <typename Char, typename Generator> test(std::basic_string<Char> const & expected,Generator const & g)105 inline bool test(std::basic_string<Char> const& expected, Generator const& g) 106 { 107 namespace karma = boost::spirit::karma; 108 typedef std::basic_string<Char> string_type; 109 110 // we don't care about the result of the "what" function. 111 // we only care that all generators have it: 112 karma::what(g); 113 114 string_type generated; 115 std::back_insert_iterator<string_type> outit(generated); 116 bool result = karma::generate(outit, g); 117 118 print_if_failed("test", result, generated, expected); 119 return result && generated == expected; 120 } 121 122 /////////////////////////////////////////////////////////////////////////// 123 template <typename Char, typename Generator, typename Attribute> test(Char const * expected,Generator const & g,Attribute const & attrib)124 inline bool test(Char const *expected, Generator const& g, 125 Attribute const &attrib) 126 { 127 namespace karma = boost::spirit::karma; 128 typedef std::basic_string<Char> string_type; 129 130 // we don't care about the result of the "what" function. 131 // we only care that all generators have it: 132 karma::what(g); 133 134 string_type generated; 135 std::back_insert_iterator<string_type> outit(generated); 136 bool result = karma::generate(outit, g, attrib); 137 138 print_if_failed("test", result, generated, expected); 139 return result && generated == expected; 140 } 141 142 template <typename Char, typename Generator, typename Attribute> test(std::basic_string<Char> const & expected,Generator const & g,Attribute const & attrib)143 inline bool test(std::basic_string<Char> const& expected, Generator const& g, 144 Attribute const &attrib) 145 { 146 namespace karma = boost::spirit::karma; 147 typedef std::basic_string<Char> string_type; 148 149 // we don't care about the result of the "what" function. 150 // we only care that all generators have it: 151 karma::what(g); 152 153 string_type generated; 154 std::back_insert_iterator<string_type> outit(generated); 155 bool result = karma::generate(outit, g, attrib); 156 157 print_if_failed("test", result, generated, expected); 158 return result && generated == expected; 159 } 160 161 /////////////////////////////////////////////////////////////////////////// 162 template <typename Char, typename Generator, typename Delimiter> test_delimited(Char const * expected,Generator const & g,Delimiter const & d)163 inline bool test_delimited(Char const *expected, Generator const& g, 164 Delimiter const& d) 165 { 166 namespace karma = boost::spirit::karma; 167 typedef std::basic_string<Char> string_type; 168 169 // we don't care about the result of the "what" function. 170 // we only care that all generators have it: 171 karma::what(g); 172 173 string_type generated; 174 std::back_insert_iterator<string_type> outit(generated); 175 bool result = karma::generate_delimited(outit, g, d); 176 177 print_if_failed("test_delimited", result, generated, expected); 178 return result && generated == expected; 179 } 180 181 template <typename Char, typename Generator, typename Delimiter> test_delimited(std::basic_string<Char> const & expected,Generator const & g,Delimiter const & d)182 inline bool test_delimited(std::basic_string<Char> const& expected, 183 Generator const& g, Delimiter const& d) 184 { 185 namespace karma = boost::spirit::karma; 186 typedef std::basic_string<Char> string_type; 187 188 // we don't care about the result of the "what" function. 189 // we only care that all generators have it: 190 karma::what(g); 191 192 string_type generated; 193 std::back_insert_iterator<string_type> outit(generated); 194 bool result = karma::generate_delimited(outit, g, d); 195 196 print_if_failed("test_delimited", result, generated, expected); 197 return result && generated == expected; 198 } 199 200 /////////////////////////////////////////////////////////////////////////// 201 template <typename Char, typename Generator, typename Attribute, 202 typename Delimiter> test_delimited(Char const * expected,Generator const & g,Attribute const & attrib,Delimiter const & d)203 inline bool test_delimited(Char const *expected, Generator const& g, 204 Attribute const &attrib, Delimiter const& d) 205 { 206 namespace karma = boost::spirit::karma; 207 typedef std::basic_string<Char> string_type; 208 209 // we don't care about the result of the "what" function. 210 // we only care that all generators have it: 211 karma::what(g); 212 213 string_type generated; 214 std::back_insert_iterator<string_type> outit(generated); 215 bool result = karma::generate_delimited(outit, g, d, attrib); 216 217 print_if_failed("test_delimited", result, generated, expected); 218 return result && generated == expected; 219 } 220 221 template <typename Char, typename Generator, typename Attribute, 222 typename Delimiter> test_delimited(std::basic_string<Char> const & expected,Generator const & g,Attribute const & attrib,Delimiter const & d)223 inline bool test_delimited(std::basic_string<Char> const& expected, 224 Generator const& g, Attribute const &attrib, Delimiter const& d) 225 { 226 namespace karma = boost::spirit::karma; 227 typedef std::basic_string<Char> string_type; 228 229 // we don't care about the result of the "what" function. 230 // we only care that all generators have it: 231 karma::what(g); 232 233 string_type generated; 234 std::back_insert_iterator<string_type> outit(generated); 235 bool result = karma::generate_delimited(outit, g, d, attrib); 236 237 print_if_failed("test_delimited", result, generated, expected); 238 return result && generated == expected; 239 } 240 241 /////////////////////////////////////////////////////////////////////////// 242 template <typename Generator> 243 inline bool binary_test(char const * expected,std::size_t size,Generator const & g)244 binary_test(char const *expected, std::size_t size, 245 Generator const& g) 246 { 247 namespace karma = boost::spirit::karma; 248 typedef std::basic_string<char> string_type; 249 250 // we don't care about the result of the "what" function. 251 // we only care that all generators have it: 252 karma::what(g); 253 254 string_type generated; 255 std::back_insert_iterator<string_type> outit(generated); 256 bool result = karma::generate(outit, g); 257 258 print_binary_if_failed("binary_test", result, generated 259 , std::string(expected, size)); 260 return result && generated.size() == size 261 && !std::memcmp(generated.c_str(), expected, size); 262 } 263 264 /////////////////////////////////////////////////////////////////////////// 265 template <typename Generator, typename Attribute> 266 inline bool binary_test(char const * expected,std::size_t size,Generator const & g,Attribute const & attrib)267 binary_test(char const *expected, std::size_t size, 268 Generator const& g, Attribute const &attrib) 269 { 270 namespace karma = boost::spirit::karma; 271 typedef std::basic_string<char> string_type; 272 273 // we don't care about the result of the "what" function. 274 // we only care that all generators have it: 275 karma::what(g); 276 277 string_type generated; 278 std::back_insert_iterator<string_type> outit(generated); 279 bool result = karma::generate(outit, g, attrib); 280 281 print_binary_if_failed("binary_test", result, generated 282 , std::string(expected, size)); 283 return result && generated.size() == size 284 && !std::memcmp(generated.c_str(), expected, size); 285 } 286 287 /////////////////////////////////////////////////////////////////////////// 288 template <typename Generator, typename Delimiter> 289 inline bool binary_test_delimited(char const * expected,std::size_t size,Generator const & g,Delimiter const & d)290 binary_test_delimited(char const *expected, std::size_t size, 291 Generator const& g, Delimiter const& d) 292 { 293 namespace karma = boost::spirit::karma; 294 typedef std::basic_string<char> string_type; 295 296 // we don't care about the result of the "what" function. 297 // we only care that all generators have it: 298 karma::what(g); 299 300 string_type generated; 301 std::back_insert_iterator<string_type> outit(generated); 302 bool result = karma::generate_delimited(outit, g, d); 303 304 print_binary_if_failed("binary_test_delimited", result, generated 305 , std::string(expected, size)); 306 return result && generated.size() == size 307 && !std::memcmp(generated.c_str(), expected, size); 308 } 309 310 /////////////////////////////////////////////////////////////////////////// 311 template <typename Generator, typename Attribute, typename Delimiter> 312 inline bool binary_test_delimited(char const * expected,std::size_t size,Generator const & g,Attribute const & attrib,Delimiter const & d)313 binary_test_delimited(char const *expected, std::size_t size, 314 Generator const& g, Attribute const &attrib, Delimiter const& d) 315 { 316 namespace karma = boost::spirit::karma; 317 typedef std::basic_string<char> string_type; 318 319 // we don't care about the result of the "what" function. 320 // we only care that all generators have it: 321 karma::what(g); 322 323 string_type generated; 324 std::back_insert_iterator<string_type> outit(generated); 325 bool result = karma::generate_delimited(outit, g, d, attrib); 326 327 print_binary_if_failed("binary_test_delimited", result, generated 328 , std::string(expected, size)); 329 return result && generated.size() == size 330 && !std::memcmp(generated.c_str(), expected, size); 331 } 332 333 } // namespace spirit_test 334 335 #endif // !BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM 336