Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 09:55:54

0001 //  Boost string_algo library find_iterator.hpp header file  ---------------------------//
0002 
0003 //  Copyright Pavol Droba 2002-2004.
0004 //
0005 // Distributed under the Boost Software License, Version 1.0.
0006 //    (See accompanying file LICENSE_1_0.txt or copy at
0007 //          http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 //  See http://www.boost.org/ for updates, documentation, and revision history.
0010 
0011 #ifndef BOOST_STRING_FIND_ITERATOR_HPP
0012 #define BOOST_STRING_FIND_ITERATOR_HPP
0013 
0014 #include <boost/algorithm/string/config.hpp>
0015 #include <boost/iterator/iterator_facade.hpp>
0016 #include <boost/iterator/iterator_categories.hpp>
0017 
0018 #include <boost/range/iterator_range_core.hpp>
0019 #include <boost/range/begin.hpp>
0020 #include <boost/range/end.hpp>
0021 #include <boost/range/iterator.hpp>
0022 #include <boost/range/as_literal.hpp>
0023 
0024 #include <boost/algorithm/string/detail/find_iterator.hpp>
0025 
0026 /*! \file
0027     Defines find iterator classes. Find iterator repeatedly applies a Finder
0028     to the specified input string to search for matches. Dereferencing
0029     the iterator yields the current match or a range between the last and the current
0030     match depending on the iterator used.
0031 */
0032 
0033 namespace boost {
0034     namespace algorithm { 
0035 
0036 //  find_iterator -----------------------------------------------//
0037 
0038         //! find_iterator
0039         /*!    
0040             Find iterator encapsulates a Finder and allows
0041             for incremental searching in a string.
0042             Each increment moves the iterator to the next match.
0043 
0044             Find iterator is a readable forward traversal iterator.
0045 
0046             Dereferencing the iterator yields an iterator_range delimiting
0047             the current match.
0048         */
0049         template<typename IteratorT>
0050         class find_iterator : 
0051             public iterator_facade<
0052                 find_iterator<IteratorT>,
0053                 const iterator_range<IteratorT>,
0054                 forward_traversal_tag >,
0055             private detail::find_iterator_base<IteratorT>
0056         {
0057         private:
0058             // facade support
0059             friend class ::boost::iterator_core_access;
0060 
0061         private:
0062         // typedefs
0063 
0064             typedef detail::find_iterator_base<IteratorT> base_type;
0065             typedef BOOST_STRING_TYPENAME 
0066                 base_type::input_iterator_type input_iterator_type;
0067             typedef BOOST_STRING_TYPENAME 
0068                 base_type::match_type match_type;
0069 
0070         public:
0071             //! Default constructor
0072             /*!
0073                 Construct null iterator. All null iterators are equal.
0074 
0075                 \post eof()==true
0076             */
0077             BOOST_DEFAULTED_FUNCTION(find_iterator(), {})
0078 
0079             //! Copy constructor
0080             /*!
0081                 Construct a copy of the find_iterator
0082             */
0083             find_iterator( const find_iterator& Other ) :
0084                 base_type(Other),
0085                 m_Match(Other.m_Match),
0086                 m_End(Other.m_End) {}
0087 
0088             //! Copy assignment
0089             /*!
0090                 Assigns a copy of the find_iterator
0091             */
0092             BOOST_DEFAULTED_FUNCTION(find_iterator& operator=( const find_iterator& Other ), {
0093                 if (this == &Other) return *this;
0094                 this->base_type::operator=(Other);
0095                 m_Match = Other.m_Match;
0096                 m_End = Other.m_End;
0097                 return *this;
0098             })
0099 
0100             //! Constructor
0101             /*!
0102                 Construct new find_iterator for a given finder
0103                 and a range.
0104             */
0105             template<typename FinderT>
0106             find_iterator(
0107                     IteratorT Begin,
0108                     IteratorT End,
0109                     FinderT Finder ) :
0110                 detail::find_iterator_base<IteratorT>(Finder,0),
0111                 m_Match(Begin,Begin),
0112                 m_End(End)
0113             {
0114                 increment();
0115             }
0116 
0117             //! Constructor
0118             /*!
0119                 Construct new find_iterator for a given finder
0120                 and a range.
0121             */
0122             template<typename FinderT, typename RangeT>
0123             find_iterator(
0124                     RangeT& Col,
0125                     FinderT Finder ) :
0126                 detail::find_iterator_base<IteratorT>(Finder,0)
0127             {
0128                 iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
0129                 m_Match=::boost::make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
0130                 m_End=::boost::end(lit_col);
0131 
0132                 increment();
0133             }
0134 
0135         private:
0136         // iterator operations
0137 
0138             // dereference
0139             const match_type& dereference() const
0140             {
0141                 return m_Match;
0142             }
0143 
0144             // increment
0145             void increment()
0146             {
0147                 m_Match=this->do_find(m_Match.end(),m_End);
0148             }
0149 
0150             // comparison
0151             bool equal( const find_iterator& Other ) const
0152             {
0153                 bool bEof=eof();
0154                 bool bOtherEof=Other.eof();
0155 
0156                 return bEof || bOtherEof ? bEof==bOtherEof :
0157                     (
0158                         m_Match==Other.m_Match &&
0159                         m_End==Other.m_End 
0160                     );
0161             }
0162 
0163         public:
0164         // operations
0165 
0166             //! Eof check
0167             /*!
0168                 Check the eof condition. Eof condition means that
0169                 there is nothing more to be searched i.e. find_iterator
0170                 is after the last match.
0171             */
0172             bool eof() const
0173             {
0174                 return 
0175                     this->is_null() || 
0176                     ( 
0177                         m_Match.begin() == m_End &&
0178                         m_Match.end() == m_End
0179                     );
0180             }
0181 
0182         private:
0183         // Attributes
0184             match_type m_Match;
0185             input_iterator_type m_End;
0186         };
0187 
0188         //! find iterator construction helper
0189         /*!
0190          *    Construct a find iterator to iterate through the specified string
0191          */
0192         template<typename RangeT, typename FinderT>
0193         inline find_iterator< 
0194             BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
0195         make_find_iterator(
0196             RangeT& Collection,
0197             FinderT Finder)
0198         {
0199             return find_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
0200                 Collection, Finder);
0201         }
0202 
0203 //  split iterator -----------------------------------------------//
0204 
0205         //! split_iterator
0206         /*!    
0207             Split iterator encapsulates a Finder and allows
0208             for incremental searching in a string.
0209             Unlike the find iterator, split iterator iterates
0210             through gaps between matches.
0211 
0212             Find iterator is a readable forward traversal iterator.
0213 
0214             Dereferencing the iterator yields an iterator_range delimiting
0215             the current match.
0216         */
0217         template<typename IteratorT>
0218         class split_iterator : 
0219             public iterator_facade<
0220                 split_iterator<IteratorT>,
0221                 const iterator_range<IteratorT>,
0222                 forward_traversal_tag >,
0223             private detail::find_iterator_base<IteratorT>
0224         {
0225         private:
0226             // facade support
0227             friend class ::boost::iterator_core_access;
0228 
0229         private:
0230         // typedefs
0231 
0232             typedef detail::find_iterator_base<IteratorT> base_type;
0233             typedef BOOST_STRING_TYPENAME 
0234                 base_type::input_iterator_type input_iterator_type;
0235             typedef BOOST_STRING_TYPENAME 
0236                 base_type::match_type match_type;
0237 
0238         public:
0239             //! Default constructor
0240             /*!
0241                 Construct null iterator. All null iterators are equal.
0242     
0243                 \post eof()==true
0244             */
0245             split_iterator() :
0246                 m_Next(),
0247                 m_End(),
0248                 m_bEof(true)
0249             {}
0250 
0251             //! Copy constructor
0252             /*!
0253                 Construct a copy of the split_iterator
0254             */
0255             split_iterator( const split_iterator& Other ) :
0256                 base_type(Other),
0257                 m_Match(Other.m_Match),
0258                 m_Next(Other.m_Next),
0259                 m_End(Other.m_End),
0260                 m_bEof(Other.m_bEof)
0261             {}
0262 
0263             //! Assignment operator
0264             /*!
0265                 Assigns a copy of the split_iterator
0266             */
0267             BOOST_DEFAULTED_FUNCTION(split_iterator& operator=( const split_iterator& Other ), {
0268                 if (this == &Other) return *this;
0269                 this->base_type::operator=(Other);
0270                 m_Match = Other.m_Match;
0271                 m_Next = Other.m_Next;
0272                 m_End = Other.m_End;
0273                 m_bEof = Other.m_bEof;
0274                 return *this;
0275             })
0276 
0277             //! Constructor
0278             /*!
0279                 Construct new split_iterator for a given finder
0280                 and a range.
0281             */
0282             template<typename FinderT>
0283             split_iterator(
0284                     IteratorT Begin,
0285                     IteratorT End,
0286                     FinderT Finder ) :
0287                 detail::find_iterator_base<IteratorT>(Finder,0),
0288                 m_Match(Begin,Begin),
0289                 m_Next(Begin),
0290                 m_End(End),
0291                 m_bEof(false)
0292             {
0293                 // force the correct behavior for empty sequences and yield at least one token
0294                 if(Begin!=End)
0295                 {
0296                     increment();
0297                 }
0298             }
0299             //! Constructor
0300             /*!
0301                 Construct new split_iterator for a given finder
0302                 and a collection.
0303             */
0304             template<typename FinderT, typename RangeT>
0305             split_iterator(
0306                     RangeT& Col,
0307                     FinderT Finder ) :
0308                 detail::find_iterator_base<IteratorT>(Finder,0),
0309                 m_bEof(false)
0310             {
0311                 iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
0312                 m_Match=make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
0313                 m_Next=::boost::begin(lit_col);
0314                 m_End=::boost::end(lit_col);
0315 
0316                 // force the correct behavior for empty sequences and yield at least one token
0317                 if(m_Next!=m_End)
0318                 {
0319                     increment();
0320                 }
0321             }
0322 
0323 
0324         private:
0325         // iterator operations
0326 
0327             // dereference
0328             const match_type& dereference() const
0329             {
0330                 return m_Match;
0331             }
0332 
0333             // increment
0334             void increment()
0335             {
0336                 match_type FindMatch=this->do_find( m_Next, m_End );
0337 
0338                 if(FindMatch.begin()==m_End && FindMatch.end()==m_End)
0339                 {
0340                     if(m_Match.end()==m_End)
0341                     {
0342                         // Mark iterator as eof
0343                         m_bEof=true;
0344                     }
0345                 }
0346 
0347                 m_Match=match_type( m_Next, FindMatch.begin() );
0348                 m_Next=FindMatch.end();
0349             }
0350 
0351             // comparison
0352             bool equal( const split_iterator& Other ) const
0353             {
0354                 bool bEof=eof();
0355                 bool bOtherEof=Other.eof();
0356 
0357                 return bEof || bOtherEof ? bEof==bOtherEof :
0358                     (
0359                         m_Match==Other.m_Match &&
0360                         m_Next==Other.m_Next &&
0361                         m_End==Other.m_End
0362                     );
0363             }
0364 
0365         public:
0366         // operations
0367 
0368             //! Eof check
0369             /*!
0370                 Check the eof condition. Eof condition means that
0371                 there is nothing more to be searched i.e. find_iterator
0372                 is after the last match.
0373             */
0374             bool eof() const
0375             {
0376                 return this->is_null() || m_bEof;
0377             }
0378 
0379         private:
0380         // Attributes
0381             match_type m_Match;
0382             input_iterator_type m_Next;
0383             input_iterator_type m_End;
0384             bool m_bEof;
0385         };
0386 
0387         //! split iterator construction helper
0388         /*!
0389          *    Construct a split iterator to iterate through the specified collection
0390          */
0391         template<typename RangeT, typename FinderT>
0392         inline split_iterator< 
0393             BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
0394         make_split_iterator(
0395             RangeT& Collection,
0396             FinderT Finder)
0397         {
0398             return split_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
0399                 Collection, Finder);
0400         }
0401 
0402 
0403     } // namespace algorithm
0404 
0405     // pull names to the boost namespace
0406     using algorithm::find_iterator;
0407     using algorithm::make_find_iterator;
0408     using algorithm::split_iterator;
0409     using algorithm::make_split_iterator;
0410 
0411 } // namespace boost
0412 
0413 
0414 #endif  // BOOST_STRING_FIND_ITERATOR_HPP