]> git.lyx.org Git - lyx.git/blob - boost/boost/regex/icu.hpp
Also display the info about BibTeX databases in the TeX info panel.
[lyx.git] / 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 re_detail{
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(re_detail::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)) ? re_detail::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)) ? re_detail::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    int toi(const char_type*& p1, const char_type* p2, int radix)const
156    {
157       return re_detail::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 = re_detail::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 re_detail::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::re_detail::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 re_detail{
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 re_detail::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 re_detail::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 re_detail::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 re_detail::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 re_detail::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 re_detail::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 re_detail::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 re_detail{
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)
401       {
402          out.set_first(in[i].first.base(), i);
403          out.set_second(in[i].second.base(), i);
404       }
405    }
406 }
407
408 template <class BidiIterator, class Allocator>
409 inline bool do_regex_match(BidiIterator first, BidiIterator last, 
410                  match_results<BidiIterator, Allocator>& m, 
411                  const u32regex& e, 
412                  match_flag_type flags,
413                  boost::mpl::int_<4> const*)
414 {
415    return ::boost::regex_match(first, last, m, e, flags);
416 }
417 template <class BidiIterator, class Allocator>
418 bool do_regex_match(BidiIterator first, BidiIterator last, 
419                  match_results<BidiIterator, Allocator>& m, 
420                  const u32regex& e, 
421                  match_flag_type flags,
422                  boost::mpl::int_<2> const*)
423 {
424    typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;
425    typedef match_results<conv_type>                   match_type;
426    typedef typename match_type::allocator_type        alloc_type;
427    match_type what;
428    bool result = ::boost::regex_match(conv_type(first, first, last), conv_type(last, first, last), what, e, flags);
429    // copy results across to m:
430    if(result) copy_results(m, what);
431    return result;
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_<1> const*)
439 {
440    typedef u8_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 } // namespace re_detail
450
451 template <class BidiIterator, class Allocator>
452 inline bool u32regex_match(BidiIterator first, BidiIterator last, 
453                  match_results<BidiIterator, Allocator>& m, 
454                  const u32regex& e, 
455                  match_flag_type flags = match_default)
456 {
457    return re_detail::do_regex_match(first, last, m, e, flags, static_cast<mpl::int_<sizeof(*first)> const*>(0));
458 }
459 inline bool u32regex_match(const UChar* p, 
460                  match_results<const UChar*>& m, 
461                  const u32regex& e, 
462                  match_flag_type flags = match_default)
463 {
464    return re_detail::do_regex_match(p, p+u_strlen(p), m, e, flags, static_cast<mpl::int_<2> const*>(0));
465 }
466 #if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(BOOST_NO_WREGEX)
467 inline bool u32regex_match(const wchar_t* p, 
468                  match_results<const wchar_t*>& m, 
469                  const u32regex& e, 
470                  match_flag_type flags = match_default)
471 {
472    return re_detail::do_regex_match(p, p+std::wcslen(p), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
473 }
474 #endif
475 inline bool u32regex_match(const char* p, 
476                  match_results<const char*>& m, 
477                  const u32regex& e, 
478                  match_flag_type flags = match_default)
479 {
480    return re_detail::do_regex_match(p, p+std::strlen(p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
481 }
482 inline bool u32regex_match(const unsigned char* p, 
483                  match_results<const unsigned char*>& m, 
484                  const u32regex& e, 
485                  match_flag_type flags = match_default)
486 {
487    return re_detail::do_regex_match(p, p+std::strlen((const char*)p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
488 }
489 inline bool u32regex_match(const std::string& s, 
490                         match_results<std::string::const_iterator>& m, 
491                         const u32regex& e, 
492                         match_flag_type flags = match_default)
493 {
494    return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<1> const*>(0));
495 }
496 #ifndef BOOST_NO_STD_WSTRING
497 inline bool u32regex_match(const std::wstring& s, 
498                         match_results<std::wstring::const_iterator>& m, 
499                         const u32regex& e, 
500                         match_flag_type flags = match_default)
501 {
502    return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
503 }
504 #endif
505 inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s, 
506                         match_results<const UChar*>& m, 
507                         const u32regex& e, 
508                         match_flag_type flags = match_default)
509 {
510    return re_detail::do_regex_match(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
511 }
512 //
513 // regex_match overloads that do not return what matched:
514 //
515 template <class BidiIterator>
516 inline bool u32regex_match(BidiIterator first, BidiIterator last, 
517                  const u32regex& e, 
518                  match_flag_type flags = match_default)
519 {
520    match_results<BidiIterator> m;
521    return re_detail::do_regex_match(first, last, m, e, flags, static_cast<mpl::int_<sizeof(*first)> const*>(0));
522 }
523 inline bool u32regex_match(const UChar* p, 
524                  const u32regex& e, 
525                  match_flag_type flags = match_default)
526 {
527    match_results<const UChar*> m;
528    return re_detail::do_regex_match(p, p+u_strlen(p), m, e, flags, static_cast<mpl::int_<2> const*>(0));
529 }
530 #if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(BOOST_NO_WREGEX)
531 inline bool u32regex_match(const wchar_t* p, 
532                  const u32regex& e, 
533                  match_flag_type flags = match_default)
534 {
535    match_results<const wchar_t*> m;
536    return re_detail::do_regex_match(p, p+std::wcslen(p), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
537 }
538 #endif
539 inline bool u32regex_match(const char* p, 
540                  const u32regex& e, 
541                  match_flag_type flags = match_default)
542 {
543    match_results<const char*> m;
544    return re_detail::do_regex_match(p, p+std::strlen(p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
545 }
546 inline bool u32regex_match(const unsigned char* p, 
547                  const u32regex& e, 
548                  match_flag_type flags = match_default)
549 {
550    match_results<const unsigned char*> m;
551    return re_detail::do_regex_match(p, p+std::strlen((const char*)p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
552 }
553 inline bool u32regex_match(const std::string& s, 
554                         const u32regex& e, 
555                         match_flag_type flags = match_default)
556 {
557    match_results<std::string::const_iterator> m;
558    return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<1> const*>(0));
559 }
560 #ifndef BOOST_NO_STD_WSTRING
561 inline bool u32regex_match(const std::wstring& s, 
562                         const u32regex& e, 
563                         match_flag_type flags = match_default)
564 {
565    match_results<std::wstring::const_iterator> m;
566    return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
567 }
568 #endif
569 inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s, 
570                         const u32regex& e, 
571                         match_flag_type flags = match_default)
572 {
573    match_results<const UChar*> m;
574    return re_detail::do_regex_match(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
575 }
576
577 //
578 // regex_search overloads that widen the character type as appropriate:
579 //
580 namespace re_detail{
581 template <class BidiIterator, class Allocator>
582 inline bool do_regex_search(BidiIterator first, BidiIterator last, 
583                  match_results<BidiIterator, Allocator>& m, 
584                  const u32regex& e, 
585                  match_flag_type flags,
586                  BidiIterator base,
587                  boost::mpl::int_<4> const*)
588 {
589    return ::boost::regex_search(first, last, m, e, flags, base);
590 }
591 template <class BidiIterator, class Allocator>
592 bool do_regex_search(BidiIterator first, BidiIterator last, 
593                  match_results<BidiIterator, Allocator>& m, 
594                  const u32regex& e, 
595                  match_flag_type flags,
596                  BidiIterator base,
597                  boost::mpl::int_<2> const*)
598 {
599    typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;
600    typedef match_results<conv_type>                   match_type;
601    typedef typename match_type::allocator_type        alloc_type;
602    match_type what;
603    bool result = ::boost::regex_search(conv_type(first, first, last), conv_type(last, first, last), what, e, flags, conv_type(base));
604    // copy results across to m:
605    if(result) copy_results(m, what);
606    return result;
607 }
608 template <class BidiIterator, class Allocator>
609 bool do_regex_search(BidiIterator first, BidiIterator last, 
610                  match_results<BidiIterator, Allocator>& m, 
611                  const u32regex& e, 
612                  match_flag_type flags,
613                  BidiIterator base,
614                  boost::mpl::int_<1> const*)
615 {
616    typedef u8_to_u32_iterator<BidiIterator, UChar32>  conv_type;
617    typedef match_results<conv_type>                   match_type;
618    typedef typename match_type::allocator_type        alloc_type;
619    match_type what;
620    bool result = ::boost::regex_search(conv_type(first, first, last), conv_type(last, first, last), what, e, flags, conv_type(base));
621    // copy results across to m:
622    if(result) copy_results(m, what);
623    return result;
624 }
625 }
626
627 template <class BidiIterator, class Allocator>
628 inline bool u32regex_search(BidiIterator first, BidiIterator last, 
629                  match_results<BidiIterator, Allocator>& m, 
630                  const u32regex& e, 
631                  match_flag_type flags = match_default)
632 {
633    return re_detail::do_regex_search(first, last, m, e, flags, first, static_cast<mpl::int_<sizeof(*first)> const*>(0));
634 }
635 template <class BidiIterator, class Allocator>
636 inline bool u32regex_search(BidiIterator first, BidiIterator last, 
637                  match_results<BidiIterator, Allocator>& m, 
638                  const u32regex& e, 
639                  match_flag_type flags,
640                  BidiIterator base)
641 {
642    return re_detail::do_regex_search(first, last, m, e, flags, base, static_cast<mpl::int_<sizeof(*first)> const*>(0));
643 }
644 inline bool u32regex_search(const UChar* p, 
645                  match_results<const UChar*>& m, 
646                  const u32regex& e, 
647                  match_flag_type flags = match_default)
648 {
649    return re_detail::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast<mpl::int_<2> const*>(0));
650 }
651 #if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(BOOST_NO_WREGEX)
652 inline bool u32regex_search(const wchar_t* p, 
653                  match_results<const wchar_t*>& m, 
654                  const u32regex& e, 
655                  match_flag_type flags = match_default)
656 {
657    return re_detail::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
658 }
659 #endif
660 inline bool u32regex_search(const char* p, 
661                  match_results<const char*>& m, 
662                  const u32regex& e, 
663                  match_flag_type flags = match_default)
664 {
665    return re_detail::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
666 }
667 inline bool u32regex_search(const unsigned char* p, 
668                  match_results<const unsigned char*>& m, 
669                  const u32regex& e, 
670                  match_flag_type flags = match_default)
671 {
672    return re_detail::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
673 }
674 inline bool u32regex_search(const std::string& s, 
675                         match_results<std::string::const_iterator>& m, 
676                         const u32regex& e, 
677                         match_flag_type flags = match_default)
678 {
679    return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<1> const*>(0));
680 }
681 #ifndef BOOST_NO_STD_WSTRING
682 inline bool u32regex_search(const std::wstring& s, 
683                         match_results<std::wstring::const_iterator>& m, 
684                         const u32regex& e, 
685                         match_flag_type flags = match_default)
686 {
687    return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
688 }
689 #endif
690 inline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s, 
691                         match_results<const UChar*>& m, 
692                         const u32regex& e, 
693                         match_flag_type flags = match_default)
694 {
695    return re_detail::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
696 }
697 template <class BidiIterator>
698 inline bool u32regex_search(BidiIterator first, BidiIterator last, 
699                  const u32regex& e, 
700                  match_flag_type flags = match_default)
701 {
702    match_results<BidiIterator> m;
703    return re_detail::do_regex_search(first, last, m, e, flags, first, static_cast<mpl::int_<sizeof(*first)> const*>(0));
704 }
705 inline bool u32regex_search(const UChar* p, 
706                  const u32regex& e, 
707                  match_flag_type flags = match_default)
708 {
709    match_results<const UChar*> m;
710    return re_detail::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast<mpl::int_<2> const*>(0));
711 }
712 #if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(BOOST_NO_WREGEX)
713 inline bool u32regex_search(const wchar_t* p, 
714                  const u32regex& e, 
715                  match_flag_type flags = match_default)
716 {
717    match_results<const wchar_t*> m;
718    return re_detail::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
719 }
720 #endif
721 inline bool u32regex_search(const char* p, 
722                  const u32regex& e, 
723                  match_flag_type flags = match_default)
724 {
725    match_results<const char*> m;
726    return re_detail::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
727 }
728 inline bool u32regex_search(const unsigned char* p, 
729                  const u32regex& e, 
730                  match_flag_type flags = match_default)
731 {
732    match_results<const unsigned char*> m;
733    return re_detail::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
734 }
735 inline bool u32regex_search(const std::string& s, 
736                         const u32regex& e, 
737                         match_flag_type flags = match_default)
738 {
739    match_results<std::string::const_iterator> m;
740    return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<1> const*>(0));
741 }
742 #ifndef BOOST_NO_STD_WSTRING
743 inline bool u32regex_search(const std::wstring& s, 
744                         const u32regex& e, 
745                         match_flag_type flags = match_default)
746 {
747    match_results<std::wstring::const_iterator> m;
748    return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
749 }
750 #endif
751 inline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s, 
752                         const u32regex& e, 
753                         match_flag_type flags = match_default)
754 {
755    match_results<const UChar*> m;
756    return re_detail::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
757 }
758
759 //
760 // overloads for regex_replace with utf-8 and utf-16 data types:
761 //
762 namespace re_detail{
763 template <class I>
764 inline std::pair< boost::u8_to_u32_iterator<I>, boost::u8_to_u32_iterator<I> >
765    make_utf32_seq(I i, I j, mpl::int_<1> const*)
766 {
767    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));
768 }
769 template <class I>
770 inline std::pair< boost::u16_to_u32_iterator<I>, boost::u16_to_u32_iterator<I> >
771    make_utf32_seq(I i, I j, mpl::int_<2> const*)
772 {
773    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));
774 }
775 template <class I>
776 inline std::pair< I, I >
777    make_utf32_seq(I i, I j, mpl::int_<4> const*)
778 {
779    return std::pair< I, I >(i, j);
780 }
781 template <class charT>
782 inline std::pair< boost::u8_to_u32_iterator<const charT*>, boost::u8_to_u32_iterator<const charT*> >
783    make_utf32_seq(const charT* p, mpl::int_<1> const*)
784 {
785    std::size_t len = std::strlen((const char*)p);
786    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));
787 }
788 template <class charT>
789 inline std::pair< boost::u16_to_u32_iterator<const charT*>, boost::u16_to_u32_iterator<const charT*> >
790    make_utf32_seq(const charT* p, mpl::int_<2> const*)
791 {
792    std::size_t len = u_strlen((const UChar*)p);
793    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));
794 }
795 template <class charT>
796 inline std::pair< const charT*, const charT* >
797    make_utf32_seq(const charT* p, mpl::int_<4> const*)
798 {
799    return std::pair< const charT*, const charT* >(p, p+icu_regex_traits::length((UChar32 const*)p));
800 }
801 template <class OutputIterator>
802 inline OutputIterator make_utf32_out(OutputIterator o, mpl::int_<4> const*)
803 {
804    return o;
805 }
806 template <class OutputIterator>
807 inline utf16_output_iterator<OutputIterator> make_utf32_out(OutputIterator o, mpl::int_<2> const*)
808 {
809    return o;
810 }
811 template <class OutputIterator>
812 inline utf8_output_iterator<OutputIterator> make_utf32_out(OutputIterator o, mpl::int_<1> const*)
813 {
814    return o;
815 }
816
817 template <class OutputIterator, class I1, class I2>
818 OutputIterator do_regex_replace(OutputIterator out,
819                                  std::pair<I1, I1> const& in,
820                                  const u32regex& e, 
821                                  const std::pair<I2, I2>& fmt, 
822                                  match_flag_type flags
823                                  )
824 {
825    // unfortunately we have to copy the format string in order to pass in onward:
826    std::vector<UChar32> f;
827 #ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
828    f.assign(fmt.first, fmt.second);
829 #else
830    f.clear();
831    I2 pos = fmt.first;
832    while(pos != fmt.second)
833       f.push_back(*pos++);
834 #endif
835    
836    regex_iterator<I1, UChar32, icu_regex_traits> i(in.first, in.second, e, flags);
837    regex_iterator<I1, UChar32, icu_regex_traits> j;
838    if(i == j)
839    {
840       if(!(flags & regex_constants::format_no_copy))
841          out = re_detail::copy(in.first, in.second, out);
842    }
843    else
844    {
845       I1 last_m = in.first;
846       while(i != j)
847       {
848          if(!(flags & regex_constants::format_no_copy))
849             out = re_detail::copy(i->prefix().first, i->prefix().second, out); 
850          if(f.size())
851             out = ::boost::re_detail::regex_format_imp(out, *i, &*f.begin(), &*f.begin() + f.size(), flags, e.get_traits());
852          else
853             out = ::boost::re_detail::regex_format_imp(out, *i, static_cast<UChar32 const*>(0), static_cast<UChar32 const*>(0), flags, e.get_traits());
854          last_m = (*i)[0].second;
855          if(flags & regex_constants::format_first_only)
856             break;
857          ++i;
858       }
859       if(!(flags & regex_constants::format_no_copy))
860          out = re_detail::copy(last_m, in.second, out);
861    }
862    return out;
863 }
864 template <class BaseIterator>
865 inline const BaseIterator& extract_output_base(const BaseIterator& b)
866 {
867    return b;
868 }
869 template <class BaseIterator>
870 inline BaseIterator extract_output_base(const utf8_output_iterator<BaseIterator>& b)
871 {
872    return b.base();
873 }
874 template <class BaseIterator>
875 inline BaseIterator extract_output_base(const utf16_output_iterator<BaseIterator>& b)
876 {
877    return b.base();
878 }
879 }  // re_detail
880
881 template <class OutputIterator, class BidirectionalIterator, class charT>
882 inline OutputIterator u32regex_replace(OutputIterator out,
883                          BidirectionalIterator first,
884                          BidirectionalIterator last,
885                          const u32regex& e, 
886                          const charT* fmt, 
887                          match_flag_type flags = match_default)
888 {
889    return re_detail::extract_output_base
890 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
891    <OutputIterator>
892 #endif
893     (
894       re_detail::do_regex_replace(
895          re_detail::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
896          re_detail::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
897          e,
898          re_detail::make_utf32_seq(fmt, static_cast<mpl::int_<sizeof(*fmt)> const*>(0)),
899          flags)
900       );
901 }
902
903 template <class OutputIterator, class Iterator, class charT>
904 inline OutputIterator u32regex_replace(OutputIterator out,
905                          Iterator first,
906                          Iterator last,
907                          const u32regex& e, 
908                          const std::basic_string<charT>& fmt,
909                          match_flag_type flags = match_default)
910 {
911    return re_detail::extract_output_base
912 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
913    <OutputIterator>
914 #endif
915     (
916       re_detail::do_regex_replace(
917          re_detail::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
918          re_detail::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
919          e,
920          re_detail::make_utf32_seq(fmt.begin(), fmt.end(), static_cast<mpl::int_<sizeof(charT)> const*>(0)),
921          flags)
922       );
923 }
924
925 template <class OutputIterator, class Iterator>
926 inline OutputIterator u32regex_replace(OutputIterator out,
927                          Iterator first,
928                          Iterator last,
929                          const u32regex& e, 
930                          const U_NAMESPACE_QUALIFIER UnicodeString& fmt,
931                          match_flag_type flags = match_default)
932 {
933    return re_detail::extract_output_base
934 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
935    <OutputIterator>
936 #endif
937    (
938       re_detail::do_regex_replace(
939          re_detail::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
940          re_detail::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
941          e,
942          re_detail::make_utf32_seq(fmt.getBuffer(), fmt.getBuffer() + fmt.length(), static_cast<mpl::int_<2> const*>(0)),
943          flags)
944       );
945 }
946
947 template <class charT>
948 std::basic_string<charT> u32regex_replace(const std::basic_string<charT>& s,
949                          const u32regex& e, 
950                          const charT* fmt,
951                          match_flag_type flags = match_default)
952 {
953    std::basic_string<charT> result;
954    re_detail::string_out_iterator<std::basic_string<charT> > i(result);
955    u32regex_replace(i, s.begin(), s.end(), e, fmt, flags);
956    return result;
957 }
958
959 template <class charT>
960 std::basic_string<charT> u32regex_replace(const std::basic_string<charT>& s,
961                          const u32regex& e, 
962                          const std::basic_string<charT>& fmt,
963                          match_flag_type flags = match_default)
964 {
965    std::basic_string<charT> result;
966    re_detail::string_out_iterator<std::basic_string<charT> > i(result);
967    u32regex_replace(i, s.begin(), s.end(), e, fmt.c_str(), flags);
968    return result;
969 }
970
971 namespace re_detail{
972
973 class unicode_string_out_iterator
974 {
975    U_NAMESPACE_QUALIFIER UnicodeString* out;
976 public:
977    unicode_string_out_iterator(U_NAMESPACE_QUALIFIER UnicodeString& s) : out(&s) {}
978    unicode_string_out_iterator& operator++() { return *this; }
979    unicode_string_out_iterator& operator++(int) { return *this; }
980    unicode_string_out_iterator& operator*() { return *this; }
981    unicode_string_out_iterator& operator=(UChar v) 
982    { 
983       *out += v; 
984       return *this; 
985    }
986    typedef std::ptrdiff_t difference_type;
987    typedef UChar value_type;
988    typedef value_type* pointer;
989    typedef value_type& reference;
990    typedef std::output_iterator_tag iterator_category;
991 };
992
993 }
994
995 inline U_NAMESPACE_QUALIFIER UnicodeString u32regex_replace(const U_NAMESPACE_QUALIFIER UnicodeString& s,
996                          const u32regex& e, 
997                          const UChar* fmt,
998                          match_flag_type flags = match_default)
999 {
1000    U_NAMESPACE_QUALIFIER UnicodeString result;
1001    re_detail::unicode_string_out_iterator i(result);
1002    u32regex_replace(i, s.getBuffer(), s.getBuffer()+s.length(), e, fmt, flags);
1003    return result;
1004 }
1005
1006 inline U_NAMESPACE_QUALIFIER UnicodeString u32regex_replace(const U_NAMESPACE_QUALIFIER UnicodeString& s,
1007                          const u32regex& e, 
1008                          const U_NAMESPACE_QUALIFIER UnicodeString& fmt,
1009                          match_flag_type flags = match_default)
1010 {
1011    U_NAMESPACE_QUALIFIER UnicodeString result;
1012    re_detail::unicode_string_out_iterator i(result);
1013    re_detail::do_regex_replace(
1014          re_detail::make_utf32_out(i, static_cast<mpl::int_<2> const*>(0)),
1015          re_detail::make_utf32_seq(s.getBuffer(), s.getBuffer()+s.length(), static_cast<mpl::int_<2> const*>(0)),
1016          e,
1017          re_detail::make_utf32_seq(fmt.getBuffer(), fmt.getBuffer() + fmt.length(), static_cast<mpl::int_<2> const*>(0)),
1018          flags);
1019    return result;
1020 }
1021
1022 } // namespace boost.
1023
1024 #ifdef BOOST_MSVC
1025 #pragma warning (pop)
1026 #endif
1027
1028 #include <boost/regex/v4/u32regex_iterator.hpp>
1029 #include <boost/regex/v4/u32regex_token_iterator.hpp>
1030
1031 #endif