]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/regex/test/regress/test_icu.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / regex / test / regress / test_icu.cpp
1 /*
2 *
3 * Copyright (c) 2004
4 * John Maddock
5 *
6 * Use, modification and distribution are subject to the
7 * Boost Software License, Version 1.0. (See accompanying file
8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 *
10 */
11
12 /*
13 * LOCATION: see http://www.boost.org for most recent version.
14 * FILE test_icu.cpp
15 * VERSION see <boost/version.hpp>
16 * DESCRIPTION: Test code for Unicode regexes with ICU support.
17 */
18
19 //
20 // We can only build this if we have ICU support:
21 //
22 #include <boost/regex/config.hpp>
23 #if defined(BOOST_HAS_ICU) && !defined(BOOST_NO_STD_WSTRING)
24
25 #include <boost/regex/icu.hpp>
26 #include <boost/mpl/int.hpp>
27 #include "test.hpp"
28
29 namespace unnecessary_fix{
30 //
31 // Some outrageously broken std lib's don't have a conforming
32 // back_insert_iterator, which means we can't use the std version
33 // as an argument to regex_replace, sigh... use our own:
34 //
35 template <class Seq>
36 class back_insert_iterator
37 {
38 private:
39 Seq* container;
40 public:
41 typedef const typename Seq::value_type value_type;
42 typedef Seq container_type;
43 typedef void difference_type;
44 typedef void pointer;
45 typedef void reference;
46 typedef std::output_iterator_tag iterator_category;
47
48 explicit back_insert_iterator(Seq& x) : container(&x) {}
49 back_insert_iterator& operator=(const value_type& val)
50 {
51 container->push_back(val);
52 return *this;
53 }
54 back_insert_iterator& operator*() { return *this; }
55 back_insert_iterator& operator++() { return *this; }
56 back_insert_iterator operator++(int) { return *this; }
57 };
58
59 template <class Seq>
60 inline back_insert_iterator<Seq> back_inserter(Seq& x)
61 {
62 return back_insert_iterator<Seq>(x);
63 }
64
65 }
66
67 //
68 // compare two match_results struct's for equality,
69 // converting the iterator as needed:
70 //
71 template <class MR1, class MR2>
72 void compare_result(const MR1& w1, const MR2& w2, boost::mpl::int_<2> const*)
73 {
74 typedef typename MR2::value_type MR2_value_type;
75 typedef typename MR2_value_type::const_iterator MR2_iterator_type;
76 typedef boost::u16_to_u32_iterator<MR2_iterator_type> iterator_type;
77 //typedef typename MR1::size_type size_type;
78 if(w1.size() != w2.size())
79 {
80 BOOST_REGEX_TEST_ERROR("Size mismatch in match_results class", UChar32);
81 }
82 for(int i = 0; i < (int)w1.size(); ++i)
83 {
84 if(w1[i].matched)
85 {
86 if(w2[i].matched == 0)
87 {
88 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32);
89 }
90 if((w1.position(i) != std::distance(iterator_type(w2.prefix().first), iterator_type(w2[i].first))) || (w1.length(i) != std::distance(iterator_type(w2[i].first), iterator_type(w2[i].second))))
91 {
92 BOOST_REGEX_TEST_ERROR("Iterator mismatch in match_results class", UChar32);
93 }
94 }
95 else if(w2[i].matched)
96 {
97 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32);
98 }
99 }
100 //
101 // We don't have a way to access a list of named sub-expressions since we only store
102 // hashes, but "abc" and "N" are common names used in our tests, so check those:
103 //
104 if (w1["abc"].matched)
105 {
106 if (w2["abc"].matched == 0)
107 {
108 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32);
109 }
110 if ((w1.position("abc") != std::distance(iterator_type(w2.prefix().first), iterator_type(w2["abc"].first))) || (w1.length("abc") != std::distance(iterator_type(w2["abc"].first), iterator_type(w2["abc"].second))))
111 {
112 BOOST_REGEX_TEST_ERROR("Iterator mismatch in match_results class", UChar32);
113 }
114 }
115 else if (w2["abc"].matched)
116 {
117 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32);
118 }
119 if (w1["N"].matched)
120 {
121 if (w2["N"].matched == 0)
122 {
123 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32);
124 }
125 if ((w1.position("N") != std::distance(iterator_type(w2.prefix().first), iterator_type(w2["N"].first))) || (w1.length("N") != std::distance(iterator_type(w2["N"].first), iterator_type(w2["N"].second))))
126 {
127 BOOST_REGEX_TEST_ERROR("Iterator mismatch in match_results class", UChar32);
128 }
129 }
130 else if (w2["N"].matched)
131 {
132 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32);
133 }
134 }
135 template <class MR1, class MR2>
136 void compare_result(const MR1& w1, const MR2& w2, boost::mpl::int_<1> const*)
137 {
138 typedef typename MR2::value_type MR2_value_type;
139 typedef typename MR2_value_type::const_iterator MR2_iterator_type;
140 typedef boost::u8_to_u32_iterator<MR2_iterator_type> iterator_type;
141 //typedef typename MR1::size_type size_type;
142 if(w1.size() != w2.size())
143 {
144 BOOST_REGEX_TEST_ERROR("Size mismatch in match_results class", UChar32);
145 }
146 for(int i = 0; i < (int)w1.size(); ++i)
147 {
148 if(w1[i].matched)
149 {
150 if(w2[i].matched == 0)
151 {
152 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32);
153 }
154 if((w1.position(i) != std::distance(iterator_type(w2.prefix().first), iterator_type(w2[i].first))) || (w1.length(i) != std::distance(iterator_type(w2[i].first), iterator_type(w2[i].second))))
155 {
156 BOOST_REGEX_TEST_ERROR("Iterator mismatch in match_results class", UChar32);
157 }
158 }
159 else if(w2[i].matched)
160 {
161 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32);
162 }
163 }
164 }
165
166 void test_icu_grep(const boost::u32regex& r, const std::vector< ::UChar32>& search_text)
167 {
168 typedef std::vector< ::UChar32>::const_iterator const_iterator;
169 typedef boost::u32regex_iterator<const_iterator> test_iterator;
170 boost::regex_constants::match_flag_type opts = test_info<wchar_t>::match_options();
171 const int* answer_table = test_info<wchar_t>::answer_table();
172 test_iterator start(search_text.begin(), search_text.end(), r, opts), end;
173 test_iterator copy(start);
174 const_iterator last_end = search_text.begin();
175 while(start != end)
176 {
177 if(start != copy)
178 {
179 BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", wchar_t);
180 }
181 if(!(start == copy))
182 {
183 BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", wchar_t);
184 }
185 test_result(*start, search_text.begin(), answer_table);
186 // test $` and $' :
187 if(start->prefix().first != last_end)
188 {
189 BOOST_REGEX_TEST_ERROR("Incorrect position for start of $`", wchar_t);
190 }
191 if(start->prefix().second != (*start)[0].first)
192 {
193 BOOST_REGEX_TEST_ERROR("Incorrect position for end of $`", wchar_t);
194 }
195 if(start->prefix().matched != (start->prefix().first != start->prefix().second))
196 {
197 BOOST_REGEX_TEST_ERROR("Incorrect position for matched member of $`", wchar_t);
198 }
199 if(start->suffix().first != (*start)[0].second)
200 {
201 BOOST_REGEX_TEST_ERROR("Incorrect position for start of $'", wchar_t);
202 }
203 if(start->suffix().second != search_text.end())
204 {
205 BOOST_REGEX_TEST_ERROR("Incorrect position for end of $'", wchar_t);
206 }
207 if(start->suffix().matched != (start->suffix().first != start->suffix().second))
208 {
209 BOOST_REGEX_TEST_ERROR("Incorrect position for matched member of $'", wchar_t);
210 }
211 last_end = (*start)[0].second;
212 ++start;
213 ++copy;
214 // move on the answer table to next set of answers;
215 if(*answer_table != -2)
216 while(*answer_table++ != -2){}
217 }
218 if(answer_table[0] >= 0)
219 {
220 // we should have had a match but didn't:
221 BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t);
222 }
223 }
224
225 void test_icu(const wchar_t&, const test_regex_search_tag& )
226 {
227 boost::u32regex r;
228 if(*test_locale::c_str())
229 {
230 U_NAMESPACE_QUALIFIER Locale l(test_locale::c_str());
231 if(l.isBogus())
232 return;
233 r.imbue(l);
234 }
235
236 std::vector< ::UChar32> expression;
237 #ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
238 expression.assign(test_info<wchar_t>::expression().begin(), test_info<wchar_t>::expression().end());
239 #else
240 std::copy(test_info<wchar_t>::expression().begin(), test_info<wchar_t>::expression().end(), std::back_inserter(expression));
241 #endif
242 boost::regex_constants::syntax_option_type syntax_options = test_info<UChar32>::syntax_options();
243 #ifndef BOOST_NO_EXCEPTIONS
244 try
245 #endif
246 {
247 #if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
248 r.assign(expression.begin(), expression.end(), syntax_options);
249 #else
250 if(expression.size())
251 r.assign(&*expression.begin(), expression.size(), syntax_options);
252 else
253 r.assign(static_cast<UChar32 const*>(0), expression.size(), syntax_options);
254 #endif
255 if(r.status())
256 {
257 BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << r.status(), UChar32);
258 }
259 std::vector< ::UChar32> search_text;
260 #ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
261 search_text.assign(test_info<wchar_t>::search_text().begin(), test_info<wchar_t>::search_text().end());
262 #else
263 std::copy(test_info<wchar_t>::search_text().begin(), test_info<wchar_t>::search_text().end(), std::back_inserter(search_text));
264 #endif
265 boost::regex_constants::match_flag_type opts = test_info<wchar_t>::match_options();
266 const int* answer_table = test_info<wchar_t>::answer_table();
267 boost::match_results<std::vector< ::UChar32>::const_iterator> what;
268 if(boost::u32regex_search(
269 const_cast<std::vector< ::UChar32>const&>(search_text).begin(),
270 const_cast<std::vector< ::UChar32>const&>(search_text).end(),
271 what,
272 r,
273 opts))
274 {
275 test_result(what, const_cast<std::vector< ::UChar32>const&>(search_text).begin(), answer_table);
276 }
277 else if(answer_table[0] >= 0)
278 {
279 // we should have had a match but didn't:
280 BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32);
281 }
282
283 if(0 == *test_locale::c_str())
284 {
285 //
286 // Now try UTF-16 construction:
287 //
288 typedef boost::u32_to_u16_iterator<std::vector<UChar32>::const_iterator> u16_conv;
289 std::vector<UChar> expression16, text16;
290 boost::match_results<std::vector<UChar>::const_iterator> what16;
291 boost::match_results<const UChar*> what16c;
292 #ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
293 expression16.assign(u16_conv(expression.begin()), u16_conv(expression.end()));
294 text16.assign(u16_conv(search_text.begin()), u16_conv(search_text.end()));
295 #else
296 expression16.clear();
297 std::copy(u16_conv(expression.begin()), u16_conv(expression.end()), std::back_inserter(expression16));
298 text16.clear();
299 std::copy(u16_conv(search_text.begin()), u16_conv(search_text.end()), std::back_inserter(text16));
300 #endif
301 r = boost::make_u32regex(expression16.begin(), expression16.end(), syntax_options);
302 if(boost::u32regex_search(const_cast<const std::vector<UChar>&>(text16).begin(), const_cast<const std::vector<UChar>&>(text16).end(), what16, r, opts))
303 {
304 compare_result(what, what16, static_cast<boost::mpl::int_<2> const*>(0));
305 }
306 else if(answer_table[0] >= 0)
307 {
308 // we should have had a match but didn't:
309 BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32);
310 }
311 if(std::find(expression16.begin(), expression16.end(), 0) == expression16.end())
312 {
313 expression16.push_back(0);
314 r = boost::make_u32regex(&*expression16.begin(), syntax_options);
315 if(std::find(text16.begin(), text16.end(), 0) == text16.end())
316 {
317 text16.push_back(0);
318 if(boost::u32regex_search((const UChar*)&*text16.begin(), what16c, r, opts))
319 {
320 compare_result(what, what16c, static_cast<boost::mpl::int_<2> const*>(0));
321 }
322 else if(answer_table[0] >= 0)
323 {
324 // we should have had a match but didn't:
325 BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32);
326 }
327 }
328 }
329 //
330 // Now try UTF-8 construction:
331 //
332 typedef boost::u32_to_u8_iterator<std::vector<UChar32>::const_iterator, unsigned char> u8_conv;
333 std::vector<unsigned char> expression8, text8;
334 boost::match_results<std::vector<unsigned char>::const_iterator> what8;
335 boost::match_results<const unsigned char*> what8c;
336 #ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
337 expression8.assign(u8_conv(expression.begin()), u8_conv(expression.end()));
338 text8.assign(u8_conv(search_text.begin()), u8_conv(search_text.end()));
339 #else
340 expression8.clear();
341 std::copy(u8_conv(expression.begin()), u8_conv(expression.end()), std::back_inserter(expression8));
342 text8.clear();
343 std::copy(u8_conv(search_text.begin()), u8_conv(search_text.end()), std::back_inserter(text8));
344 #endif
345 r = boost::make_u32regex(expression8.begin(), expression8.end(), syntax_options);
346 if(boost::u32regex_search(const_cast<const std::vector<unsigned char>&>(text8).begin(), const_cast<const std::vector<unsigned char>&>(text8).end(), what8, r, opts))
347 {
348 compare_result(what, what8, static_cast<boost::mpl::int_<1> const*>(0));
349 }
350 else if(answer_table[0] >= 0)
351 {
352 // we should have had a match but didn't:
353 BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32);
354 }
355 if(std::find(expression8.begin(), expression8.end(), 0) == expression8.end())
356 {
357 expression8.push_back(0);
358 r = boost::make_u32regex(&*expression8.begin(), syntax_options);
359 if(std::find(text8.begin(), text8.end(), 0) == text8.end())
360 {
361 text8.push_back(0);
362 if(boost::u32regex_search((const unsigned char*)&*text8.begin(), what8c, r, opts))
363 {
364 compare_result(what, what8c, static_cast<boost::mpl::int_<1> const*>(0));
365 }
366 else if(answer_table[0] >= 0)
367 {
368 // we should have had a match but didn't:
369 BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32);
370 }
371 }
372 }
373 }
374 //
375 // finally try a grep:
376 //
377 test_icu_grep(r, search_text);
378 }
379 #ifndef BOOST_NO_EXCEPTIONS
380 catch(const boost::bad_expression& e)
381 {
382 BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done: " << e.what(), UChar32);
383 }
384 catch(const std::runtime_error& e)
385 {
386 BOOST_REGEX_TEST_ERROR("Received an unexpected std::runtime_error: " << e.what(), UChar32);
387 }
388 catch(const std::exception& e)
389 {
390 BOOST_REGEX_TEST_ERROR("Received an unexpected std::exception: " << e.what(), UChar32);
391 }
392 catch(...)
393 {
394 BOOST_REGEX_TEST_ERROR("Received an unexpected exception of unknown type", UChar32);
395 }
396 #endif
397 }
398
399 void test_icu(const wchar_t&, const test_invalid_regex_tag&)
400 {
401 //typedef boost::u16_to_u32_iterator<std::wstring::const_iterator, ::UChar32> conv_iterator;
402 std::vector< ::UChar32> expression;
403 #ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
404 expression.assign(test_info<wchar_t>::expression().begin(), test_info<wchar_t>::expression().end());
405 #else
406 std::copy(test_info<wchar_t>::expression().begin(), test_info<wchar_t>::expression().end(), std::back_inserter(expression));
407 #endif
408 boost::regex_constants::syntax_option_type syntax_options = test_info<wchar_t>::syntax_options();
409 boost::u32regex r;
410 if(*test_locale::c_str())
411 {
412 U_NAMESPACE_QUALIFIER Locale l(test_locale::c_str());
413 if(l.isBogus())
414 return;
415 r.imbue(l);
416 }
417 //
418 // try it with exceptions disabled first:
419 //
420 #ifndef BOOST_NO_EXCEPTIONS
421 try
422 #endif
423 {
424 #if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
425 if(0 == r.assign(expression.begin(), expression.end(), syntax_options | boost::regex_constants::no_except).status())
426 #else
427 if(expression.size())
428 r.assign(&*expression.begin(), expression.size(), syntax_options | boost::regex_constants::no_except);
429 else
430 r.assign(static_cast<UChar32 const*>(0), static_cast<boost::u32regex::size_type>(0), syntax_options | boost::regex_constants::no_except);
431 if(0 == r.status())
432 #endif
433 {
434 BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t);
435 }
436 }
437 #ifndef BOOST_NO_EXCEPTIONS
438 catch(...)
439 {
440 BOOST_REGEX_TEST_ERROR("Unexpected exception thrown.", wchar_t);
441 }
442 #endif
443 //
444 // now try again with exceptions:
445 //
446 bool have_catch = false;
447 #ifndef BOOST_NO_EXCEPTIONS
448 try
449 #endif
450 {
451 #if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
452 r.assign(expression.begin(), expression.end(), syntax_options);
453 #else
454 if(expression.size())
455 r.assign(&*expression.begin(), expression.size(), syntax_options);
456 else
457 r.assign(static_cast<UChar32 const*>(0), static_cast<boost::u32regex::size_type>(0), syntax_options);
458 #endif
459 #ifdef BOOST_NO_EXCEPTIONS
460 if(r.status())
461 have_catch = true;
462 #endif
463 }
464 #ifndef BOOST_NO_EXCEPTIONS
465 catch(const boost::bad_expression&)
466 {
467 have_catch = true;
468 }
469 catch(const std::runtime_error& e)
470 {
471 have_catch = true;
472 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::runtime_error instead: " << e.what(), wchar_t);
473 }
474 catch(const std::exception& e)
475 {
476 have_catch = true;
477 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::exception instead: " << e.what(), wchar_t);
478 }
479 catch(...)
480 {
481 have_catch = true;
482 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but got an exception of unknown type instead", wchar_t);
483 }
484 #endif
485 if(!have_catch)
486 {
487 // oops expected exception was not thrown:
488 BOOST_REGEX_TEST_ERROR("Expected an exception, but didn't find one.", wchar_t);
489 }
490
491 if(0 == *test_locale::c_str())
492 {
493 //
494 // Now try UTF-16 construction:
495 //
496 typedef boost::u32_to_u16_iterator<std::vector<UChar32>::const_iterator> u16_conv;
497 std::vector<UChar> expression16;
498 #ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
499 expression16.assign(u16_conv(expression.begin()), u16_conv(expression.end()));
500 #else
501 std::copy(u16_conv(expression.begin()), u16_conv(expression.end()), std::back_inserter(expression16));
502 #endif
503 if(0 == boost::make_u32regex(expression16.begin(), expression16.end(), syntax_options | boost::regex_constants::no_except).status())
504 {
505 BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t);
506 }
507 if(std::find(expression16.begin(), expression16.end(), 0) == expression16.end())
508 {
509 expression16.push_back(0);
510 if(0 == boost::make_u32regex(&*expression16.begin(), syntax_options | boost::regex_constants::no_except).status())
511 {
512 BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t);
513 }
514 }
515 //
516 // Now try UTF-8 construction:
517 //
518 typedef boost::u32_to_u8_iterator<std::vector<UChar32>::const_iterator> u8_conv;
519 std::vector<unsigned char> expression8;
520 #ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
521 expression8.assign(u8_conv(expression.begin()), u8_conv(expression.end()));
522 #else
523 std::copy(u8_conv(expression.begin()), u8_conv(expression.end()), std::back_inserter(expression8));
524 #endif
525 if(0 == boost::make_u32regex(expression8.begin(), expression8.end(), syntax_options | boost::regex_constants::no_except).status())
526 {
527 BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t);
528 }
529 if(std::find(expression8.begin(), expression8.end(), 0) == expression8.end())
530 {
531 expression8.push_back(0);
532 if(0 == boost::make_u32regex(&*expression8.begin(), syntax_options | boost::regex_constants::no_except).status())
533 {
534 BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t);
535 }
536 }
537 }
538 }
539
540 void test_icu(const wchar_t&, const test_regex_replace_tag&)
541 {
542 std::vector< ::UChar32> expression;
543 #ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
544 expression.assign(test_info<wchar_t>::expression().begin(), test_info<wchar_t>::expression().end());
545 #else
546 std::copy(test_info<wchar_t>::expression().begin(), test_info<wchar_t>::expression().end(), std::back_inserter(expression));
547 #endif
548 boost::regex_constants::syntax_option_type syntax_options = test_info<UChar32>::syntax_options();
549 boost::u32regex r;
550 #ifndef BOOST_NO_EXCEPTIONS
551 try
552 #endif
553 {
554 #if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
555 r.assign(expression.begin(), expression.end(), syntax_options);
556 #else
557 if(expression.size())
558 r.assign(&*expression.begin(), expression.size(), syntax_options);
559 else
560 r.assign(static_cast<UChar32 const*>(0), static_cast<boost::u32regex::size_type>(0), syntax_options);
561 #endif
562 if(r.status())
563 {
564 BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << r.status(), UChar32);
565 }
566 typedef std::vector<UChar32> string_type;
567 string_type search_text;
568 boost::regex_constants::match_flag_type opts = test_info<UChar32>::match_options();
569 string_type format_string;
570 string_type result_string;
571 #ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
572 search_text.assign(test_info<UChar32>::search_text().begin(), test_info<UChar32>::search_text().end());
573 format_string.assign(test_info<UChar32>::format_string().begin(), test_info<UChar32>::format_string().end());
574 format_string.push_back(0);
575 result_string.assign(test_info<UChar32>::result_string().begin(), test_info<UChar32>::result_string().end());
576 #else
577 std::copy(test_info<UChar32>::search_text().begin(), test_info<UChar32>::search_text().end(), std::back_inserter(search_text));
578 std::copy(test_info<UChar32>::format_string().begin(), test_info<UChar32>::format_string().end(), std::back_inserter(format_string));
579 format_string.push_back(0);
580 std::copy(test_info<UChar32>::result_string().begin(), test_info<UChar32>::result_string().end(), std::back_inserter(result_string));
581 #endif
582 string_type result;
583
584 boost::u32regex_replace(unnecessary_fix::back_inserter(result), search_text.begin(), search_text.end(), r, &*format_string.begin(), opts);
585 if(result != result_string)
586 {
587 BOOST_REGEX_TEST_ERROR("regex_replace generated an incorrect string result", UChar32);
588 }
589 //
590 // Mixed mode character encoding:
591 //
592 if(0 == *test_locale::c_str())
593 {
594 //
595 // Now try UTF-16 construction:
596 //
597 typedef boost::u32_to_u16_iterator<std::vector<UChar32>::const_iterator> u16_conv;
598 std::vector<UChar> expression16, text16, format16, result16, found16;
599 #ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
600 expression16.assign(u16_conv(expression.begin()), u16_conv(expression.end()));
601 text16.assign(u16_conv(search_text.begin()), u16_conv(search_text.end()));
602 format16.assign(u16_conv(format_string.begin()), u16_conv(format_string.end()));
603 result16.assign(u16_conv(result_string.begin()), u16_conv(result_string.end()));
604 #else
605 std::copy(u16_conv(expression.begin()), u16_conv(expression.end()), std::back_inserter(expression16));
606 std::copy(u16_conv(search_text.begin()), u16_conv(search_text.end()), std::back_inserter(text16));
607 std::copy(u16_conv(format_string.begin()), u16_conv(format_string.end()), std::back_inserter(format16));
608 std::copy(u16_conv(result_string.begin()), u16_conv(result_string.end()), std::back_inserter(result16));
609 #endif
610 r = boost::make_u32regex(expression16.begin(), expression16.end(), syntax_options);
611 boost::u32regex_replace(unnecessary_fix::back_inserter(found16), text16.begin(), text16.end(), r, &*format16.begin(), opts);
612 if(result16 != found16)
613 {
614 BOOST_REGEX_TEST_ERROR("u32regex_replace with UTF-16 string returned incorrect result", UChar32);
615 }
616 //
617 // Now with UnicodeString:
618 //
619 U_NAMESPACE_QUALIFIER UnicodeString expression16u, text16u, format16u, result16u, found16u;
620 if(expression16.size())
621 expression16u.setTo(&*expression16.begin(), expression16.size());
622 if(text16.size())
623 text16u.setTo(&*text16.begin(), text16.size());
624 format16u.setTo(&*format16.begin(), format16.size()-1);
625 if(result16.size())
626 result16u.setTo(&*result16.begin(), result16.size());
627 r = boost::make_u32regex(expression16.begin(), expression16.end(), syntax_options);
628 found16u = boost::u32regex_replace(text16u, r, format16u, opts);
629 if(result16u != found16u)
630 {
631 BOOST_REGEX_TEST_ERROR("u32regex_replace with UTF-16 string returned incorrect result", UChar32);
632 }
633
634 //
635 // Now try UTF-8 construction:
636 //
637 typedef boost::u32_to_u8_iterator<std::vector<UChar32>::const_iterator, unsigned char> u8_conv;
638 std::vector<char> expression8, text8, format8, result8, found8;
639 #ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
640 expression8.assign(u8_conv(expression.begin()), u8_conv(expression.end()));
641 text8.assign(u8_conv(search_text.begin()), u8_conv(search_text.end()));
642 format8.assign(u8_conv(format_string.begin()), u8_conv(format_string.end()));
643 result8.assign(u8_conv(result_string.begin()), u8_conv(result_string.end()));
644 #else
645 std::copy(u8_conv(expression.begin()), u8_conv(expression.end()), std::back_inserter(expression8));
646 std::copy(u8_conv(search_text.begin()), u8_conv(search_text.end()), std::back_inserter(text8));
647 std::copy(u8_conv(format_string.begin()), u8_conv(format_string.end()), std::back_inserter(format8));
648 std::copy(u8_conv(result_string.begin()), u8_conv(result_string.end()), std::back_inserter(result8));
649 #endif
650 r = boost::make_u32regex(expression8.begin(), expression8.end(), syntax_options);
651 boost::u32regex_replace(unnecessary_fix::back_inserter(found8), text8.begin(), text8.end(), r, &*format8.begin(), opts);
652 if(result8 != found8)
653 {
654 BOOST_REGEX_TEST_ERROR("u32regex_replace with UTF-8 string returned incorrect result", UChar32);
655 }
656 //
657 // Now with std::string and UTF-8:
658 //
659 std::string expression8s, text8s, format8s, result8s, found8s;
660 if(expression8.size())
661 expression8s.assign(&*expression8.begin(), expression8.size());
662 if(text8.size())
663 text8s.assign(&*text8.begin(), text8.size());
664 format8s.assign(&*format8.begin(), format8.size()-1);
665 if(result8.size())
666 result8s.assign(&*result8.begin(), result8.size());
667 r = boost::make_u32regex(expression8.begin(), expression8.end(), syntax_options);
668 found8s = boost::u32regex_replace(text8s, r, format8s, opts);
669 if(result8s != found8s)
670 {
671 BOOST_REGEX_TEST_ERROR("u32regex_replace with UTF-8 string returned incorrect result", UChar32);
672 }
673 }
674 }
675 #ifndef BOOST_NO_EXCEPTIONS
676 catch(const boost::bad_expression& e)
677 {
678 BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done: " << e.what(), UChar32);
679 }
680 catch(const std::runtime_error& e)
681 {
682 BOOST_REGEX_TEST_ERROR("Received an unexpected std::runtime_error: " << e.what(), UChar32);
683 }
684 catch(const std::exception& e)
685 {
686 BOOST_REGEX_TEST_ERROR("Received an unexpected std::exception: " << e.what(), UChar32);
687 }
688 catch(...)
689 {
690 BOOST_REGEX_TEST_ERROR("Received an unexpected exception of unknown type", UChar32);
691 }
692 #endif
693 }
694
695 #else
696
697 #include "test.hpp"
698
699 void test_icu(const wchar_t&, const test_regex_search_tag&){}
700 void test_icu(const wchar_t&, const test_invalid_regex_tag&){}
701 void test_icu(const wchar_t&, const test_regex_replace_tag&){}
702
703 #endif
704