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 11 #ifndef BOOST_RANGE_ADAPTOR_TOKENIZED_HPP 12 #define BOOST_RANGE_ADAPTOR_TOKENIZED_HPP 13 14 #include <boost/regex.hpp> 15 #include <boost/range/iterator_range.hpp> 16 17 namespace boost 18 { 19 namespace range_detail 20 { 21 22 template< class R > 23 struct tokenized_range : 24 public boost::iterator_range< 25 boost::regex_token_iterator< 26 BOOST_DEDUCED_TYPENAME range_iterator<R>::type 27 > 28 > 29 { 30 private: 31 typedef 32 boost::regex_token_iterator< 33 BOOST_DEDUCED_TYPENAME range_iterator<R>::type 34 > 35 regex_iter; 36 37 typedef BOOST_DEDUCED_TYPENAME regex_iter::regex_type 38 regex_type; 39 40 typedef boost::iterator_range<regex_iter> 41 base; 42 43 public: 44 template< class Regex, class Submatch, class Flag > tokenized_rangeboost::range_detail::tokenized_range45 tokenized_range( R& r, const Regex& re, const Submatch& sub, Flag f ) 46 : base( regex_iter( boost::begin(r), boost::end(r), 47 regex_type(re), sub, f ), 48 regex_iter() ) 49 { } 50 }; 51 52 template< class T, class U, class V > 53 struct regex_holder 54 { 55 T re; 56 U sub; 57 V f; 58 regex_holderboost::range_detail::regex_holder59 regex_holder( const T& rex, const U& subm, V flag ) : 60 re(rex), sub(subm), f(flag) 61 { } 62 private: 63 // Not assignable 64 void operator=(const regex_holder&); 65 }; 66 67 struct regex_forwarder 68 { 69 template< class Regex > 70 regex_holder<Regex,int,regex_constants::match_flag_type> operator ()boost::range_detail::regex_forwarder71 operator()( const Regex& re, 72 int submatch = 0, 73 regex_constants::match_flag_type f = 74 regex_constants::match_default ) const 75 { 76 return regex_holder<Regex,int, 77 regex_constants::match_flag_type>( re, submatch, f ); 78 } 79 80 template< class Regex, class Submatch > 81 regex_holder<Regex,Submatch,regex_constants::match_flag_type> operator ()boost::range_detail::regex_forwarder82 operator()( const Regex& re, 83 const Submatch& sub, 84 regex_constants::match_flag_type f = 85 regex_constants::match_default ) const 86 { 87 return regex_holder<Regex,Submatch, 88 regex_constants::match_flag_type>( re, sub, f ); 89 } 90 }; 91 92 template< class BidirectionalRng, class R, class S, class F > 93 inline tokenized_range<BidirectionalRng> operator |(BidirectionalRng & r,const regex_holder<R,S,F> & f)94 operator|( BidirectionalRng& r, 95 const regex_holder<R,S,F>& f ) 96 { 97 return tokenized_range<BidirectionalRng>( r, f.re, f.sub, f.f ); 98 } 99 100 template< class BidirectionalRng, class R, class S, class F > 101 inline tokenized_range<const BidirectionalRng> operator |(const BidirectionalRng & r,const regex_holder<R,S,F> & f)102 operator|( const BidirectionalRng& r, 103 const regex_holder<R,S,F>& f ) 104 { 105 return tokenized_range<const BidirectionalRng>( r, f.re, f.sub, f.f ); 106 } 107 108 } // 'range_detail' 109 110 using range_detail::tokenized_range; 111 112 namespace adaptors 113 { 114 namespace 115 { 116 const range_detail::regex_forwarder tokenized = 117 range_detail::regex_forwarder(); 118 } 119 120 template<class BidirectionalRange, class Regex, class Submatch, class Flag> 121 inline tokenized_range<BidirectionalRange> tokenize(BidirectionalRange & rng,const Regex & reg,const Submatch & sub,Flag f)122 tokenize(BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f) 123 { 124 return tokenized_range<BidirectionalRange>(rng, reg, sub, f); 125 } 126 127 template<class BidirectionalRange, class Regex, class Submatch, class Flag> 128 inline tokenized_range<const BidirectionalRange> tokenize(const BidirectionalRange & rng,const Regex & reg,const Submatch & sub,Flag f)129 tokenize(const BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f) 130 { 131 return tokenized_range<const BidirectionalRange>(rng, reg, sub, f); 132 } 133 } // 'adaptors' 134 135 } 136 137 #endif 138