tokenized.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Boost.Range library
  2. //
  3. // Copyright Thorsten Ottosen, Neil Groves 2006. Use, modification and
  4. // distribution is subject to the Boost Software License, Version
  5. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // For more information, see http://www.boost.org/libs/range/
  9. //
  10. #ifndef BOOST_RANGE_ADAPTOR_TOKENIZED_HPP
  11. #define BOOST_RANGE_ADAPTOR_TOKENIZED_HPP
  12. #include <boost/regex.hpp>
  13. #include <boost/range/iterator_range.hpp>
  14. namespace boost
  15. {
  16. namespace range_detail
  17. {
  18. template< class R >
  19. struct tokenized_range :
  20. public boost::iterator_range<
  21. boost::regex_token_iterator<
  22. BOOST_DEDUCED_TYPENAME range_iterator<R>::type
  23. >
  24. >
  25. {
  26. private:
  27. typedef
  28. boost::regex_token_iterator<
  29. BOOST_DEDUCED_TYPENAME range_iterator<R>::type
  30. >
  31. regex_iter;
  32. typedef BOOST_DEDUCED_TYPENAME regex_iter::regex_type
  33. regex_type;
  34. typedef boost::iterator_range<regex_iter>
  35. base;
  36. public:
  37. template< class Regex, class Submatch, class Flag >
  38. tokenized_range( R& r, const Regex& re, const Submatch& sub, Flag f )
  39. : base( regex_iter( boost::begin(r), boost::end(r),
  40. regex_type(re), sub, f ),
  41. regex_iter() )
  42. { }
  43. };
  44. template< class T, class U, class V >
  45. struct regex_holder
  46. {
  47. T re;
  48. U sub;
  49. V f;
  50. regex_holder( const T& rex, const U& subm, V flag ) :
  51. re(rex), sub(subm), f(flag)
  52. { }
  53. private:
  54. // Not assignable
  55. void operator=(const regex_holder&);
  56. };
  57. struct regex_forwarder
  58. {
  59. template< class Regex >
  60. regex_holder<Regex,int,regex_constants::match_flag_type>
  61. operator()( const Regex& re,
  62. int submatch = 0,
  63. regex_constants::match_flag_type f =
  64. regex_constants::match_default ) const
  65. {
  66. return regex_holder<Regex,int,
  67. regex_constants::match_flag_type>( re, submatch, f );
  68. }
  69. template< class Regex, class Submatch >
  70. regex_holder<Regex,Submatch,regex_constants::match_flag_type>
  71. operator()( const Regex& re,
  72. const Submatch& sub,
  73. regex_constants::match_flag_type f =
  74. regex_constants::match_default ) const
  75. {
  76. return regex_holder<Regex,Submatch,
  77. regex_constants::match_flag_type>( re, sub, f );
  78. }
  79. };
  80. template< class BidirectionalRng, class R, class S, class F >
  81. inline tokenized_range<BidirectionalRng>
  82. operator|( BidirectionalRng& r,
  83. const regex_holder<R,S,F>& f )
  84. {
  85. return tokenized_range<BidirectionalRng>( r, f.re, f.sub, f.f );
  86. }
  87. template< class BidirectionalRng, class R, class S, class F >
  88. inline tokenized_range<const BidirectionalRng>
  89. operator|( const BidirectionalRng& r,
  90. const regex_holder<R,S,F>& f )
  91. {
  92. return tokenized_range<const BidirectionalRng>( r, f.re, f.sub, f.f );
  93. }
  94. } // 'range_detail'
  95. using range_detail::tokenized_range;
  96. namespace adaptors
  97. {
  98. namespace
  99. {
  100. const range_detail::regex_forwarder tokenized =
  101. range_detail::regex_forwarder();
  102. }
  103. template<class BidirectionalRange, class Regex, class Submatch, class Flag>
  104. inline tokenized_range<BidirectionalRange>
  105. tokenize(BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f)
  106. {
  107. return tokenized_range<BidirectionalRange>(rng, reg, sub, f);
  108. }
  109. template<class BidirectionalRange, class Regex, class Submatch, class Flag>
  110. inline tokenized_range<const BidirectionalRange>
  111. tokenize(const BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f)
  112. {
  113. return tokenized_range<const BidirectionalRange>(rng, reg, sub, f);
  114. }
  115. } // 'adaptors'
  116. }
  117. #endif