| 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 | 
|---|