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 std::cerr << "in " << func << ": generated \"" 57 << std::string(generated.begin(), generated.end()) 58 << "\"" << std::endl; 59 } 60 61 /////////////////////////////////////////////////////////////////////////// 62 template <typename Char, typename T> print_binary_if_failed(char const * func,bool result,std::basic_string<Char> const & generated,T const & expected)63 void print_binary_if_failed(char const* func, bool result 64 , std::basic_string<Char> const& generated, T const& expected) 65 { 66 if (!result) 67 std::cerr << "in " << func << ": result is false" << std::endl; 68 else if (generated.size() != expected.size() || 69 std::memcmp(generated.c_str(), expected.c_str(), generated.size())) 70 { 71 std::cerr << "in " << func << ": generated \""; 72 BOOST_FOREACH(int c, generated) 73 std::cerr << "\\x" << std::hex << std::setfill('0') << std::setw(2) << c; 74 std::cerr << "\"" << std::endl; 75 } 76 } 77 78 /////////////////////////////////////////////////////////////////////////// 79 template <typename Char, typename Generator> test(Char const * expected,Generator const & g)80 inline bool test(Char const *expected, Generator const& g) 81 { 82 namespace karma = boost::spirit::karma; 83 typedef std::basic_string<Char> string_type; 84 85 // we don't care about the result of the "what" function. 86 // we only care that all generators have it: 87 karma::what(g); 88 89 string_type generated; 90 std::back_insert_iterator<string_type> outit(generated); 91 bool result = karma::generate(outit, g); 92 93 print_if_failed("test", result, generated, expected); 94 return result && generated == expected; 95 } 96 97 template <typename Char, typename Generator> test(std::basic_string<Char> const & expected,Generator const & g)98 inline bool test(std::basic_string<Char> const& expected, Generator const& g) 99 { 100 namespace karma = boost::spirit::karma; 101 typedef std::basic_string<Char> string_type; 102 103 // we don't care about the result of the "what" function. 104 // we only care that all generators have it: 105 karma::what(g); 106 107 string_type generated; 108 std::back_insert_iterator<string_type> outit(generated); 109 bool result = karma::generate(outit, g); 110 111 print_if_failed("test", result, generated, expected); 112 return result && generated == expected; 113 } 114 115 /////////////////////////////////////////////////////////////////////////// 116 template <typename Char, typename Generator, typename Attribute> test(Char const * expected,Generator const & g,Attribute const & attrib)117 inline bool test(Char const *expected, Generator const& g, 118 Attribute const &attrib) 119 { 120 namespace karma = boost::spirit::karma; 121 typedef std::basic_string<Char> string_type; 122 123 // we don't care about the result of the "what" function. 124 // we only care that all generators have it: 125 karma::what(g); 126 127 string_type generated; 128 std::back_insert_iterator<string_type> outit(generated); 129 bool result = karma::generate(outit, g, attrib); 130 131 print_if_failed("test", result, generated, expected); 132 return result && generated == expected; 133 } 134 135 template <typename Char, typename Generator, typename Attribute> test(std::basic_string<Char> const & expected,Generator const & g,Attribute const & attrib)136 inline bool test(std::basic_string<Char> const& expected, Generator const& g, 137 Attribute const &attrib) 138 { 139 namespace karma = boost::spirit::karma; 140 typedef std::basic_string<Char> string_type; 141 142 // we don't care about the result of the "what" function. 143 // we only care that all generators have it: 144 karma::what(g); 145 146 string_type generated; 147 std::back_insert_iterator<string_type> outit(generated); 148 bool result = karma::generate(outit, g, attrib); 149 150 print_if_failed("test", result, generated, expected); 151 return result && generated == expected; 152 } 153 154 /////////////////////////////////////////////////////////////////////////// 155 template <typename Char, typename Generator, typename Delimiter> test_delimited(Char const * expected,Generator const & g,Delimiter const & d)156 inline bool test_delimited(Char const *expected, Generator const& g, 157 Delimiter const& d) 158 { 159 namespace karma = boost::spirit::karma; 160 typedef std::basic_string<Char> string_type; 161 162 // we don't care about the result of the "what" function. 163 // we only care that all generators have it: 164 karma::what(g); 165 166 string_type generated; 167 std::back_insert_iterator<string_type> outit(generated); 168 bool result = karma::generate_delimited(outit, g, d); 169 170 print_if_failed("test_delimited", result, generated, expected); 171 return result && generated == expected; 172 } 173 174 template <typename Char, typename Generator, typename Delimiter> test_delimited(std::basic_string<Char> const & expected,Generator const & g,Delimiter const & d)175 inline bool test_delimited(std::basic_string<Char> const& expected, 176 Generator const& g, Delimiter const& d) 177 { 178 namespace karma = boost::spirit::karma; 179 typedef std::basic_string<Char> string_type; 180 181 // we don't care about the result of the "what" function. 182 // we only care that all generators have it: 183 karma::what(g); 184 185 string_type generated; 186 std::back_insert_iterator<string_type> outit(generated); 187 bool result = karma::generate_delimited(outit, g, d); 188 189 print_if_failed("test_delimited", result, generated, expected); 190 return result && generated == expected; 191 } 192 193 /////////////////////////////////////////////////////////////////////////// 194 template <typename Char, typename Generator, typename Attribute, 195 typename Delimiter> test_delimited(Char const * expected,Generator const & g,Attribute const & attrib,Delimiter const & d)196 inline bool test_delimited(Char const *expected, Generator const& g, 197 Attribute const &attrib, Delimiter const& d) 198 { 199 namespace karma = boost::spirit::karma; 200 typedef std::basic_string<Char> string_type; 201 202 // we don't care about the result of the "what" function. 203 // we only care that all generators have it: 204 karma::what(g); 205 206 string_type generated; 207 std::back_insert_iterator<string_type> outit(generated); 208 bool result = karma::generate_delimited(outit, g, d, attrib); 209 210 print_if_failed("test_delimited", result, generated, expected); 211 return result && generated == expected; 212 } 213 214 template <typename Char, typename Generator, typename Attribute, 215 typename Delimiter> test_delimited(std::basic_string<Char> const & expected,Generator const & g,Attribute const & attrib,Delimiter const & d)216 inline bool test_delimited(std::basic_string<Char> const& expected, 217 Generator const& g, Attribute const &attrib, Delimiter const& d) 218 { 219 namespace karma = boost::spirit::karma; 220 typedef std::basic_string<Char> string_type; 221 222 // we don't care about the result of the "what" function. 223 // we only care that all generators have it: 224 karma::what(g); 225 226 string_type generated; 227 std::back_insert_iterator<string_type> outit(generated); 228 bool result = karma::generate_delimited(outit, g, d, attrib); 229 230 print_if_failed("test_delimited", result, generated, expected); 231 return result && generated == expected; 232 } 233 234 /////////////////////////////////////////////////////////////////////////// 235 template <typename Generator> 236 inline bool binary_test(char const * expected,std::size_t size,Generator const & g)237 binary_test(char const *expected, std::size_t size, 238 Generator const& g) 239 { 240 namespace karma = boost::spirit::karma; 241 typedef std::basic_string<char> string_type; 242 243 // we don't care about the result of the "what" function. 244 // we only care that all generators have it: 245 karma::what(g); 246 247 string_type generated; 248 std::back_insert_iterator<string_type> outit(generated); 249 bool result = karma::generate(outit, g); 250 251 print_binary_if_failed("binary_test", result, generated 252 , std::string(expected, size)); 253 return result && generated.size() == size 254 && !std::memcmp(generated.c_str(), expected, size); 255 } 256 257 /////////////////////////////////////////////////////////////////////////// 258 template <typename Generator, typename Attribute> 259 inline bool binary_test(char const * expected,std::size_t size,Generator const & g,Attribute const & attrib)260 binary_test(char const *expected, std::size_t size, 261 Generator const& g, Attribute const &attrib) 262 { 263 namespace karma = boost::spirit::karma; 264 typedef std::basic_string<char> string_type; 265 266 // we don't care about the result of the "what" function. 267 // we only care that all generators have it: 268 karma::what(g); 269 270 string_type generated; 271 std::back_insert_iterator<string_type> outit(generated); 272 bool result = karma::generate(outit, g, attrib); 273 274 print_binary_if_failed("binary_test", result, generated 275 , std::string(expected, size)); 276 return result && generated.size() == size 277 && !std::memcmp(generated.c_str(), expected, size); 278 } 279 280 /////////////////////////////////////////////////////////////////////////// 281 template <typename Generator, typename Delimiter> 282 inline bool binary_test_delimited(char const * expected,std::size_t size,Generator const & g,Delimiter const & d)283 binary_test_delimited(char const *expected, std::size_t size, 284 Generator const& g, Delimiter const& d) 285 { 286 namespace karma = boost::spirit::karma; 287 typedef std::basic_string<char> string_type; 288 289 // we don't care about the result of the "what" function. 290 // we only care that all generators have it: 291 karma::what(g); 292 293 string_type generated; 294 std::back_insert_iterator<string_type> outit(generated); 295 bool result = karma::generate_delimited(outit, g, d); 296 297 print_binary_if_failed("binary_test_delimited", result, generated 298 , std::string(expected, size)); 299 return result && generated.size() == size 300 && !std::memcmp(generated.c_str(), expected, size); 301 } 302 303 /////////////////////////////////////////////////////////////////////////// 304 template <typename Generator, typename Attribute, typename Delimiter> 305 inline bool binary_test_delimited(char const * expected,std::size_t size,Generator const & g,Attribute const & attrib,Delimiter const & d)306 binary_test_delimited(char const *expected, std::size_t size, 307 Generator const& g, Attribute const &attrib, Delimiter const& d) 308 { 309 namespace karma = boost::spirit::karma; 310 typedef std::basic_string<char> string_type; 311 312 // we don't care about the result of the "what" function. 313 // we only care that all generators have it: 314 karma::what(g); 315 316 string_type generated; 317 std::back_insert_iterator<string_type> outit(generated); 318 bool result = karma::generate_delimited(outit, g, d, attrib); 319 320 print_binary_if_failed("binary_test_delimited", result, generated 321 , std::string(expected, size)); 322 return result && generated.size() == size 323 && !std::memcmp(generated.c_str(), expected, size); 324 } 325 326 } // namespace spirit_test 327 328 #endif // !BOOST_SPIRIT_KARMA_TEST_FEB_23_2007_1221PM 329