| // Boost.Range library |
| // |
| // Copyright Thorsten Ottosen, Neil Groves 2006. Use, modification and |
| // distribution is subject to the Boost Software License, Version |
| // 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| // |
| // For more information, see http://www.boost.org/libs/range/ |
| // |
| |
| #ifndef BOOST_RANGE_ADAPTOR_TOKENIZED_HPP |
| #define BOOST_RANGE_ADAPTOR_TOKENIZED_HPP |
| |
| #include <boost/regex.hpp> |
| #include <boost/range/iterator_range.hpp> |
| |
| namespace boost |
| { |
| namespace range_detail |
| { |
| |
| template< class R > |
| struct token_range : |
| public boost::iterator_range< |
| boost::regex_token_iterator< |
| BOOST_DEDUCED_TYPENAME range_iterator<R>::type |
| > |
| > |
| { |
| private: |
| typedef |
| boost::regex_token_iterator< |
| BOOST_DEDUCED_TYPENAME range_iterator<R>::type |
| > |
| regex_iter; |
| |
| typedef BOOST_DEDUCED_TYPENAME regex_iter::regex_type |
| regex_type; |
| |
| typedef boost::iterator_range<regex_iter> |
| base; |
| |
| public: |
| template< class Regex, class Submatch, class Flag > |
| token_range( R& r, const Regex& re, const Submatch& sub, Flag f ) |
| : base( regex_iter( boost::begin(r), boost::end(r), |
| regex_type(re), sub, f ), |
| regex_iter() ) |
| { } |
| }; |
| |
| template< class T, class U, class V > |
| struct regex_holder |
| { |
| const T& re; |
| const U& sub; |
| V f; |
| |
| regex_holder( const T& rex, const U& subm, V flag ) : |
| re(rex), sub(subm), f(flag) |
| { } |
| private: |
| // Not assignable |
| void operator=(const regex_holder&); |
| }; |
| |
| struct regex_forwarder |
| { |
| template< class Regex > |
| regex_holder<Regex,int,regex_constants::match_flag_type> |
| operator()( const Regex& re, |
| int submatch = 0, |
| regex_constants::match_flag_type f = |
| regex_constants::match_default ) const |
| { |
| return regex_holder<Regex,int, |
| regex_constants::match_flag_type>( re, submatch, f ); |
| } |
| |
| template< class Regex, class Submatch > |
| regex_holder<Regex,Submatch,regex_constants::match_flag_type> |
| operator()( const Regex& re, |
| const Submatch& sub, |
| regex_constants::match_flag_type f = |
| regex_constants::match_default ) const |
| { |
| return regex_holder<Regex,Submatch, |
| regex_constants::match_flag_type>( re, sub, f ); |
| } |
| }; |
| |
| template< class BidirectionalRng, class R, class S, class F > |
| inline token_range<BidirectionalRng> |
| operator|( BidirectionalRng& r, |
| const regex_holder<R,S,F>& f ) |
| { |
| return token_range<BidirectionalRng>( r, f.re, f.sub, f.f ); |
| } |
| |
| template< class BidirectionalRng, class R, class S, class F > |
| inline token_range<const BidirectionalRng> |
| operator|( const BidirectionalRng& r, |
| const regex_holder<R,S,F>& f ) |
| { |
| return token_range<const BidirectionalRng>( r, f.re, f.sub, f.f ); |
| } |
| |
| } // 'range_detail' |
| |
| using range_detail::token_range; |
| |
| namespace adaptors |
| { |
| namespace |
| { |
| const range_detail::regex_forwarder tokenized = |
| range_detail::regex_forwarder(); |
| } |
| |
| template<class BidirectionalRange, class Regex, class Submatch, class Flag> |
| inline token_range<BidirectionalRange> |
| tokenize(BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f) |
| { |
| return token_range<BidirectionalRange>(rng, reg, sub, f); |
| } |
| |
| template<class BidirectionalRange, class Regex, class Submatch, class Flag> |
| inline token_range<const BidirectionalRange> |
| tokenize(const BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f) |
| { |
| return token_range<const BidirectionalRange>(rng, reg, sub, f); |
| } |
| } // 'adaptors' |
| |
| } |
| |
| #endif |