tokenized.hpp 4.62 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
// 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 tokenized_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 >
            tokenized_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 tokenized_range<BidirectionalRng> 
        operator|( BidirectionalRng& r, 
                   const regex_holder<R,S,F>& f )
        {
            return tokenized_range<BidirectionalRng>( r, f.re, f.sub, f.f );   
        }

        template< class BidirectionalRng, class R, class S, class F  >
        inline tokenized_range<const BidirectionalRng> 
        operator|( const BidirectionalRng& r, 
                   const regex_holder<R,S,F>& f )
        {
            return tokenized_range<const BidirectionalRng>( r, f.re, f.sub, f.f );
        }
        
    } // 'range_detail'

    using range_detail::tokenized_range;

    namespace adaptors
    { 
        namespace
        {
            const range_detail::regex_forwarder tokenized = 
                    range_detail::regex_forwarder();
        }
        
        template<class BidirectionalRange, class Regex, class Submatch, class Flag>
        inline tokenized_range<BidirectionalRange>
        tokenize(BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f)
        {
            return tokenized_range<BidirectionalRange>(rng, reg, sub, f);
        }
        
        template<class BidirectionalRange, class Regex, class Submatch, class Flag>
        inline tokenized_range<const BidirectionalRange>
        tokenize(const BidirectionalRange& rng, const Regex& reg, const Submatch& sub, Flag f)
        {
            return tokenized_range<const BidirectionalRange>(rng, reg, sub, f);
        }
    } // 'adaptors'
    
}

#endif