sub_match.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. /*
  2. *
  3. * Copyright (c) 1998-2002
  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 sub_match.cpp
  14. * VERSION see <boost/version.hpp>
  15. * DESCRIPTION: Declares template class sub_match.
  16. */
  17. #ifndef BOOST_REGEX_V4_SUB_MATCH_HPP
  18. #define BOOST_REGEX_V4_SUB_MATCH_HPP
  19. #ifdef BOOST_MSVC
  20. #pragma warning(push)
  21. #pragma warning(disable: 4103)
  22. #endif
  23. #ifdef BOOST_HAS_ABI_HEADERS
  24. # include BOOST_ABI_PREFIX
  25. #endif
  26. #ifdef BOOST_MSVC
  27. #pragma warning(pop)
  28. #endif
  29. namespace boost{
  30. template <class BidiIterator>
  31. struct sub_match : public std::pair<BidiIterator, BidiIterator>
  32. {
  33. typedef typename re_detail::regex_iterator_traits<BidiIterator>::value_type value_type;
  34. #if defined(BOOST_NO_STD_ITERATOR_TRAITS) || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
  35. typedef std::ptrdiff_t difference_type;
  36. #else
  37. typedef typename re_detail::regex_iterator_traits<BidiIterator>::difference_type difference_type;
  38. #endif
  39. typedef BidiIterator iterator_type;
  40. typedef BidiIterator iterator;
  41. typedef BidiIterator const_iterator;
  42. bool matched;
  43. sub_match() : std::pair<BidiIterator, BidiIterator>(), matched(false) {}
  44. sub_match(BidiIterator i) : std::pair<BidiIterator, BidiIterator>(i, i), matched(false) {}
  45. #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
  46. && !BOOST_WORKAROUND(BOOST_MSVC, < 1310)\
  47. && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)\
  48. && !BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
  49. template <class T, class A>
  50. operator std::basic_string<value_type, T, A> ()const
  51. {
  52. return std::basic_string<value_type, T, A>(this->first, this->second);
  53. }
  54. #else
  55. operator std::basic_string<value_type> ()const
  56. {
  57. return str();
  58. }
  59. #endif
  60. difference_type BOOST_REGEX_CALL length()const
  61. {
  62. difference_type n = ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second);
  63. return n;
  64. }
  65. std::basic_string<value_type> str()const
  66. {
  67. std::basic_string<value_type> result;
  68. std::size_t len = ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second);
  69. result.reserve(len);
  70. BidiIterator i = this->first;
  71. while(i != this->second)
  72. {
  73. result.append(1, *i);
  74. ++i;
  75. }
  76. return result;
  77. }
  78. int compare(const sub_match& s)const
  79. {
  80. if(matched != s.matched)
  81. return static_cast<int>(matched) - static_cast<int>(s.matched);
  82. return str().compare(s.str());
  83. }
  84. int compare(const std::basic_string<value_type>& s)const
  85. {
  86. return str().compare(s);
  87. }
  88. int compare(const value_type* p)const
  89. {
  90. return str().compare(p);
  91. }
  92. bool operator==(const sub_match& that)const
  93. { return compare(that) == 0; }
  94. bool BOOST_REGEX_CALL operator !=(const sub_match& that)const
  95. { return compare(that) != 0; }
  96. bool operator<(const sub_match& that)const
  97. { return compare(that) < 0; }
  98. bool operator>(const sub_match& that)const
  99. { return compare(that) > 0; }
  100. bool operator<=(const sub_match& that)const
  101. { return compare(that) <= 0; }
  102. bool operator>=(const sub_match& that)const
  103. { return compare(that) >= 0; }
  104. #ifdef BOOST_REGEX_MATCH_EXTRA
  105. typedef std::vector<sub_match<BidiIterator> > capture_sequence_type;
  106. const capture_sequence_type& captures()const
  107. {
  108. if(!m_captures)
  109. m_captures.reset(new capture_sequence_type());
  110. return *m_captures;
  111. }
  112. //
  113. // Private implementation API: DO NOT USE!
  114. //
  115. capture_sequence_type& get_captures()const
  116. {
  117. if(!m_captures)
  118. m_captures.reset(new capture_sequence_type());
  119. return *m_captures;
  120. }
  121. private:
  122. mutable boost::scoped_ptr<capture_sequence_type> m_captures;
  123. public:
  124. #endif
  125. sub_match(const sub_match& that, bool
  126. #ifdef BOOST_REGEX_MATCH_EXTRA
  127. deep_copy
  128. #endif
  129. = true
  130. )
  131. : std::pair<BidiIterator, BidiIterator>(that),
  132. matched(that.matched)
  133. {
  134. #ifdef BOOST_REGEX_MATCH_EXTRA
  135. if(that.m_captures)
  136. if(deep_copy)
  137. m_captures.reset(new capture_sequence_type(*(that.m_captures)));
  138. #endif
  139. }
  140. sub_match& operator=(const sub_match& that)
  141. {
  142. this->first = that.first;
  143. this->second = that.second;
  144. matched = that.matched;
  145. #ifdef BOOST_REGEX_MATCH_EXTRA
  146. if(that.m_captures)
  147. get_captures() = *(that.m_captures);
  148. #endif
  149. return *this;
  150. }
  151. #ifdef BOOST_OLD_REGEX_H
  152. //
  153. // the following are deprecated, do not use!!
  154. //
  155. operator int()const;
  156. operator unsigned int()const;
  157. operator short()const
  158. {
  159. return (short)(int)(*this);
  160. }
  161. operator unsigned short()const
  162. {
  163. return (unsigned short)(unsigned int)(*this);
  164. }
  165. #endif
  166. };
  167. typedef sub_match<const char*> csub_match;
  168. typedef sub_match<std::string::const_iterator> ssub_match;
  169. #ifndef BOOST_NO_WREGEX
  170. typedef sub_match<const wchar_t*> wcsub_match;
  171. typedef sub_match<std::wstring::const_iterator> wssub_match;
  172. #endif
  173. // comparison to std::basic_string<> part 1:
  174. template <class RandomAccessIterator, class traits, class Allocator>
  175. inline bool operator == (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
  176. const sub_match<RandomAccessIterator>& m)
  177. { return s.compare(m.str()) == 0; }
  178. template <class RandomAccessIterator, class traits, class Allocator>
  179. inline bool operator != (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
  180. const sub_match<RandomAccessIterator>& m)
  181. { return s.compare(m.str()) != 0; }
  182. template <class RandomAccessIterator, class traits, class Allocator>
  183. inline bool operator < (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
  184. const sub_match<RandomAccessIterator>& m)
  185. { return s.compare(m.str()) < 0; }
  186. template <class RandomAccessIterator, class traits, class Allocator>
  187. inline bool operator <= (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
  188. const sub_match<RandomAccessIterator>& m)
  189. { return s.compare(m.str()) <= 0; }
  190. template <class RandomAccessIterator, class traits, class Allocator>
  191. inline bool operator >= (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
  192. const sub_match<RandomAccessIterator>& m)
  193. { return s.compare(m.str()) >= 0; }
  194. template <class RandomAccessIterator, class traits, class Allocator>
  195. inline bool operator > (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
  196. const sub_match<RandomAccessIterator>& m)
  197. { return s.compare(m.str()) > 0; }
  198. // comparison to std::basic_string<> part 2:
  199. template <class RandomAccessIterator, class traits, class Allocator>
  200. inline bool operator == (const sub_match<RandomAccessIterator>& m,
  201. const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
  202. { return m.str().compare(s) == 0; }
  203. template <class RandomAccessIterator, class traits, class Allocator>
  204. inline bool operator != (const sub_match<RandomAccessIterator>& m,
  205. const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
  206. { return m.str().compare(s) != 0; }
  207. template <class RandomAccessIterator, class traits, class Allocator>
  208. inline bool operator < (const sub_match<RandomAccessIterator>& m,
  209. const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
  210. { return m.str().compare(s) < 0; }
  211. template <class RandomAccessIterator, class traits, class Allocator>
  212. inline bool operator > (const sub_match<RandomAccessIterator>& m,
  213. const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
  214. { return m.str().compare(s) > 0; }
  215. template <class RandomAccessIterator, class traits, class Allocator>
  216. inline bool operator <= (const sub_match<RandomAccessIterator>& m,
  217. const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
  218. { return m.str().compare(s) <= 0; }
  219. template <class RandomAccessIterator, class traits, class Allocator>
  220. inline bool operator >= (const sub_match<RandomAccessIterator>& m,
  221. const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
  222. { return m.str().compare(s) >= 0; }
  223. // comparison to const charT* part 1:
  224. template <class RandomAccessIterator>
  225. inline bool operator == (const sub_match<RandomAccessIterator>& m,
  226. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
  227. { return m.str().compare(s) == 0; }
  228. template <class RandomAccessIterator>
  229. inline bool operator != (const sub_match<RandomAccessIterator>& m,
  230. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
  231. { return m.str().compare(s) != 0; }
  232. template <class RandomAccessIterator>
  233. inline bool operator > (const sub_match<RandomAccessIterator>& m,
  234. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
  235. { return m.str().compare(s) > 0; }
  236. template <class RandomAccessIterator>
  237. inline bool operator < (const sub_match<RandomAccessIterator>& m,
  238. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
  239. { return m.str().compare(s) < 0; }
  240. template <class RandomAccessIterator>
  241. inline bool operator >= (const sub_match<RandomAccessIterator>& m,
  242. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
  243. { return m.str().compare(s) >= 0; }
  244. template <class RandomAccessIterator>
  245. inline bool operator <= (const sub_match<RandomAccessIterator>& m,
  246. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s)
  247. { return m.str().compare(s) <= 0; }
  248. // comparison to const charT* part 2:
  249. template <class RandomAccessIterator>
  250. inline bool operator == (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
  251. const sub_match<RandomAccessIterator>& m)
  252. { return m.str().compare(s) == 0; }
  253. template <class RandomAccessIterator>
  254. inline bool operator != (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
  255. const sub_match<RandomAccessIterator>& m)
  256. { return m.str().compare(s) != 0; }
  257. template <class RandomAccessIterator>
  258. inline bool operator < (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
  259. const sub_match<RandomAccessIterator>& m)
  260. { return m.str().compare(s) > 0; }
  261. template <class RandomAccessIterator>
  262. inline bool operator > (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
  263. const sub_match<RandomAccessIterator>& m)
  264. { return m.str().compare(s) < 0; }
  265. template <class RandomAccessIterator>
  266. inline bool operator <= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
  267. const sub_match<RandomAccessIterator>& m)
  268. { return m.str().compare(s) >= 0; }
  269. template <class RandomAccessIterator>
  270. inline bool operator >= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
  271. const sub_match<RandomAccessIterator>& m)
  272. { return m.str().compare(s) <= 0; }
  273. // comparison to const charT& part 1:
  274. template <class RandomAccessIterator>
  275. inline bool operator == (const sub_match<RandomAccessIterator>& m,
  276. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
  277. { return m.str().compare(0, m.length(), &s, 1) == 0; }
  278. template <class RandomAccessIterator>
  279. inline bool operator != (const sub_match<RandomAccessIterator>& m,
  280. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
  281. { return m.str().compare(0, m.length(), &s, 1) != 0; }
  282. template <class RandomAccessIterator>
  283. inline bool operator > (const sub_match<RandomAccessIterator>& m,
  284. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
  285. { return m.str().compare(0, m.length(), &s, 1) > 0; }
  286. template <class RandomAccessIterator>
  287. inline bool operator < (const sub_match<RandomAccessIterator>& m,
  288. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
  289. { return m.str().compare(0, m.length(), &s, 1) < 0; }
  290. template <class RandomAccessIterator>
  291. inline bool operator >= (const sub_match<RandomAccessIterator>& m,
  292. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
  293. { return m.str().compare(0, m.length(), &s, 1) >= 0; }
  294. template <class RandomAccessIterator>
  295. inline bool operator <= (const sub_match<RandomAccessIterator>& m,
  296. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
  297. { return m.str().compare(0, m.length(), &s, 1) <= 0; }
  298. // comparison to const charT* part 2:
  299. template <class RandomAccessIterator>
  300. inline bool operator == (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
  301. const sub_match<RandomAccessIterator>& m)
  302. { return m.str().compare(0, m.length(), &s, 1) == 0; }
  303. template <class RandomAccessIterator>
  304. inline bool operator != (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
  305. const sub_match<RandomAccessIterator>& m)
  306. { return m.str().compare(0, m.length(), &s, 1) != 0; }
  307. template <class RandomAccessIterator>
  308. inline bool operator < (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
  309. const sub_match<RandomAccessIterator>& m)
  310. { return m.str().compare(0, m.length(), &s, 1) > 0; }
  311. template <class RandomAccessIterator>
  312. inline bool operator > (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
  313. const sub_match<RandomAccessIterator>& m)
  314. { return m.str().compare(0, m.length(), &s, 1) < 0; }
  315. template <class RandomAccessIterator>
  316. inline bool operator <= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
  317. const sub_match<RandomAccessIterator>& m)
  318. { return m.str().compare(0, m.length(), &s, 1) >= 0; }
  319. template <class RandomAccessIterator>
  320. inline bool operator >= (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
  321. const sub_match<RandomAccessIterator>& m)
  322. { return m.str().compare(0, m.length(), &s, 1) <= 0; }
  323. // addition operators:
  324. template <class RandomAccessIterator, class traits, class Allocator>
  325. inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>
  326. operator + (const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s,
  327. const sub_match<RandomAccessIterator>& m)
  328. {
  329. std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;
  330. result.reserve(s.size() + m.length() + 1);
  331. return result.append(s).append(m.first, m.second);
  332. }
  333. template <class RandomAccessIterator, class traits, class Allocator>
  334. inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>
  335. operator + (const sub_match<RandomAccessIterator>& m,
  336. const std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator>& s)
  337. {
  338. std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type, traits, Allocator> result;
  339. result.reserve(s.size() + m.length() + 1);
  340. return result.append(m.first, m.second).append(s);
  341. }
  342. #if !(defined(__GNUC__) && defined(BOOST_NO_STD_LOCALE))
  343. template <class RandomAccessIterator>
  344. inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
  345. operator + (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
  346. const sub_match<RandomAccessIterator>& m)
  347. {
  348. std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
  349. result.reserve(std::char_traits<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);
  350. return result.append(s).append(m.first, m.second);
  351. }
  352. template <class RandomAccessIterator>
  353. inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
  354. operator + (const sub_match<RandomAccessIterator>& m,
  355. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const * s)
  356. {
  357. std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
  358. result.reserve(std::char_traits<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>::length(s) + m.length() + 1);
  359. return result.append(m.first, m.second).append(s);
  360. }
  361. #else
  362. // worwaround versions:
  363. template <class RandomAccessIterator>
  364. inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
  365. operator + (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const* s,
  366. const sub_match<RandomAccessIterator>& m)
  367. {
  368. return s + m.str();
  369. }
  370. template <class RandomAccessIterator>
  371. inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
  372. operator + (const sub_match<RandomAccessIterator>& m,
  373. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const * s)
  374. {
  375. return m.str() + s;
  376. }
  377. #endif
  378. template <class RandomAccessIterator>
  379. inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
  380. operator + (typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s,
  381. const sub_match<RandomAccessIterator>& m)
  382. {
  383. std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
  384. result.reserve(m.length() + 2);
  385. return result.append(1, s).append(m.first, m.second);
  386. }
  387. template <class RandomAccessIterator>
  388. inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
  389. operator + (const sub_match<RandomAccessIterator>& m,
  390. typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type const& s)
  391. {
  392. std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
  393. result.reserve(m.length() + 2);
  394. return result.append(m.first, m.second).append(1, s);
  395. }
  396. template <class RandomAccessIterator>
  397. inline std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type>
  398. operator + (const sub_match<RandomAccessIterator>& m1,
  399. const sub_match<RandomAccessIterator>& m2)
  400. {
  401. std::basic_string<typename re_detail::regex_iterator_traits<RandomAccessIterator>::value_type> result;
  402. result.reserve(m1.length() + m2.length() + 1);
  403. return result.append(m1.first, m1.second).append(m2.first, m2.second);
  404. }
  405. #ifndef BOOST_NO_STD_LOCALE
  406. template <class charT, class traits, class RandomAccessIterator>
  407. std::basic_ostream<charT, traits>&
  408. operator << (std::basic_ostream<charT, traits>& os,
  409. const sub_match<RandomAccessIterator>& s)
  410. {
  411. return (os << s.str());
  412. }
  413. #else
  414. template <class RandomAccessIterator>
  415. std::ostream& operator << (std::ostream& os,
  416. const sub_match<RandomAccessIterator>& s)
  417. {
  418. return (os << s.str());
  419. }
  420. #endif
  421. #ifdef BOOST_OLD_REGEX_H
  422. namespace re_detail{
  423. template <class BidiIterator, class charT>
  424. int do_toi(BidiIterator i, BidiIterator j, char c, int radix)
  425. {
  426. std::string s(i, j);
  427. char* p;
  428. int result = std::strtol(s.c_str(), &p, radix);
  429. if(*p)raise_regex_exception("Bad sub-expression");
  430. return result;
  431. }
  432. //
  433. // helper:
  434. template <class I, class charT>
  435. int do_toi(I& i, I j, charT c)
  436. {
  437. int result = 0;
  438. while((i != j) && (isdigit(*i)))
  439. {
  440. result = result*10 + (*i - '0');
  441. ++i;
  442. }
  443. return result;
  444. }
  445. }
  446. template <class BidiIterator>
  447. sub_match<BidiIterator>::operator int()const
  448. {
  449. BidiIterator i = first;
  450. BidiIterator j = second;
  451. if(i == j)raise_regex_exception("Bad sub-expression");
  452. int neg = 1;
  453. if((i != j) && (*i == '-'))
  454. {
  455. neg = -1;
  456. ++i;
  457. }
  458. neg *= re_detail::do_toi(i, j, *i);
  459. if(i != j)raise_regex_exception("Bad sub-expression");
  460. return neg;
  461. }
  462. template <class BidiIterator>
  463. sub_match<BidiIterator>::operator unsigned int()const
  464. {
  465. BidiIterator i = first;
  466. BidiIterator j = second;
  467. if(i == j)
  468. raise_regex_exception("Bad sub-expression");
  469. return re_detail::do_toi(i, j, *first);
  470. }
  471. #endif
  472. } // namespace boost
  473. #ifdef BOOST_MSVC
  474. #pragma warning(push)
  475. #pragma warning(disable: 4103)
  476. #endif
  477. #ifdef BOOST_HAS_ABI_HEADERS
  478. # include BOOST_ABI_SUFFIX
  479. #endif
  480. #ifdef BOOST_MSVC
  481. #pragma warning(pop)
  482. #endif
  483. #endif