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)
13 * LOCATION: see http://www.boost.org for most recent version.
15 * VERSION see <boost/version.hpp>
16 * DESCRIPTION: Test code for Unicode regexes with ICU support.
20 // We can only build this if we have ICU support:
22 #include <boost/regex/config.hpp>
23 #if defined(BOOST_HAS_ICU) && !defined(BOOST_NO_STD_WSTRING)
25 #include <boost/regex/icu.hpp>
26 #include <boost/mpl/int.hpp>
29 namespace unnecessary_fix
{
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:
36 class back_insert_iterator
41 typedef const typename
Seq::value_type value_type
;
42 typedef Seq container_type
;
43 typedef void difference_type
;
45 typedef void reference
;
46 typedef std::output_iterator_tag iterator_category
;
48 explicit back_insert_iterator(Seq
& x
) : container(&x
) {}
49 back_insert_iterator
& operator=(const value_type
& val
)
51 container
->push_back(val
);
54 back_insert_iterator
& operator*() { return *this; }
55 back_insert_iterator
& operator++() { return *this; }
56 back_insert_iterator
operator++(int) { return *this; }
60 inline back_insert_iterator
<Seq
> back_inserter(Seq
& x
)
62 return back_insert_iterator
<Seq
>(x
);
68 // compare two match_results struct's for equality,
69 // converting the iterator as needed:
71 template <class MR1
, class MR2
>
72 void compare_result(const MR1
& w1
, const MR2
& w2
, boost::mpl::int_
<2> const*)
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())
80 BOOST_REGEX_TEST_ERROR("Size mismatch in match_results class", UChar32
);
82 for(int i
= 0; i
< (int)w1
.size(); ++i
)
86 if(w2
[i
].matched
== 0)
88 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32
);
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
))))
92 BOOST_REGEX_TEST_ERROR("Iterator mismatch in match_results class", UChar32
);
95 else if(w2
[i
].matched
)
97 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32
);
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:
104 if (w1
["abc"].matched
)
106 if (w2
["abc"].matched
== 0)
108 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32
);
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
))))
112 BOOST_REGEX_TEST_ERROR("Iterator mismatch in match_results class", UChar32
);
115 else if (w2
["abc"].matched
)
117 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32
);
121 if (w2
["N"].matched
== 0)
123 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32
);
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
))))
127 BOOST_REGEX_TEST_ERROR("Iterator mismatch in match_results class", UChar32
);
130 else if (w2
["N"].matched
)
132 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32
);
135 template <class MR1
, class MR2
>
136 void compare_result(const MR1
& w1
, const MR2
& w2
, boost::mpl::int_
<1> const*)
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())
144 BOOST_REGEX_TEST_ERROR("Size mismatch in match_results class", UChar32
);
146 for(int i
= 0; i
< (int)w1
.size(); ++i
)
150 if(w2
[i
].matched
== 0)
152 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32
);
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
))))
156 BOOST_REGEX_TEST_ERROR("Iterator mismatch in match_results class", UChar32
);
159 else if(w2
[i
].matched
)
161 BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32
);
166 void test_icu_grep(const boost::u32regex
& r
, const std::vector
< ::UChar32
>& search_text
)
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();
179 BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", wchar_t);
183 BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", wchar_t);
185 test_result(*start
, search_text
.begin(), answer_table
);
187 if(start
->prefix().first
!= last_end
)
189 BOOST_REGEX_TEST_ERROR("Incorrect position for start of $`", wchar_t);
191 if(start
->prefix().second
!= (*start
)[0].first
)
193 BOOST_REGEX_TEST_ERROR("Incorrect position for end of $`", wchar_t);
195 if(start
->prefix().matched
!= (start
->prefix().first
!= start
->prefix().second
))
197 BOOST_REGEX_TEST_ERROR("Incorrect position for matched member of $`", wchar_t);
199 if(start
->suffix().first
!= (*start
)[0].second
)
201 BOOST_REGEX_TEST_ERROR("Incorrect position for start of $'", wchar_t);
203 if(start
->suffix().second
!= search_text
.end())
205 BOOST_REGEX_TEST_ERROR("Incorrect position for end of $'", wchar_t);
207 if(start
->suffix().matched
!= (start
->suffix().first
!= start
->suffix().second
))
209 BOOST_REGEX_TEST_ERROR("Incorrect position for matched member of $'", wchar_t);
211 last_end
= (*start
)[0].second
;
214 // move on the answer table to next set of answers;
215 if(*answer_table
!= -2)
216 while(*answer_table
++ != -2){}
218 if(answer_table
[0] >= 0)
220 // we should have had a match but didn't:
221 BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t);
225 void test_icu(const wchar_t&, const test_regex_search_tag
& )
228 if(*test_locale::c_str())
230 U_NAMESPACE_QUALIFIER Locale
l(test_locale::c_str());
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());
240 std::copy(test_info
<wchar_t>::expression().begin(), test_info
<wchar_t>::expression().end(), std::back_inserter(expression
));
242 boost::regex_constants::syntax_option_type syntax_options
= test_info
<UChar32
>::syntax_options();
243 #ifndef BOOST_NO_EXCEPTIONS
247 #if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
248 r
.assign(expression
.begin(), expression
.end(), syntax_options
);
250 if(expression
.size())
251 r
.assign(&*expression
.begin(), expression
.size(), syntax_options
);
253 r
.assign(static_cast<UChar32
const*>(0), expression
.size(), syntax_options
);
257 BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << r
.status(), UChar32
);
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());
263 std::copy(test_info
<wchar_t>::search_text().begin(), test_info
<wchar_t>::search_text().end(), std::back_inserter(search_text
));
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(),
275 test_result(what
, const_cast<std::vector
< ::UChar32
>const&>(search_text
).begin(), answer_table
);
277 else if(answer_table
[0] >= 0)
279 // we should have had a match but didn't:
280 BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32
);
283 if(0 == *test_locale::c_str())
286 // Now try UTF-16 construction:
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()));
296 expression16
.clear();
297 std::copy(u16_conv(expression
.begin()), u16_conv(expression
.end()), std::back_inserter(expression16
));
299 std::copy(u16_conv(search_text
.begin()), u16_conv(search_text
.end()), std::back_inserter(text16
));
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
))
304 compare_result(what
, what16
, static_cast<boost::mpl::int_
<2> const*>(0));
306 else if(answer_table
[0] >= 0)
308 // we should have had a match but didn't:
309 BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32
);
311 if(std::find(expression16
.begin(), expression16
.end(), 0) == expression16
.end())
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())
318 if(boost::u32regex_search((const UChar
*)&*text16
.begin(), what16c
, r
, opts
))
320 compare_result(what
, what16c
, static_cast<boost::mpl::int_
<2> const*>(0));
322 else if(answer_table
[0] >= 0)
324 // we should have had a match but didn't:
325 BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32
);
330 // Now try UTF-8 construction:
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()));
341 std::copy(u8_conv(expression
.begin()), u8_conv(expression
.end()), std::back_inserter(expression8
));
343 std::copy(u8_conv(search_text
.begin()), u8_conv(search_text
.end()), std::back_inserter(text8
));
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
))
348 compare_result(what
, what8
, static_cast<boost::mpl::int_
<1> const*>(0));
350 else if(answer_table
[0] >= 0)
352 // we should have had a match but didn't:
353 BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32
);
355 if(std::find(expression8
.begin(), expression8
.end(), 0) == expression8
.end())
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())
362 if(boost::u32regex_search((const unsigned char*)&*text8
.begin(), what8c
, r
, opts
))
364 compare_result(what
, what8c
, static_cast<boost::mpl::int_
<1> const*>(0));
366 else if(answer_table
[0] >= 0)
368 // we should have had a match but didn't:
369 BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32
);
375 // finally try a grep:
377 test_icu_grep(r
, search_text
);
379 #ifndef BOOST_NO_EXCEPTIONS
380 catch(const boost::bad_expression
& e
)
382 BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done: " << e
.what(), UChar32
);
384 catch(const std::runtime_error
& e
)
386 BOOST_REGEX_TEST_ERROR("Received an unexpected std::runtime_error: " << e
.what(), UChar32
);
388 catch(const std::exception
& e
)
390 BOOST_REGEX_TEST_ERROR("Received an unexpected std::exception: " << e
.what(), UChar32
);
394 BOOST_REGEX_TEST_ERROR("Received an unexpected exception of unknown type", UChar32
);
399 void test_icu(const wchar_t&, const test_invalid_regex_tag
&)
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());
406 std::copy(test_info
<wchar_t>::expression().begin(), test_info
<wchar_t>::expression().end(), std::back_inserter(expression
));
408 boost::regex_constants::syntax_option_type syntax_options
= test_info
<wchar_t>::syntax_options();
410 if(*test_locale::c_str())
412 U_NAMESPACE_QUALIFIER Locale
l(test_locale::c_str());
418 // try it with exceptions disabled first:
420 #ifndef BOOST_NO_EXCEPTIONS
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())
427 if(expression
.size())
428 r
.assign(&*expression
.begin(), expression
.size(), syntax_options
| boost::regex_constants::no_except
);
430 r
.assign(static_cast<UChar32
const*>(0), static_cast<boost::u32regex::size_type
>(0), syntax_options
| boost::regex_constants::no_except
);
434 BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t);
437 #ifndef BOOST_NO_EXCEPTIONS
440 BOOST_REGEX_TEST_ERROR("Unexpected exception thrown.", wchar_t);
444 // now try again with exceptions:
446 bool have_catch
= false;
447 #ifndef BOOST_NO_EXCEPTIONS
451 #if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
452 r
.assign(expression
.begin(), expression
.end(), syntax_options
);
454 if(expression
.size())
455 r
.assign(&*expression
.begin(), expression
.size(), syntax_options
);
457 r
.assign(static_cast<UChar32
const*>(0), static_cast<boost::u32regex::size_type
>(0), syntax_options
);
459 #ifdef BOOST_NO_EXCEPTIONS
464 #ifndef BOOST_NO_EXCEPTIONS
465 catch(const boost::bad_expression
&)
469 catch(const std::runtime_error
& e
)
472 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::runtime_error instead: " << e
.what(), wchar_t);
474 catch(const std::exception
& e
)
477 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::exception instead: " << e
.what(), wchar_t);
482 BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but got an exception of unknown type instead", wchar_t);
487 // oops expected exception was not thrown:
488 BOOST_REGEX_TEST_ERROR("Expected an exception, but didn't find one.", wchar_t);
491 if(0 == *test_locale::c_str())
494 // Now try UTF-16 construction:
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()));
501 std::copy(u16_conv(expression
.begin()), u16_conv(expression
.end()), std::back_inserter(expression16
));
503 if(0 == boost::make_u32regex(expression16
.begin(), expression16
.end(), syntax_options
| boost::regex_constants::no_except
).status())
505 BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t);
507 if(std::find(expression16
.begin(), expression16
.end(), 0) == expression16
.end())
509 expression16
.push_back(0);
510 if(0 == boost::make_u32regex(&*expression16
.begin(), syntax_options
| boost::regex_constants::no_except
).status())
512 BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t);
516 // Now try UTF-8 construction:
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()));
523 std::copy(u8_conv(expression
.begin()), u8_conv(expression
.end()), std::back_inserter(expression8
));
525 if(0 == boost::make_u32regex(expression8
.begin(), expression8
.end(), syntax_options
| boost::regex_constants::no_except
).status())
527 BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t);
529 if(std::find(expression8
.begin(), expression8
.end(), 0) == expression8
.end())
531 expression8
.push_back(0);
532 if(0 == boost::make_u32regex(&*expression8
.begin(), syntax_options
| boost::regex_constants::no_except
).status())
534 BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t);
540 void test_icu(const wchar_t&, const test_regex_replace_tag
&)
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());
546 std::copy(test_info
<wchar_t>::expression().begin(), test_info
<wchar_t>::expression().end(), std::back_inserter(expression
));
548 boost::regex_constants::syntax_option_type syntax_options
= test_info
<UChar32
>::syntax_options();
550 #ifndef BOOST_NO_EXCEPTIONS
554 #if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
555 r
.assign(expression
.begin(), expression
.end(), syntax_options
);
557 if(expression
.size())
558 r
.assign(&*expression
.begin(), expression
.size(), syntax_options
);
560 r
.assign(static_cast<UChar32
const*>(0), static_cast<boost::u32regex::size_type
>(0), syntax_options
);
564 BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << r
.status(), UChar32
);
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());
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
));
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
)
587 BOOST_REGEX_TEST_ERROR("regex_replace generated an incorrect string result", UChar32
);
590 // Mixed mode character encoding:
592 if(0 == *test_locale::c_str())
595 // Now try UTF-16 construction:
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()));
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
));
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
)
614 BOOST_REGEX_TEST_ERROR("u32regex_replace with UTF-16 string returned incorrect result", UChar32
);
617 // Now with UnicodeString:
619 U_NAMESPACE_QUALIFIER UnicodeString expression16u
, text16u
, format16u
, result16u
, found16u
;
620 if(expression16
.size())
621 expression16u
.setTo(&*expression16
.begin(), expression16
.size());
623 text16u
.setTo(&*text16
.begin(), text16
.size());
624 format16u
.setTo(&*format16
.begin(), format16
.size()-1);
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
)
631 BOOST_REGEX_TEST_ERROR("u32regex_replace with UTF-16 string returned incorrect result", UChar32
);
635 // Now try UTF-8 construction:
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()));
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
));
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
)
654 BOOST_REGEX_TEST_ERROR("u32regex_replace with UTF-8 string returned incorrect result", UChar32
);
657 // Now with std::string and UTF-8:
659 std::string expression8s
, text8s
, format8s
, result8s
, found8s
;
660 if(expression8
.size())
661 expression8s
.assign(&*expression8
.begin(), expression8
.size());
663 text8s
.assign(&*text8
.begin(), text8
.size());
664 format8s
.assign(&*format8
.begin(), format8
.size()-1);
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
)
671 BOOST_REGEX_TEST_ERROR("u32regex_replace with UTF-8 string returned incorrect result", UChar32
);
675 #ifndef BOOST_NO_EXCEPTIONS
676 catch(const boost::bad_expression
& e
)
678 BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done: " << e
.what(), UChar32
);
680 catch(const std::runtime_error
& e
)
682 BOOST_REGEX_TEST_ERROR("Received an unexpected std::runtime_error: " << e
.what(), UChar32
);
684 catch(const std::exception
& e
)
686 BOOST_REGEX_TEST_ERROR("Received an unexpected std::exception: " << e
.what(), UChar32
);
690 BOOST_REGEX_TEST_ERROR("Received an unexpected exception of unknown type", UChar32
);
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
&){}