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         icu.hpp
15   *   VERSION      see <boost/version.hpp>
16   *   DESCRIPTION: Unicode regular expressions on top of the ICU Library.
17   */
18 
19 #ifndef BOOST_REGEX_ICU_HPP
20 #define BOOST_REGEX_ICU_HPP
21 
22 #include <boost/config.hpp>
23 #include <unicode/utypes.h>
24 #include <unicode/uchar.h>
25 #include <unicode/coll.h>
26 #include <boost/regex.hpp>
27 #include <boost/regex/pending/unicode_iterator.hpp>
28 #include <boost/mpl/int_fwd.hpp>
29 #include <boost/static_assert.hpp>
30 #include <bitset>
31 
32 #ifdef BOOST_MSVC
33 #pragma warning (push)
34 #pragma warning (disable: 4251)
35 #endif
36 
37 namespace boost{
38 
39 namespace BOOST_REGEX_DETAIL_NS{
40 
41 //
42 // Implementation details:
43 //
44 class BOOST_REGEX_DECL icu_regex_traits_implementation
45 {
46    typedef UChar32                      char_type;
47    typedef std::size_t                  size_type;
48    typedef std::vector<char_type>       string_type;
49    typedef U_NAMESPACE_QUALIFIER Locale locale_type;
50    typedef boost::uint_least32_t        char_class_type;
51 public:
icu_regex_traits_implementation(const U_NAMESPACE_QUALIFIER Locale & l)52    icu_regex_traits_implementation(const U_NAMESPACE_QUALIFIER Locale& l)
53       : m_locale(l)
54    {
55       UErrorCode success = U_ZERO_ERROR;
56       m_collator.reset(U_NAMESPACE_QUALIFIER Collator::createInstance(l, success));
57       if(U_SUCCESS(success) == 0)
58          init_error();
59       m_collator->setStrength(U_NAMESPACE_QUALIFIER Collator::IDENTICAL);
60       success = U_ZERO_ERROR;
61       m_primary_collator.reset(U_NAMESPACE_QUALIFIER Collator::createInstance(l, success));
62       if(U_SUCCESS(success) == 0)
63          init_error();
64       m_primary_collator->setStrength(U_NAMESPACE_QUALIFIER Collator::PRIMARY);
65    }
getloc() const66    U_NAMESPACE_QUALIFIER Locale getloc()const
67    {
68       return m_locale;
69    }
70    string_type do_transform(const char_type* p1, const char_type* p2, const U_NAMESPACE_QUALIFIER Collator* pcoll) const;
transform(const char_type * p1,const char_type * p2) const71    string_type transform(const char_type* p1, const char_type* p2) const
72    {
73       return do_transform(p1, p2, m_collator.get());
74    }
transform_primary(const char_type * p1,const char_type * p2) const75    string_type transform_primary(const char_type* p1, const char_type* p2) const
76    {
77       return do_transform(p1, p2, m_primary_collator.get());
78    }
79 private:
init_error()80    void init_error()
81    {
82       std::runtime_error e("Could not initialize ICU resources");
83       boost::throw_exception(e);
84    }
85    U_NAMESPACE_QUALIFIER Locale m_locale;                                  // The ICU locale that we're using
86    boost::scoped_ptr< U_NAMESPACE_QUALIFIER Collator> m_collator;          // The full collation object
87    boost::scoped_ptr< U_NAMESPACE_QUALIFIER Collator> m_primary_collator;  // The primary collation object
88 };
89 
get_icu_regex_traits_implementation(const U_NAMESPACE_QUALIFIER Locale & loc)90 inline boost::shared_ptr<icu_regex_traits_implementation> get_icu_regex_traits_implementation(const U_NAMESPACE_QUALIFIER Locale& loc)
91 {
92    return boost::shared_ptr<icu_regex_traits_implementation>(new icu_regex_traits_implementation(loc));
93 }
94 
95 }
96 
97 class BOOST_REGEX_DECL icu_regex_traits
98 {
99 public:
100    typedef UChar32                      char_type;
101    typedef std::size_t                  size_type;
102    typedef std::vector<char_type>       string_type;
103    typedef U_NAMESPACE_QUALIFIER Locale locale_type;
104 #ifdef BOOST_NO_INT64_T
105    typedef std::bitset<64>              char_class_type;
106 #else
107    typedef boost::uint64_t              char_class_type;
108 #endif
109 
110    struct boost_extensions_tag{};
111 
icu_regex_traits()112    icu_regex_traits()
113       : m_pimpl(BOOST_REGEX_DETAIL_NS::get_icu_regex_traits_implementation(U_NAMESPACE_QUALIFIER Locale()))
114    {
115    }
116    static size_type length(const char_type* p);
117 
syntax_type(char_type c) const118    ::boost::regex_constants::syntax_type syntax_type(char_type c)const
119    {
120       return ((c < 0x7f) && (c > 0)) ? BOOST_REGEX_DETAIL_NS::get_default_syntax_type(static_cast<char>(c)) : regex_constants::syntax_char;
121    }
escape_syntax_type(char_type c) const122    ::boost::regex_constants::escape_syntax_type escape_syntax_type(char_type c) const
123    {
124       return ((c < 0x7f) && (c > 0)) ? BOOST_REGEX_DETAIL_NS::get_default_escape_syntax_type(static_cast<char>(c)) : regex_constants::syntax_char;
125    }
translate(char_type c) const126    char_type translate(char_type c) const
127    {
128       return c;
129    }
translate_nocase(char_type c) const130    char_type translate_nocase(char_type c) const
131    {
132       return ::u_tolower(c);
133    }
translate(char_type c,bool icase) const134    char_type translate(char_type c, bool icase) const
135    {
136       return icase ? translate_nocase(c) : translate(c);
137    }
tolower(char_type c) const138    char_type tolower(char_type c) const
139    {
140       return ::u_tolower(c);
141    }
toupper(char_type c) const142    char_type toupper(char_type c) const
143    {
144       return ::u_toupper(c);
145    }
transform(const char_type * p1,const char_type * p2) const146    string_type transform(const char_type* p1, const char_type* p2) const
147    {
148       return m_pimpl->transform(p1, p2);
149    }
transform_primary(const char_type * p1,const char_type * p2) const150    string_type transform_primary(const char_type* p1, const char_type* p2) const
151    {
152       return m_pimpl->transform_primary(p1, p2);
153    }
154    char_class_type lookup_classname(const char_type* p1, const char_type* p2) const;
155    string_type lookup_collatename(const char_type* p1, const char_type* p2) const;
156    bool isctype(char_type c, char_class_type f) const;
toi(const char_type * & p1,const char_type * p2,int radix) const157    boost::intmax_t toi(const char_type*& p1, const char_type* p2, int radix)const
158    {
159       return BOOST_REGEX_DETAIL_NS::global_toi(p1, p2, radix, *this);
160    }
value(char_type c,int radix) const161    int value(char_type c, int radix)const
162    {
163       return u_digit(c, static_cast< ::int8_t>(radix));
164    }
imbue(locale_type l)165    locale_type imbue(locale_type l)
166    {
167       locale_type result(m_pimpl->getloc());
168       m_pimpl = BOOST_REGEX_DETAIL_NS::get_icu_regex_traits_implementation(l);
169       return result;
170    }
getloc() const171    locale_type getloc()const
172    {
173       return locale_type();
174    }
error_string(::boost::regex_constants::error_type n) const175    std::string error_string(::boost::regex_constants::error_type n) const
176    {
177       return BOOST_REGEX_DETAIL_NS::get_default_error_string(n);
178    }
179 private:
180    icu_regex_traits(const icu_regex_traits&);
181    icu_regex_traits& operator=(const icu_regex_traits&);
182 
183    //
184    // define the bitmasks offsets we need for additional character properties:
185    //
186    enum{
187       offset_blank = U_CHAR_CATEGORY_COUNT,
188       offset_space = U_CHAR_CATEGORY_COUNT+1,
189       offset_xdigit = U_CHAR_CATEGORY_COUNT+2,
190       offset_underscore = U_CHAR_CATEGORY_COUNT+3,
191       offset_unicode = U_CHAR_CATEGORY_COUNT+4,
192       offset_any = U_CHAR_CATEGORY_COUNT+5,
193       offset_ascii = U_CHAR_CATEGORY_COUNT+6,
194       offset_horizontal = U_CHAR_CATEGORY_COUNT+7,
195       offset_vertical = U_CHAR_CATEGORY_COUNT+8
196    };
197 
198    //
199    // and now the masks:
200    //
201    static const char_class_type mask_blank;
202    static const char_class_type mask_space;
203    static const char_class_type mask_xdigit;
204    static const char_class_type mask_underscore;
205    static const char_class_type mask_unicode;
206    static const char_class_type mask_any;
207    static const char_class_type mask_ascii;
208    static const char_class_type mask_horizontal;
209    static const char_class_type mask_vertical;
210 
211    static char_class_type lookup_icu_mask(const ::UChar32* p1, const ::UChar32* p2);
212 
213    boost::shared_ptr< ::boost::BOOST_REGEX_DETAIL_NS::icu_regex_traits_implementation> m_pimpl;
214 };
215 
216 } // namespace boost
217 
218 //
219 // template instances:
220 //
221 #define BOOST_REGEX_CHAR_T UChar32
222 #undef BOOST_REGEX_TRAITS_T
223 #define BOOST_REGEX_TRAITS_T , icu_regex_traits
224 #define BOOST_REGEX_ICU_INSTANCES
225 #ifdef BOOST_REGEX_ICU_INSTANTIATE
226 #  define BOOST_REGEX_INSTANTIATE
227 #endif
228 #include <boost/regex/v4/instances.hpp>
229 #undef BOOST_REGEX_CHAR_T
230 #undef BOOST_REGEX_TRAITS_T
231 #undef BOOST_REGEX_ICU_INSTANCES
232 #ifdef BOOST_REGEX_INSTANTIATE
233 #  undef BOOST_REGEX_INSTANTIATE
234 #endif
235 
236 namespace boost{
237 
238 // types:
239 typedef basic_regex< ::UChar32, icu_regex_traits> u32regex;
240 typedef match_results<const ::UChar32*> u32match;
241 typedef match_results<const ::UChar*> u16match;
242 
243 //
244 // Construction of 32-bit regex types from UTF-8 and UTF-16 primitives:
245 //
246 namespace BOOST_REGEX_DETAIL_NS{
247 
248 #if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
249 template <class InputIterator>
do_make_u32regex(InputIterator i,InputIterator j,boost::regex_constants::syntax_option_type opt,const boost::mpl::int_<1> *)250 inline u32regex do_make_u32regex(InputIterator i,
251                               InputIterator j,
252                               boost::regex_constants::syntax_option_type opt,
253                               const boost::mpl::int_<1>*)
254 {
255    typedef boost::u8_to_u32_iterator<InputIterator, UChar32> conv_type;
256    return u32regex(conv_type(i, i, j), conv_type(j, i, j), opt);
257 }
258 
259 template <class InputIterator>
do_make_u32regex(InputIterator i,InputIterator j,boost::regex_constants::syntax_option_type opt,const boost::mpl::int_<2> *)260 inline u32regex do_make_u32regex(InputIterator i,
261                               InputIterator j,
262                               boost::regex_constants::syntax_option_type opt,
263                               const boost::mpl::int_<2>*)
264 {
265    typedef boost::u16_to_u32_iterator<InputIterator, UChar32> conv_type;
266    return u32regex(conv_type(i, i, j), conv_type(j, i, j), opt);
267 }
268 
269 template <class InputIterator>
do_make_u32regex(InputIterator i,InputIterator j,boost::regex_constants::syntax_option_type opt,const boost::mpl::int_<4> *)270 inline u32regex do_make_u32regex(InputIterator i,
271                               InputIterator j,
272                               boost::regex_constants::syntax_option_type opt,
273                               const boost::mpl::int_<4>*)
274 {
275    return u32regex(i, j, opt);
276 }
277 #else
278 template <class InputIterator>
279 inline u32regex do_make_u32regex(InputIterator i,
280                               InputIterator j,
281                               boost::regex_constants::syntax_option_type opt,
282                               const boost::mpl::int_<1>*)
283 {
284    typedef boost::u8_to_u32_iterator<InputIterator, UChar32> conv_type;
285    typedef std::vector<UChar32> vector_type;
286    vector_type v;
287    conv_type a(i, i, j), b(j, i, j);
288    while(a != b)
289    {
290       v.push_back(*a);
291       ++a;
292    }
293    if(v.size())
294       return u32regex(&*v.begin(), v.size(), opt);
295    return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
296 }
297 
298 template <class InputIterator>
299 inline u32regex do_make_u32regex(InputIterator i,
300                               InputIterator j,
301                               boost::regex_constants::syntax_option_type opt,
302                               const boost::mpl::int_<2>*)
303 {
304    typedef boost::u16_to_u32_iterator<InputIterator, UChar32> conv_type;
305    typedef std::vector<UChar32> vector_type;
306    vector_type v;
307    conv_type a(i, i, j), b(j, i, j);
308    while(a != b)
309    {
310       v.push_back(*a);
311       ++a;
312    }
313    if(v.size())
314       return u32regex(&*v.begin(), v.size(), opt);
315    return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
316 }
317 
318 template <class InputIterator>
319 inline u32regex do_make_u32regex(InputIterator i,
320                               InputIterator j,
321                               boost::regex_constants::syntax_option_type opt,
322                               const boost::mpl::int_<4>*)
323 {
324    typedef std::vector<UChar32> vector_type;
325    vector_type v;
326    while(i != j)
327    {
328       v.push_back((UChar32)(*i));
329       ++i;
330    }
331    if(v.size())
332       return u32regex(&*v.begin(), v.size(), opt);
333    return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
334 }
335 #endif
336 }
337 
338 // BOOST_REGEX_UCHAR_IS_WCHAR_T
339 //
340 // Source inspection of unicode/umachine.h in ICU version 59 indicates that:
341 //
342 // On version 59, UChar is always char16_t in C++ mode (and uint16_t in C mode)
343 //
344 // On earlier versions, the logic is
345 //
346 // #if U_SIZEOF_WCHAR_T==2
347 //   typedef wchar_t OldUChar;
348 // #elif defined(__CHAR16_TYPE__)
349 //   typedef __CHAR16_TYPE__ OldUChar;
350 // #else
351 //   typedef uint16_t OldUChar;
352 // #endif
353 //
354 // That is, UChar is wchar_t only on versions below 59, when U_SIZEOF_WCHAR_T==2
355 //
356 // Hence,
357 
358 #define BOOST_REGEX_UCHAR_IS_WCHAR_T (U_ICU_VERSION_MAJOR_NUM < 59 && U_SIZEOF_WCHAR_T == 2)
359 
360 #if BOOST_REGEX_UCHAR_IS_WCHAR_T
361   BOOST_STATIC_ASSERT((boost::is_same<UChar, wchar_t>::value));
362 #else
363   BOOST_STATIC_ASSERT(!(boost::is_same<UChar, wchar_t>::value));
364 #endif
365 
366 //
367 // Construction from an iterator pair:
368 //
369 template <class InputIterator>
make_u32regex(InputIterator i,InputIterator j,boost::regex_constants::syntax_option_type opt)370 inline u32regex make_u32regex(InputIterator i,
371                               InputIterator j,
372                               boost::regex_constants::syntax_option_type opt)
373 {
374    return BOOST_REGEX_DETAIL_NS::do_make_u32regex(i, j, opt, static_cast<boost::mpl::int_<sizeof(*i)> const*>(0));
375 }
376 //
377 // construction from UTF-8 nul-terminated strings:
378 //
make_u32regex(const char * p,boost::regex_constants::syntax_option_type opt=boost::regex_constants::perl)379 inline u32regex make_u32regex(const char* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)
380 {
381    return BOOST_REGEX_DETAIL_NS::do_make_u32regex(p, p + std::strlen(p), opt, static_cast<boost::mpl::int_<1> const*>(0));
382 }
make_u32regex(const unsigned char * p,boost::regex_constants::syntax_option_type opt=boost::regex_constants::perl)383 inline u32regex make_u32regex(const unsigned char* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)
384 {
385    return BOOST_REGEX_DETAIL_NS::do_make_u32regex(p, p + std::strlen(reinterpret_cast<const char*>(p)), opt, static_cast<boost::mpl::int_<1> const*>(0));
386 }
387 //
388 // construction from UTF-16 nul-terminated strings:
389 //
390 #ifndef BOOST_NO_WREGEX
make_u32regex(const wchar_t * p,boost::regex_constants::syntax_option_type opt=boost::regex_constants::perl)391 inline u32regex make_u32regex(const wchar_t* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)
392 {
393    return BOOST_REGEX_DETAIL_NS::do_make_u32regex(p, p + std::wcslen(p), opt, static_cast<boost::mpl::int_<sizeof(wchar_t)> const*>(0));
394 }
395 #endif
396 #if !BOOST_REGEX_UCHAR_IS_WCHAR_T
make_u32regex(const UChar * p,boost::regex_constants::syntax_option_type opt=boost::regex_constants::perl)397 inline u32regex make_u32regex(const UChar* p, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)
398 {
399    return BOOST_REGEX_DETAIL_NS::do_make_u32regex(p, p + u_strlen(p), opt, static_cast<boost::mpl::int_<2> const*>(0));
400 }
401 #endif
402 //
403 // construction from basic_string class-template:
404 //
405 template<class C, class T, class A>
make_u32regex(const std::basic_string<C,T,A> & s,boost::regex_constants::syntax_option_type opt=boost::regex_constants::perl)406 inline u32regex make_u32regex(const std::basic_string<C, T, A>& s, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)
407 {
408    return BOOST_REGEX_DETAIL_NS::do_make_u32regex(s.begin(), s.end(), opt, static_cast<boost::mpl::int_<sizeof(C)> const*>(0));
409 }
410 //
411 // Construction from ICU string type:
412 //
make_u32regex(const U_NAMESPACE_QUALIFIER UnicodeString & s,boost::regex_constants::syntax_option_type opt=boost::regex_constants::perl)413 inline u32regex make_u32regex(const U_NAMESPACE_QUALIFIER UnicodeString& s, boost::regex_constants::syntax_option_type opt = boost::regex_constants::perl)
414 {
415    return BOOST_REGEX_DETAIL_NS::do_make_u32regex(s.getBuffer(), s.getBuffer() + s.length(), opt, static_cast<boost::mpl::int_<2> const*>(0));
416 }
417 
418 //
419 // regex_match overloads that widen the character type as appropriate:
420 //
421 namespace BOOST_REGEX_DETAIL_NS{
422 template<class MR1, class MR2, class NSubs>
copy_results(MR1 & out,MR2 const & in,NSubs named_subs)423 void copy_results(MR1& out, MR2 const& in, NSubs named_subs)
424 {
425    // copy results from an adapted MR2 match_results:
426    out.set_size(in.size(), in.prefix().first.base(), in.suffix().second.base());
427    out.set_base(in.base().base());
428    out.set_named_subs(named_subs);
429    for(int i = 0; i < (int)in.size(); ++i)
430    {
431       if(in[i].matched || !i)
432       {
433          out.set_first(in[i].first.base(), i);
434          out.set_second(in[i].second.base(), i, in[i].matched);
435       }
436    }
437 #ifdef BOOST_REGEX_MATCH_EXTRA
438    // Copy full capture info as well:
439    for(int i = 0; i < (int)in.size(); ++i)
440    {
441       if(in[i].captures().size())
442       {
443          out[i].get_captures().assign(in[i].captures().size(), typename MR1::value_type());
444          for(int j = 0; j < (int)out[i].captures().size(); ++j)
445          {
446             out[i].get_captures()[j].first = in[i].captures()[j].first.base();
447             out[i].get_captures()[j].second = in[i].captures()[j].second.base();
448             out[i].get_captures()[j].matched = in[i].captures()[j].matched;
449          }
450       }
451    }
452 #endif
453 }
454 
455 template <class BidiIterator, class Allocator>
do_regex_match(BidiIterator first,BidiIterator last,match_results<BidiIterator,Allocator> & m,const u32regex & e,match_flag_type flags,boost::mpl::int_<4> const *)456 inline bool do_regex_match(BidiIterator first, BidiIterator last,
457                  match_results<BidiIterator, Allocator>& m,
458                  const u32regex& e,
459                  match_flag_type flags,
460                  boost::mpl::int_<4> const*)
461 {
462    return ::boost::regex_match(first, last, m, e, flags);
463 }
464 template <class BidiIterator, class Allocator>
do_regex_match(BidiIterator first,BidiIterator last,match_results<BidiIterator,Allocator> & m,const u32regex & e,match_flag_type flags,boost::mpl::int_<2> const *)465 bool do_regex_match(BidiIterator first, BidiIterator last,
466                  match_results<BidiIterator, Allocator>& m,
467                  const u32regex& e,
468                  match_flag_type flags,
469                  boost::mpl::int_<2> const*)
470 {
471    typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;
472    typedef match_results<conv_type>                   match_type;
473    //typedef typename match_type::allocator_type        alloc_type;
474    match_type what;
475    bool result = ::boost::regex_match(conv_type(first, first, last), conv_type(last, first, last), what, e, flags);
476    // copy results across to m:
477    if(result) copy_results(m, what, e.get_named_subs());
478    return result;
479 }
480 template <class BidiIterator, class Allocator>
do_regex_match(BidiIterator first,BidiIterator last,match_results<BidiIterator,Allocator> & m,const u32regex & e,match_flag_type flags,boost::mpl::int_<1> const *)481 bool do_regex_match(BidiIterator first, BidiIterator last,
482                  match_results<BidiIterator, Allocator>& m,
483                  const u32regex& e,
484                  match_flag_type flags,
485                  boost::mpl::int_<1> const*)
486 {
487    typedef u8_to_u32_iterator<BidiIterator, UChar32>  conv_type;
488    typedef match_results<conv_type>                   match_type;
489    //typedef typename match_type::allocator_type        alloc_type;
490    match_type what;
491    bool result = ::boost::regex_match(conv_type(first, first, last), conv_type(last, first, last), what, e, flags);
492    // copy results across to m:
493    if(result) copy_results(m, what, e.get_named_subs());
494    return result;
495 }
496 } // namespace BOOST_REGEX_DETAIL_NS
497 
498 template <class BidiIterator, class Allocator>
u32regex_match(BidiIterator first,BidiIterator last,match_results<BidiIterator,Allocator> & m,const u32regex & e,match_flag_type flags=match_default)499 inline bool u32regex_match(BidiIterator first, BidiIterator last,
500                  match_results<BidiIterator, Allocator>& m,
501                  const u32regex& e,
502                  match_flag_type flags = match_default)
503 {
504    return BOOST_REGEX_DETAIL_NS::do_regex_match(first, last, m, e, flags, static_cast<mpl::int_<sizeof(*first)> const*>(0));
505 }
u32regex_match(const UChar * p,match_results<const UChar * > & m,const u32regex & e,match_flag_type flags=match_default)506 inline bool u32regex_match(const UChar* p,
507                  match_results<const UChar*>& m,
508                  const u32regex& e,
509                  match_flag_type flags = match_default)
510 {
511    return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+u_strlen(p), m, e, flags, static_cast<mpl::int_<2> const*>(0));
512 }
513 #if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX)
u32regex_match(const wchar_t * p,match_results<const wchar_t * > & m,const u32regex & e,match_flag_type flags=match_default)514 inline bool u32regex_match(const wchar_t* p,
515                  match_results<const wchar_t*>& m,
516                  const u32regex& e,
517                  match_flag_type flags = match_default)
518 {
519    return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::wcslen(p), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
520 }
521 #endif
u32regex_match(const char * p,match_results<const char * > & m,const u32regex & e,match_flag_type flags=match_default)522 inline bool u32regex_match(const char* p,
523                  match_results<const char*>& m,
524                  const u32regex& e,
525                  match_flag_type flags = match_default)
526 {
527    return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::strlen(p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
528 }
u32regex_match(const unsigned char * p,match_results<const unsigned char * > & m,const u32regex & e,match_flag_type flags=match_default)529 inline bool u32regex_match(const unsigned char* p,
530                  match_results<const unsigned char*>& m,
531                  const u32regex& e,
532                  match_flag_type flags = match_default)
533 {
534    return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::strlen((const char*)p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
535 }
u32regex_match(const std::string & s,match_results<std::string::const_iterator> & m,const u32regex & e,match_flag_type flags=match_default)536 inline bool u32regex_match(const std::string& s,
537                         match_results<std::string::const_iterator>& m,
538                         const u32regex& e,
539                         match_flag_type flags = match_default)
540 {
541    return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<1> const*>(0));
542 }
543 #ifndef BOOST_NO_STD_WSTRING
u32regex_match(const std::wstring & s,match_results<std::wstring::const_iterator> & m,const u32regex & e,match_flag_type flags=match_default)544 inline bool u32regex_match(const std::wstring& s,
545                         match_results<std::wstring::const_iterator>& m,
546                         const u32regex& e,
547                         match_flag_type flags = match_default)
548 {
549    return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
550 }
551 #endif
u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString & s,match_results<const UChar * > & m,const u32regex & e,match_flag_type flags=match_default)552 inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s,
553                         match_results<const UChar*>& m,
554                         const u32regex& e,
555                         match_flag_type flags = match_default)
556 {
557    return BOOST_REGEX_DETAIL_NS::do_regex_match(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
558 }
559 //
560 // regex_match overloads that do not return what matched:
561 //
562 template <class BidiIterator>
u32regex_match(BidiIterator first,BidiIterator last,const u32regex & e,match_flag_type flags=match_default)563 inline bool u32regex_match(BidiIterator first, BidiIterator last,
564                  const u32regex& e,
565                  match_flag_type flags = match_default)
566 {
567    match_results<BidiIterator> m;
568    return BOOST_REGEX_DETAIL_NS::do_regex_match(first, last, m, e, flags, static_cast<mpl::int_<sizeof(*first)> const*>(0));
569 }
u32regex_match(const UChar * p,const u32regex & e,match_flag_type flags=match_default)570 inline bool u32regex_match(const UChar* p,
571                  const u32regex& e,
572                  match_flag_type flags = match_default)
573 {
574    match_results<const UChar*> m;
575    return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+u_strlen(p), m, e, flags, static_cast<mpl::int_<2> const*>(0));
576 }
577 #if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX)
u32regex_match(const wchar_t * p,const u32regex & e,match_flag_type flags=match_default)578 inline bool u32regex_match(const wchar_t* p,
579                  const u32regex& e,
580                  match_flag_type flags = match_default)
581 {
582    match_results<const wchar_t*> m;
583    return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::wcslen(p), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
584 }
585 #endif
u32regex_match(const char * p,const u32regex & e,match_flag_type flags=match_default)586 inline bool u32regex_match(const char* p,
587                  const u32regex& e,
588                  match_flag_type flags = match_default)
589 {
590    match_results<const char*> m;
591    return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::strlen(p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
592 }
u32regex_match(const unsigned char * p,const u32regex & e,match_flag_type flags=match_default)593 inline bool u32regex_match(const unsigned char* p,
594                  const u32regex& e,
595                  match_flag_type flags = match_default)
596 {
597    match_results<const unsigned char*> m;
598    return BOOST_REGEX_DETAIL_NS::do_regex_match(p, p+std::strlen((const char*)p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
599 }
u32regex_match(const std::string & s,const u32regex & e,match_flag_type flags=match_default)600 inline bool u32regex_match(const std::string& s,
601                         const u32regex& e,
602                         match_flag_type flags = match_default)
603 {
604    match_results<std::string::const_iterator> m;
605    return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<1> const*>(0));
606 }
607 #ifndef BOOST_NO_STD_WSTRING
u32regex_match(const std::wstring & s,const u32regex & e,match_flag_type flags=match_default)608 inline bool u32regex_match(const std::wstring& s,
609                         const u32regex& e,
610                         match_flag_type flags = match_default)
611 {
612    match_results<std::wstring::const_iterator> m;
613    return BOOST_REGEX_DETAIL_NS::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
614 }
615 #endif
u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString & s,const u32regex & e,match_flag_type flags=match_default)616 inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s,
617                         const u32regex& e,
618                         match_flag_type flags = match_default)
619 {
620    match_results<const UChar*> m;
621    return BOOST_REGEX_DETAIL_NS::do_regex_match(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
622 }
623 
624 //
625 // regex_search overloads that widen the character type as appropriate:
626 //
627 namespace BOOST_REGEX_DETAIL_NS{
628 template <class BidiIterator, class Allocator>
do_regex_search(BidiIterator first,BidiIterator last,match_results<BidiIterator,Allocator> & m,const u32regex & e,match_flag_type flags,BidiIterator base,boost::mpl::int_<4> const *)629 inline bool do_regex_search(BidiIterator first, BidiIterator last,
630                  match_results<BidiIterator, Allocator>& m,
631                  const u32regex& e,
632                  match_flag_type flags,
633                  BidiIterator base,
634                  boost::mpl::int_<4> const*)
635 {
636    return ::boost::regex_search(first, last, m, e, flags, base);
637 }
638 template <class BidiIterator, class Allocator>
do_regex_search(BidiIterator first,BidiIterator last,match_results<BidiIterator,Allocator> & m,const u32regex & e,match_flag_type flags,BidiIterator base,boost::mpl::int_<2> const *)639 bool do_regex_search(BidiIterator first, BidiIterator last,
640                  match_results<BidiIterator, Allocator>& m,
641                  const u32regex& e,
642                  match_flag_type flags,
643                  BidiIterator base,
644                  boost::mpl::int_<2> const*)
645 {
646    typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;
647    typedef match_results<conv_type>                   match_type;
648    //typedef typename match_type::allocator_type        alloc_type;
649    match_type what;
650    bool result = ::boost::regex_search(conv_type(first, first, last), conv_type(last, first, last), what, e, flags, conv_type(base));
651    // copy results across to m:
652    if(result) copy_results(m, what, e.get_named_subs());
653    return result;
654 }
655 template <class BidiIterator, class Allocator>
do_regex_search(BidiIterator first,BidiIterator last,match_results<BidiIterator,Allocator> & m,const u32regex & e,match_flag_type flags,BidiIterator base,boost::mpl::int_<1> const *)656 bool do_regex_search(BidiIterator first, BidiIterator last,
657                  match_results<BidiIterator, Allocator>& m,
658                  const u32regex& e,
659                  match_flag_type flags,
660                  BidiIterator base,
661                  boost::mpl::int_<1> const*)
662 {
663    typedef u8_to_u32_iterator<BidiIterator, UChar32>  conv_type;
664    typedef match_results<conv_type>                   match_type;
665    //typedef typename match_type::allocator_type        alloc_type;
666    match_type what;
667    bool result = ::boost::regex_search(conv_type(first, first, last), conv_type(last, first, last), what, e, flags, conv_type(base));
668    // copy results across to m:
669    if(result) copy_results(m, what, e.get_named_subs());
670    return result;
671 }
672 }
673 
674 template <class BidiIterator, class Allocator>
u32regex_search(BidiIterator first,BidiIterator last,match_results<BidiIterator,Allocator> & m,const u32regex & e,match_flag_type flags=match_default)675 inline bool u32regex_search(BidiIterator first, BidiIterator last,
676                  match_results<BidiIterator, Allocator>& m,
677                  const u32regex& e,
678                  match_flag_type flags = match_default)
679 {
680    return BOOST_REGEX_DETAIL_NS::do_regex_search(first, last, m, e, flags, first, static_cast<mpl::int_<sizeof(*first)> const*>(0));
681 }
682 template <class BidiIterator, class Allocator>
u32regex_search(BidiIterator first,BidiIterator last,match_results<BidiIterator,Allocator> & m,const u32regex & e,match_flag_type flags,BidiIterator base)683 inline bool u32regex_search(BidiIterator first, BidiIterator last,
684                  match_results<BidiIterator, Allocator>& m,
685                  const u32regex& e,
686                  match_flag_type flags,
687                  BidiIterator base)
688 {
689    return BOOST_REGEX_DETAIL_NS::do_regex_search(first, last, m, e, flags, base, static_cast<mpl::int_<sizeof(*first)> const*>(0));
690 }
u32regex_search(const UChar * p,match_results<const UChar * > & m,const u32regex & e,match_flag_type flags=match_default)691 inline bool u32regex_search(const UChar* p,
692                  match_results<const UChar*>& m,
693                  const u32regex& e,
694                  match_flag_type flags = match_default)
695 {
696    return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast<mpl::int_<2> const*>(0));
697 }
698 #if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX)
u32regex_search(const wchar_t * p,match_results<const wchar_t * > & m,const u32regex & e,match_flag_type flags=match_default)699 inline bool u32regex_search(const wchar_t* p,
700                  match_results<const wchar_t*>& m,
701                  const u32regex& e,
702                  match_flag_type flags = match_default)
703 {
704    return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
705 }
706 #endif
u32regex_search(const char * p,match_results<const char * > & m,const u32regex & e,match_flag_type flags=match_default)707 inline bool u32regex_search(const char* p,
708                  match_results<const char*>& m,
709                  const u32regex& e,
710                  match_flag_type flags = match_default)
711 {
712    return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
713 }
u32regex_search(const unsigned char * p,match_results<const unsigned char * > & m,const u32regex & e,match_flag_type flags=match_default)714 inline bool u32regex_search(const unsigned char* p,
715                  match_results<const unsigned char*>& m,
716                  const u32regex& e,
717                  match_flag_type flags = match_default)
718 {
719    return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
720 }
u32regex_search(const std::string & s,match_results<std::string::const_iterator> & m,const u32regex & e,match_flag_type flags=match_default)721 inline bool u32regex_search(const std::string& s,
722                         match_results<std::string::const_iterator>& m,
723                         const u32regex& e,
724                         match_flag_type flags = match_default)
725 {
726    return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<1> const*>(0));
727 }
728 #ifndef BOOST_NO_STD_WSTRING
u32regex_search(const std::wstring & s,match_results<std::wstring::const_iterator> & m,const u32regex & e,match_flag_type flags=match_default)729 inline bool u32regex_search(const std::wstring& s,
730                         match_results<std::wstring::const_iterator>& m,
731                         const u32regex& e,
732                         match_flag_type flags = match_default)
733 {
734    return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
735 }
736 #endif
u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString & s,match_results<const UChar * > & m,const u32regex & e,match_flag_type flags=match_default)737 inline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s,
738                         match_results<const UChar*>& m,
739                         const u32regex& e,
740                         match_flag_type flags = match_default)
741 {
742    return BOOST_REGEX_DETAIL_NS::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
743 }
744 template <class BidiIterator>
u32regex_search(BidiIterator first,BidiIterator last,const u32regex & e,match_flag_type flags=match_default)745 inline bool u32regex_search(BidiIterator first, BidiIterator last,
746                  const u32regex& e,
747                  match_flag_type flags = match_default)
748 {
749    match_results<BidiIterator> m;
750    return BOOST_REGEX_DETAIL_NS::do_regex_search(first, last, m, e, flags, first, static_cast<mpl::int_<sizeof(*first)> const*>(0));
751 }
u32regex_search(const UChar * p,const u32regex & e,match_flag_type flags=match_default)752 inline bool u32regex_search(const UChar* p,
753                  const u32regex& e,
754                  match_flag_type flags = match_default)
755 {
756    match_results<const UChar*> m;
757    return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast<mpl::int_<2> const*>(0));
758 }
759 #if !BOOST_REGEX_UCHAR_IS_WCHAR_T && !defined(BOOST_NO_WREGEX)
u32regex_search(const wchar_t * p,const u32regex & e,match_flag_type flags=match_default)760 inline bool u32regex_search(const wchar_t* p,
761                  const u32regex& e,
762                  match_flag_type flags = match_default)
763 {
764    match_results<const wchar_t*> m;
765    return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
766 }
767 #endif
u32regex_search(const char * p,const u32regex & e,match_flag_type flags=match_default)768 inline bool u32regex_search(const char* p,
769                  const u32regex& e,
770                  match_flag_type flags = match_default)
771 {
772    match_results<const char*> m;
773    return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
774 }
u32regex_search(const unsigned char * p,const u32regex & e,match_flag_type flags=match_default)775 inline bool u32regex_search(const unsigned char* p,
776                  const u32regex& e,
777                  match_flag_type flags = match_default)
778 {
779    match_results<const unsigned char*> m;
780    return BOOST_REGEX_DETAIL_NS::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
781 }
u32regex_search(const std::string & s,const u32regex & e,match_flag_type flags=match_default)782 inline bool u32regex_search(const std::string& s,
783                         const u32regex& e,
784                         match_flag_type flags = match_default)
785 {
786    match_results<std::string::const_iterator> m;
787    return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<1> const*>(0));
788 }
789 #ifndef BOOST_NO_STD_WSTRING
u32regex_search(const std::wstring & s,const u32regex & e,match_flag_type flags=match_default)790 inline bool u32regex_search(const std::wstring& s,
791                         const u32regex& e,
792                         match_flag_type flags = match_default)
793 {
794    match_results<std::wstring::const_iterator> m;
795    return BOOST_REGEX_DETAIL_NS::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
796 }
797 #endif
u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString & s,const u32regex & e,match_flag_type flags=match_default)798 inline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s,
799                         const u32regex& e,
800                         match_flag_type flags = match_default)
801 {
802    match_results<const UChar*> m;
803    return BOOST_REGEX_DETAIL_NS::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
804 }
805 
806 //
807 // overloads for regex_replace with utf-8 and utf-16 data types:
808 //
809 namespace BOOST_REGEX_DETAIL_NS{
810 template <class I>
811 inline std::pair< boost::u8_to_u32_iterator<I>, boost::u8_to_u32_iterator<I> >
make_utf32_seq(I i,I j,mpl::int_<1> const *)812    make_utf32_seq(I i, I j, mpl::int_<1> const*)
813 {
814    return std::pair< boost::u8_to_u32_iterator<I>, boost::u8_to_u32_iterator<I> >(boost::u8_to_u32_iterator<I>(i, i, j), boost::u8_to_u32_iterator<I>(j, i, j));
815 }
816 template <class I>
817 inline std::pair< boost::u16_to_u32_iterator<I>, boost::u16_to_u32_iterator<I> >
make_utf32_seq(I i,I j,mpl::int_<2> const *)818    make_utf32_seq(I i, I j, mpl::int_<2> const*)
819 {
820    return std::pair< boost::u16_to_u32_iterator<I>, boost::u16_to_u32_iterator<I> >(boost::u16_to_u32_iterator<I>(i, i, j), boost::u16_to_u32_iterator<I>(j, i, j));
821 }
822 template <class I>
823 inline std::pair< I, I >
make_utf32_seq(I i,I j,mpl::int_<4> const *)824    make_utf32_seq(I i, I j, mpl::int_<4> const*)
825 {
826    return std::pair< I, I >(i, j);
827 }
828 template <class charT>
829 inline std::pair< boost::u8_to_u32_iterator<const charT*>, boost::u8_to_u32_iterator<const charT*> >
make_utf32_seq(const charT * p,mpl::int_<1> const *)830    make_utf32_seq(const charT* p, mpl::int_<1> const*)
831 {
832    std::size_t len = std::strlen((const char*)p);
833    return std::pair< boost::u8_to_u32_iterator<const charT*>, boost::u8_to_u32_iterator<const charT*> >(boost::u8_to_u32_iterator<const charT*>(p, p, p+len), boost::u8_to_u32_iterator<const charT*>(p+len, p, p+len));
834 }
835 template <class charT>
836 inline std::pair< boost::u16_to_u32_iterator<const charT*>, boost::u16_to_u32_iterator<const charT*> >
make_utf32_seq(const charT * p,mpl::int_<2> const *)837    make_utf32_seq(const charT* p, mpl::int_<2> const*)
838 {
839    std::size_t len = u_strlen((const UChar*)p);
840    return std::pair< boost::u16_to_u32_iterator<const charT*>, boost::u16_to_u32_iterator<const charT*> >(boost::u16_to_u32_iterator<const charT*>(p, p, p + len), boost::u16_to_u32_iterator<const charT*>(p+len, p, p + len));
841 }
842 template <class charT>
843 inline std::pair< const charT*, const charT* >
make_utf32_seq(const charT * p,mpl::int_<4> const *)844    make_utf32_seq(const charT* p, mpl::int_<4> const*)
845 {
846    return std::pair< const charT*, const charT* >(p, p+icu_regex_traits::length((UChar32 const*)p));
847 }
848 template <class OutputIterator>
make_utf32_out(OutputIterator o,mpl::int_<4> const *)849 inline OutputIterator make_utf32_out(OutputIterator o, mpl::int_<4> const*)
850 {
851    return o;
852 }
853 template <class OutputIterator>
make_utf32_out(OutputIterator o,mpl::int_<2> const *)854 inline utf16_output_iterator<OutputIterator> make_utf32_out(OutputIterator o, mpl::int_<2> const*)
855 {
856    return o;
857 }
858 template <class OutputIterator>
make_utf32_out(OutputIterator o,mpl::int_<1> const *)859 inline utf8_output_iterator<OutputIterator> make_utf32_out(OutputIterator o, mpl::int_<1> const*)
860 {
861    return o;
862 }
863 
864 template <class OutputIterator, class I1, class I2>
865 OutputIterator do_regex_replace(OutputIterator out,
866                                  std::pair<I1, I1> const& in,
867                                  const u32regex& e,
868                                  const std::pair<I2, I2>& fmt,
869                                  match_flag_type flags
870                                  )
871 {
872    // unfortunately we have to copy the format string in order to pass in onward:
873    std::vector<UChar32> f;
874 #ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
875    f.assign(fmt.first, fmt.second);
876 #else
877    f.clear();
878    I2 pos = fmt.first;
879    while(pos != fmt.second)
880       f.push_back(*pos++);
881 #endif
882 
883    regex_iterator<I1, UChar32, icu_regex_traits> i(in.first, in.second, e, flags);
884    regex_iterator<I1, UChar32, icu_regex_traits> j;
885    if(i == j)
886    {
887       if(!(flags & regex_constants::format_no_copy))
888          out = BOOST_REGEX_DETAIL_NS::copy(in.first, in.second, out);
889    }
890    else
891    {
892       I1 last_m = in.first;
893       while(i != j)
894       {
895          if(!(flags & regex_constants::format_no_copy))
896             out = BOOST_REGEX_DETAIL_NS::copy(i->prefix().first, i->prefix().second, out);
897          if(f.size())
898             out = ::boost::BOOST_REGEX_DETAIL_NS::regex_format_imp(out, *i, &*f.begin(), &*f.begin() + f.size(), flags, e.get_traits());
899          else
900             out = ::boost::BOOST_REGEX_DETAIL_NS::regex_format_imp(out, *i, static_cast<UChar32 const*>(0), static_cast<UChar32 const*>(0), flags, e.get_traits());
901          last_m = (*i)[0].second;
902          if(flags & regex_constants::format_first_only)
903             break;
904          ++i;
905       }
906       if(!(flags & regex_constants::format_no_copy))
907          out = BOOST_REGEX_DETAIL_NS::copy(last_m, in.second, out);
908    }
909    return out;
910 }
911 template <class BaseIterator>
extract_output_base(const BaseIterator & b)912 inline const BaseIterator& extract_output_base(const BaseIterator& b)
913 {
914    return b;
915 }
916 template <class BaseIterator>
extract_output_base(const utf8_output_iterator<BaseIterator> & b)917 inline BaseIterator extract_output_base(const utf8_output_iterator<BaseIterator>& b)
918 {
919    return b.base();
920 }
921 template <class BaseIterator>
extract_output_base(const utf16_output_iterator<BaseIterator> & b)922 inline BaseIterator extract_output_base(const utf16_output_iterator<BaseIterator>& b)
923 {
924    return b.base();
925 }
926 }  // BOOST_REGEX_DETAIL_NS
927 
928 template <class OutputIterator, class BidirectionalIterator, class charT>
u32regex_replace(OutputIterator out,BidirectionalIterator first,BidirectionalIterator last,const u32regex & e,const charT * fmt,match_flag_type flags=match_default)929 inline OutputIterator u32regex_replace(OutputIterator out,
930                          BidirectionalIterator first,
931                          BidirectionalIterator last,
932                          const u32regex& e,
933                          const charT* fmt,
934                          match_flag_type flags = match_default)
935 {
936    return BOOST_REGEX_DETAIL_NS::extract_output_base
937     (
938       BOOST_REGEX_DETAIL_NS::do_regex_replace(
939          BOOST_REGEX_DETAIL_NS::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
940          BOOST_REGEX_DETAIL_NS::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
941          e,
942          BOOST_REGEX_DETAIL_NS::make_utf32_seq(fmt, static_cast<mpl::int_<sizeof(*fmt)> const*>(0)),
943          flags)
944       );
945 }
946 
947 template <class OutputIterator, class Iterator, class charT>
u32regex_replace(OutputIterator out,Iterator first,Iterator last,const u32regex & e,const std::basic_string<charT> & fmt,match_flag_type flags=match_default)948 inline OutputIterator u32regex_replace(OutputIterator out,
949                          Iterator first,
950                          Iterator last,
951                          const u32regex& e,
952                          const std::basic_string<charT>& fmt,
953                          match_flag_type flags = match_default)
954 {
955    return BOOST_REGEX_DETAIL_NS::extract_output_base
956     (
957       BOOST_REGEX_DETAIL_NS::do_regex_replace(
958          BOOST_REGEX_DETAIL_NS::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
959          BOOST_REGEX_DETAIL_NS::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
960          e,
961          BOOST_REGEX_DETAIL_NS::make_utf32_seq(fmt.begin(), fmt.end(), static_cast<mpl::int_<sizeof(charT)> const*>(0)),
962          flags)
963       );
964 }
965 
966 template <class OutputIterator, class Iterator>
u32regex_replace(OutputIterator out,Iterator first,Iterator last,const u32regex & e,const U_NAMESPACE_QUALIFIER UnicodeString & fmt,match_flag_type flags=match_default)967 inline OutputIterator u32regex_replace(OutputIterator out,
968                          Iterator first,
969                          Iterator last,
970                          const u32regex& e,
971                          const U_NAMESPACE_QUALIFIER UnicodeString& fmt,
972                          match_flag_type flags = match_default)
973 {
974    return BOOST_REGEX_DETAIL_NS::extract_output_base
975    (
976       BOOST_REGEX_DETAIL_NS::do_regex_replace(
977          BOOST_REGEX_DETAIL_NS::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
978          BOOST_REGEX_DETAIL_NS::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
979          e,
980          BOOST_REGEX_DETAIL_NS::make_utf32_seq(fmt.getBuffer(), fmt.getBuffer() + fmt.length(), static_cast<mpl::int_<2> const*>(0)),
981          flags)
982       );
983 }
984 
985 template <class charT>
u32regex_replace(const std::basic_string<charT> & s,const u32regex & e,const charT * fmt,match_flag_type flags=match_default)986 std::basic_string<charT> u32regex_replace(const std::basic_string<charT>& s,
987                          const u32regex& e,
988                          const charT* fmt,
989                          match_flag_type flags = match_default)
990 {
991    std::basic_string<charT> result;
992    BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<charT> > i(result);
993    u32regex_replace(i, s.begin(), s.end(), e, fmt, flags);
994    return result;
995 }
996 
997 template <class charT>
u32regex_replace(const std::basic_string<charT> & s,const u32regex & e,const std::basic_string<charT> & fmt,match_flag_type flags=match_default)998 std::basic_string<charT> u32regex_replace(const std::basic_string<charT>& s,
999                          const u32regex& e,
1000                          const std::basic_string<charT>& fmt,
1001                          match_flag_type flags = match_default)
1002 {
1003    std::basic_string<charT> result;
1004    BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<charT> > i(result);
1005    u32regex_replace(i, s.begin(), s.end(), e, fmt.c_str(), flags);
1006    return result;
1007 }
1008 
1009 namespace BOOST_REGEX_DETAIL_NS{
1010 
1011 class unicode_string_out_iterator
1012 {
1013    U_NAMESPACE_QUALIFIER UnicodeString* out;
1014 public:
unicode_string_out_iterator(U_NAMESPACE_QUALIFIER UnicodeString & s)1015    unicode_string_out_iterator(U_NAMESPACE_QUALIFIER UnicodeString& s) : out(&s) {}
operator ++()1016    unicode_string_out_iterator& operator++() { return *this; }
operator ++(int)1017    unicode_string_out_iterator& operator++(int) { return *this; }
operator *()1018    unicode_string_out_iterator& operator*() { return *this; }
operator =(UChar v)1019    unicode_string_out_iterator& operator=(UChar v)
1020    {
1021       *out += v;
1022       return *this;
1023    }
1024    typedef std::ptrdiff_t difference_type;
1025    typedef UChar value_type;
1026    typedef value_type* pointer;
1027    typedef value_type& reference;
1028    typedef std::output_iterator_tag iterator_category;
1029 };
1030 
1031 }
1032 
u32regex_replace(const U_NAMESPACE_QUALIFIER UnicodeString & s,const u32regex & e,const UChar * fmt,match_flag_type flags=match_default)1033 inline U_NAMESPACE_QUALIFIER UnicodeString u32regex_replace(const U_NAMESPACE_QUALIFIER UnicodeString& s,
1034                          const u32regex& e,
1035                          const UChar* fmt,
1036                          match_flag_type flags = match_default)
1037 {
1038    U_NAMESPACE_QUALIFIER UnicodeString result;
1039    BOOST_REGEX_DETAIL_NS::unicode_string_out_iterator i(result);
1040    u32regex_replace(i, s.getBuffer(), s.getBuffer()+s.length(), e, fmt, flags);
1041    return result;
1042 }
1043 
u32regex_replace(const U_NAMESPACE_QUALIFIER UnicodeString & s,const u32regex & e,const U_NAMESPACE_QUALIFIER UnicodeString & fmt,match_flag_type flags=match_default)1044 inline U_NAMESPACE_QUALIFIER UnicodeString u32regex_replace(const U_NAMESPACE_QUALIFIER UnicodeString& s,
1045                          const u32regex& e,
1046                          const U_NAMESPACE_QUALIFIER UnicodeString& fmt,
1047                          match_flag_type flags = match_default)
1048 {
1049    U_NAMESPACE_QUALIFIER UnicodeString result;
1050    BOOST_REGEX_DETAIL_NS::unicode_string_out_iterator i(result);
1051    BOOST_REGEX_DETAIL_NS::do_regex_replace(
1052          BOOST_REGEX_DETAIL_NS::make_utf32_out(i, static_cast<mpl::int_<2> const*>(0)),
1053          BOOST_REGEX_DETAIL_NS::make_utf32_seq(s.getBuffer(), s.getBuffer()+s.length(), static_cast<mpl::int_<2> const*>(0)),
1054          e,
1055          BOOST_REGEX_DETAIL_NS::make_utf32_seq(fmt.getBuffer(), fmt.getBuffer() + fmt.length(), static_cast<mpl::int_<2> const*>(0)),
1056          flags);
1057    return result;
1058 }
1059 
1060 } // namespace boost.
1061 
1062 #ifdef BOOST_MSVC
1063 #pragma warning (pop)
1064 #endif
1065 
1066 #include <boost/regex/v4/u32regex_iterator.hpp>
1067 #include <boost/regex/v4/u32regex_token_iterator.hpp>
1068 
1069 #endif
1070