ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

546 lines
14 KiB

  1. //
  2. // Copyright (C) 2009-2012 Artyom Beilis (Tonkikh)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. #ifndef BOOSTER_REGEX_MATCH_H
  9. #define BOOSTER_REGEX_MATCH_H
  10. #include <algorithm>
  11. #include <iterator>
  12. #include <string>
  13. #include <vector>
  14. #include <string.h>
  15. namespace booster {
  16. ///
  17. /// \brief This class represents a single captures subexpression.
  18. ///
  19. /// The subexpressions captured text is found between [first,second).
  20. ///
  21. template<typename Iterator>
  22. class sub_match : public std::pair<Iterator,Iterator> {
  23. public:
  24. typedef Iterator iterator;
  25. typedef typename std::iterator_traits<Iterator>::value_type value_type;
  26. typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
  27. ///
  28. /// The string type that this expression can be converted into, generally std::string.
  29. ///
  30. typedef std::basic_string<value_type> string_type;
  31. typedef std::pair<Iterator,Iterator> pair_type;
  32. ///
  33. /// This flag is true if the expression was matched, false otherwise.
  34. /// if matched is false then there is no guarantees that first or second are valid iterators.
  35. ///
  36. bool matched;
  37. ///
  38. /// The length of captured subexpression, 0 if matched==false.
  39. ///
  40. difference_type length() const
  41. {
  42. if(matched)
  43. return std::distance(pair_type::first,pair_type::second);
  44. return 0;
  45. }
  46. ///
  47. /// Explicit conversion operator to string
  48. ///
  49. operator string_type() const
  50. {
  51. return str();
  52. }
  53. ///
  54. /// Convert the subexpression to string. If matched is false, return empty string.
  55. ///
  56. string_type str() const
  57. {
  58. if(matched)
  59. return string_type(pair_type::first,pair_type::second);
  60. else
  61. return string_type();
  62. }
  63. ///
  64. /// Compare two subexpressions. Same as str().compare(other.str())
  65. ///
  66. int compare(sub_match const &other) const
  67. {
  68. return str().compare(other.str());
  69. }
  70. ///
  71. /// Compare two subexpressions. Same as str().compare(other)
  72. ///
  73. int compare(string_type const &other) const
  74. {
  75. return str().compare(other);
  76. }
  77. ///
  78. /// Compare two subexpressions. Same as str().compare(s)
  79. ///
  80. int compare(value_type const *s) const
  81. {
  82. return str().compare(s);
  83. }
  84. ///
  85. /// Default not-matched subexpressions.
  86. ///
  87. sub_match() : matched(false)
  88. {
  89. }
  90. };
  91. typedef sub_match<char const *> csub_match;
  92. typedef sub_match<std::string::const_iterator> ssub_match;
  93. ///
  94. /// \brief The object that hold the result of matching a regular expression against the text
  95. /// using regex_match and regex_search functions
  96. ///
  97. template<typename Iterator>
  98. class match_results {
  99. public:
  100. ///
  101. /// Creates default empty matched result.
  102. ///
  103. match_results()
  104. {
  105. begin_ = Iterator();
  106. end_ = Iterator();
  107. }
  108. ///
  109. /// The type of subexpression returned by operator[]
  110. ///
  111. typedef sub_match<Iterator> value_type;
  112. ///
  113. /// Get the sub_match for subexpression \a n. If n < 0 or n >= size() returns an empty sub_match
  114. ///
  115. value_type operator[](int n) const
  116. {
  117. value_type r;
  118. if(n < 0 || n >= int(offsets_.size()))
  119. return r;
  120. if(offsets_[n].first == -1)
  121. return r;
  122. r.matched = true;
  123. r.first = begin_;
  124. r.second = begin_;
  125. std::advance(r.first,offsets_[n].first);
  126. std::advance(r.second,offsets_[n].second);
  127. return r;
  128. }
  129. ///
  130. /// Get the number of captured subexpressions in the regular expression.
  131. ///
  132. size_t size() const
  133. {
  134. return offsets_.size();
  135. }
  136. ///
  137. /// Get the text range before the matched expression. Always empty for match_results
  138. ///
  139. value_type suffix()
  140. {
  141. value_type r;
  142. if(offsets_.empty())
  143. return r;
  144. r.first = begin_;
  145. r.second = end_;
  146. std::advance(r.first,offsets_.back().second);
  147. r.matched = r.first != r.second;
  148. return r;
  149. }
  150. ///
  151. /// Get the text range after the matched expression. Always empty for match_results
  152. ///
  153. value_type prefix()
  154. {
  155. value_type r;
  156. if(offsets_.empty() || offsets_[0].first == 0)
  157. return r;
  158. r.matched = true;
  159. r.first = begin_;
  160. r.second = begin_;
  161. std::advance(r.second,offsets_[0].first);
  162. return r;
  163. }
  164. /// \cond INTERNAL
  165. void assign(Iterator begin,Iterator end,std::vector<std::pair<int,int> > &offsets)
  166. {
  167. begin_ = begin;
  168. end_ = end;
  169. offsets_.swap(offsets);
  170. }
  171. /// \endcond
  172. private:
  173. Iterator begin_,end_;
  174. std::vector<std::pair<int,int> > offsets_;
  175. };
  176. typedef match_results<char const *> cmatch;
  177. typedef match_results<std::string::const_iterator> smatch;
  178. ///
  179. /// Match an expression \a r against text in range [\a begin, \a end ), return true
  180. /// if found and store matched patters in \a m
  181. ///
  182. template<typename Regex>
  183. bool regex_match(char const *begin,char const *end,cmatch &m, Regex const &r,int flags = 0)
  184. {
  185. std::vector<std::pair<int,int> > map;
  186. bool res = r.match(begin,end,map,flags);
  187. if(!res) return false;
  188. m.assign(begin,end,map);
  189. return true;
  190. }
  191. ///
  192. /// Match an expression \a r against text \a s, return true
  193. /// if found and store matched patters in \a m
  194. ///
  195. template<typename Regex>
  196. bool regex_match(std::string const &s,smatch &m, Regex const &r,int flags = 0)
  197. {
  198. std::vector<std::pair<int,int> > map;
  199. bool res = r.match(s.c_str(),s.c_str()+s.size(),map,flags);
  200. if(!res) return false;
  201. m.assign(s.begin(),s.end(),map);
  202. return true;
  203. }
  204. ///
  205. /// Match an expression \a r against text \a s, return true
  206. /// if found and store matched patters in \a m
  207. ///
  208. template<typename Regex>
  209. bool regex_match(char const *s,cmatch &m, Regex const &r,int flags = 0)
  210. {
  211. std::vector<std::pair<int,int> > map;
  212. char const *begin=s;
  213. char const *end = begin+strlen(begin);
  214. bool res = r.match(begin,end,map,flags);
  215. if(!res) return false;
  216. m.assign(begin,end,map);
  217. return true;
  218. }
  219. ///
  220. /// Search an expression \a r in text in rage [\a begin, \a end). Return true if found,
  221. /// and store matched subexpressions in \a m
  222. ///
  223. template<typename Regex>
  224. bool regex_search(char const *begin,char const *end,cmatch &m, Regex const &r,int flags = 0)
  225. {
  226. std::vector<std::pair<int,int> > map;
  227. bool res = r.search(begin,end,map,flags);
  228. if(!res) return false;
  229. m.assign(begin,end,map);
  230. return true;
  231. }
  232. ///
  233. /// Search an expression \a r in text \a s. Return true if found,
  234. /// and store matched subexpressions in \a m
  235. ///
  236. template<typename Regex>
  237. bool regex_search(std::string const &s,smatch &m, Regex const &r,int flags = 0)
  238. {
  239. std::vector<std::pair<int,int> > map;
  240. bool res = r.search(s.c_str(),s.c_str()+s.size(),map,flags);
  241. if(!res) return false;
  242. m.assign(s.begin(),s.end(),map);
  243. return true;
  244. }
  245. ///
  246. /// Search an expression \a r in text \a s. Return true if found,
  247. /// and store matched subexpressions in \a m
  248. ///
  249. template<typename Regex>
  250. bool regex_search(char const *s,cmatch &m, Regex const &r,int flags = 0)
  251. {
  252. std::vector<std::pair<int,int> > map;
  253. char const *begin=s;
  254. char const *end = begin+strlen(begin);
  255. bool res = r.search(begin,end,map,flags);
  256. if(!res) return false;
  257. m.assign(begin,end,map);
  258. return true;
  259. }
  260. ///
  261. /// Match an expression \a r against text in range [\a begin, \a end ), return true if matched
  262. ///
  263. template<typename Regex>
  264. bool regex_match(char const *begin,char const *end, Regex const &r,int flags = 0)
  265. {
  266. return r.match(begin,end,flags);
  267. }
  268. ///
  269. /// Match an expression \a r against text \a s, return true if matched
  270. ///
  271. template<typename Regex>
  272. bool regex_match(std::string const &s, Regex const &r,int flags = 0)
  273. {
  274. return r.match(s.c_str(),s.c_str()+s.size(),flags);
  275. }
  276. ///
  277. /// Match an expression \a r against text \a s, return true if matched
  278. ///
  279. template<typename Regex>
  280. bool regex_match(char const *s, Regex const &r,int flags = 0)
  281. {
  282. return r.match(s,s+strlen(s),flags);
  283. }
  284. ///
  285. /// Search an expression \a r against text in range [\a begin, \a end ), return true if found
  286. ///
  287. template<typename Regex>
  288. bool regex_search(char const *begin,char const *end, Regex const &r,int flags = 0)
  289. {
  290. return r.search(begin,end,flags);
  291. }
  292. ///
  293. /// Search an expression \a r against text \a s, return true if found
  294. ///
  295. template<typename Regex>
  296. bool regex_search(std::string const &s, Regex const &r,int flags = 0)
  297. {
  298. return r.search(s.c_str(),s.c_str()+s.size(),flags);
  299. }
  300. ///
  301. /// Search an expression \a r against text \a s, return true if found
  302. ///
  303. template<typename Regex>
  304. bool regex_search(char const *s, Regex const &r,int flags = 0)
  305. {
  306. return r.search(s,s+strlen(s),flags);
  307. }
  308. // sub -- sub
  309. template<typename Iterator>
  310. bool operator==(sub_match<Iterator> const &l,sub_match<Iterator> const &r) { return l.compare(r) == 0; }
  311. template<typename Iterator>
  312. bool operator!=(sub_match<Iterator> const &l,sub_match<Iterator> const &r) { return l.compare(r) != 0; }
  313. template<typename Iterator>
  314. bool operator< (sub_match<Iterator> const &l,sub_match<Iterator> const &r) { return l.compare(r) < 0; }
  315. template<typename Iterator>
  316. bool operator> (sub_match<Iterator> const &l,sub_match<Iterator> const &r) { return l.compare(r) > 0; }
  317. template<typename Iterator>
  318. bool operator<=(sub_match<Iterator> const &l,sub_match<Iterator> const &r) { return l.compare(r) <= 0; }
  319. template<typename Iterator>
  320. bool operator>=(sub_match<Iterator> const &l,sub_match<Iterator> const &r) { return l.compare(r) >= 0; }
  321. // str -- sub
  322. template<typename Iterator>
  323. bool operator==(
  324. typename sub_match<Iterator>::string_type const &l,
  325. sub_match<Iterator> const &r)
  326. { return l.compare(r) == 0; }
  327. template<typename Iterator>
  328. bool operator!=(
  329. typename sub_match<Iterator>::string_type const &l,
  330. sub_match<Iterator> const &r)
  331. { return l.compare(r) != 0; }
  332. template<typename Iterator>
  333. bool operator<=(
  334. typename sub_match<Iterator>::string_type const &l,
  335. sub_match<Iterator> const &r)
  336. { return l.compare(r) <= 0; }
  337. template<typename Iterator>
  338. bool operator>=(
  339. typename sub_match<Iterator>::string_type const &l,
  340. sub_match<Iterator> const &r)
  341. { return l.compare(r) >= 0; }
  342. template<typename Iterator>
  343. bool operator<(
  344. typename sub_match<Iterator>::string_type const &l,
  345. sub_match<Iterator> const &r)
  346. { return l.compare(r) <0; }
  347. template<typename Iterator>
  348. bool operator>(
  349. typename sub_match<Iterator>::string_type const &l,
  350. sub_match<Iterator> const &r)
  351. { return l.compare(r) > 0; }
  352. // sub -- str
  353. template<typename Iterator>
  354. bool operator==(
  355. sub_match<Iterator> const &l,
  356. typename sub_match<Iterator>::string_type const &r
  357. )
  358. { return l.compare(r) == 0; }
  359. template<typename Iterator>
  360. bool operator!=(
  361. sub_match<Iterator> const &l,
  362. typename sub_match<Iterator>::string_type const &r
  363. )
  364. { return l.compare(r) != 0; }
  365. template<typename Iterator>
  366. bool operator<=(
  367. sub_match<Iterator> const &l,
  368. typename sub_match<Iterator>::string_type const &r
  369. )
  370. { return l.compare(r) <= 0; }
  371. template<typename Iterator>
  372. bool operator>=(
  373. sub_match<Iterator> const &l,
  374. typename sub_match<Iterator>::string_type const &r
  375. )
  376. { return l.compare(r) >= 0; }
  377. template<typename Iterator>
  378. bool operator<(
  379. sub_match<Iterator> const &l,
  380. typename sub_match<Iterator>::string_type const &r
  381. )
  382. { return l.compare(r) <0; }
  383. template<typename Iterator>
  384. bool operator>(
  385. sub_match<Iterator> const &l,
  386. typename sub_match<Iterator>::string_type const &r
  387. )
  388. { return l.compare(r) > 0; }
  389. // * -- sub
  390. template<typename Iterator>
  391. bool operator==(
  392. typename std::iterator_traits<Iterator>::value_type const *l,
  393. sub_match<Iterator> const &r)
  394. { return r.compare(l) ==0; }
  395. template<typename Iterator>
  396. bool operator!=(
  397. typename std::iterator_traits<Iterator>::value_type const *l,
  398. sub_match<Iterator> const &r)
  399. { return r.compare(l) !=0; }
  400. template<typename Iterator>
  401. bool operator<=(
  402. typename std::iterator_traits<Iterator>::value_type const *l,
  403. sub_match<Iterator> const &r)
  404. { return r.compare(l) > 0; }
  405. template<typename Iterator>
  406. bool operator>=(
  407. typename std::iterator_traits<Iterator>::value_type const *l,
  408. sub_match<Iterator> const &r)
  409. { return r.compare(l) < 0; }
  410. template<typename Iterator>
  411. bool operator<(
  412. typename std::iterator_traits<Iterator>::value_type const *l,
  413. sub_match<Iterator> const &r)
  414. { return r.compare(l) >=0; }
  415. template<typename Iterator>
  416. bool operator>(
  417. typename std::iterator_traits<Iterator>::value_type const *l,
  418. sub_match<Iterator> const &r)
  419. { return r.compare(l) <= 0; }
  420. // sub -- *
  421. template<typename Iterator>
  422. bool operator==(
  423. sub_match<Iterator> const &l,
  424. typename std::iterator_traits<Iterator>::value_type const *r
  425. )
  426. { return l.compare(r) == 0; }
  427. template<typename Iterator>
  428. bool operator!=(
  429. sub_match<Iterator> const &l,
  430. typename std::iterator_traits<Iterator>::value_type const *r
  431. )
  432. { return l.compare(r) != 0; }
  433. template<typename Iterator>
  434. bool operator<=(
  435. sub_match<Iterator> const &l,
  436. typename std::iterator_traits<Iterator>::value_type const *r
  437. )
  438. { return l.compare(r) <= 0; }
  439. template<typename Iterator>
  440. bool operator>=(
  441. sub_match<Iterator> const &l,
  442. typename std::iterator_traits<Iterator>::value_type const *r
  443. )
  444. { return l.compare(r) >= 0; }
  445. template<typename Iterator>
  446. bool operator<(
  447. sub_match<Iterator> const &l,
  448. typename std::iterator_traits<Iterator>::value_type const *r
  449. )
  450. { return l.compare(r) <0; }
  451. template<typename Iterator>
  452. bool operator>(
  453. sub_match<Iterator> const &l,
  454. typename std::iterator_traits<Iterator>::value_type const *r
  455. )
  456. { return l.compare(r) > 0; }
  457. // add +
  458. template<typename Iterator>
  459. typename sub_match<Iterator>::string_type
  460. operator+(sub_match<Iterator> const &l,sub_match<Iterator> const &r)
  461. { return l.str() + r.str(); }
  462. template<typename Iterator>
  463. typename sub_match<Iterator>::string_type
  464. operator+(sub_match<Iterator> const &l,typename sub_match<Iterator>::string_type const &r)
  465. { return l.str() + r; }
  466. template<typename Iterator>
  467. typename sub_match<Iterator>::string_type
  468. operator+(typename sub_match<Iterator>::string_type const &l,sub_match<Iterator> const &r)
  469. { return l + r.str(); }
  470. template<typename Iterator>
  471. typename sub_match<Iterator>::string_type
  472. operator+(sub_match<Iterator> const &l,typename sub_match<Iterator>::value_type const *r)
  473. { return l.str() + r; }
  474. template<typename Iterator>
  475. typename sub_match<Iterator>::string_type
  476. operator+(typename sub_match<Iterator>::value_type const *l,sub_match<Iterator> const &r)
  477. { return l + r.str(); }
  478. }
  479. #endif