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