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