icu.hpp 41 KB

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