Chris@16: // Boost string_algo library find_iterator.hpp header file ---------------------------// Chris@16: Chris@16: // Copyright Pavol Droba 2002-2004. Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // See http://www.boost.org/ for updates, documentation, and revision history. Chris@16: Chris@16: #ifndef BOOST_STRING_FIND_ITERATOR_HPP Chris@16: #define BOOST_STRING_FIND_ITERATOR_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: /*! \file Chris@16: Defines find iterator classes. Find iterator repeatedly applies a Finder Chris@16: to the specified input string to search for matches. Dereferencing Chris@16: the iterator yields the current match or a range between the last and the current Chris@16: match depending on the iterator used. Chris@16: */ Chris@16: Chris@16: namespace boost { Chris@16: namespace algorithm { Chris@16: Chris@16: // find_iterator -----------------------------------------------// Chris@16: Chris@16: //! find_iterator Chris@16: /*! Chris@16: Find iterator encapsulates a Finder and allows Chris@16: for incremental searching in a string. Chris@16: Each increment moves the iterator to the next match. Chris@16: Chris@16: Find iterator is a readable forward traversal iterator. Chris@16: Chris@16: Dereferencing the iterator yields an iterator_range delimiting Chris@16: the current match. Chris@16: */ Chris@16: template Chris@16: class find_iterator : Chris@16: public iterator_facade< Chris@16: find_iterator, Chris@16: const iterator_range, Chris@16: forward_traversal_tag >, Chris@16: private detail::find_iterator_base Chris@16: { Chris@16: private: Chris@16: // facade support Chris@16: friend class ::boost::iterator_core_access; Chris@16: Chris@16: private: Chris@16: // typedefs Chris@16: Chris@16: typedef detail::find_iterator_base base_type; Chris@16: typedef BOOST_STRING_TYPENAME Chris@16: base_type::input_iterator_type input_iterator_type; Chris@16: typedef BOOST_STRING_TYPENAME Chris@16: base_type::match_type match_type; Chris@16: Chris@16: public: Chris@16: //! Default constructor Chris@16: /*! Chris@16: Construct null iterator. All null iterators are equal. Chris@16: Chris@16: \post eof()==true Chris@16: */ Chris@16: find_iterator() {} Chris@16: Chris@16: //! Copy constructor Chris@16: /*! Chris@16: Construct a copy of the find_iterator Chris@16: */ Chris@16: find_iterator( const find_iterator& Other ) : Chris@16: base_type(Other), Chris@16: m_Match(Other.m_Match), Chris@16: m_End(Other.m_End) {} Chris@16: Chris@16: //! Constructor Chris@16: /*! Chris@16: Construct new find_iterator for a given finder Chris@16: and a range. Chris@16: */ Chris@16: template Chris@16: find_iterator( Chris@16: IteratorT Begin, Chris@16: IteratorT End, Chris@16: FinderT Finder ) : Chris@16: detail::find_iterator_base(Finder,0), Chris@16: m_Match(Begin,Begin), Chris@16: m_End(End) Chris@16: { Chris@16: increment(); Chris@16: } Chris@16: Chris@16: //! Constructor Chris@16: /*! Chris@16: Construct new find_iterator for a given finder Chris@16: and a range. Chris@16: */ Chris@16: template Chris@16: find_iterator( Chris@16: RangeT& Col, Chris@16: FinderT Finder ) : Chris@16: detail::find_iterator_base(Finder,0) Chris@16: { Chris@16: iterator_range::type> lit_col(::boost::as_literal(Col)); Chris@16: m_Match=::boost::make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col)); Chris@16: m_End=::boost::end(lit_col); Chris@16: Chris@16: increment(); Chris@16: } Chris@16: Chris@16: private: Chris@16: // iterator operations Chris@16: Chris@16: // dereference Chris@16: const match_type& dereference() const Chris@16: { Chris@16: return m_Match; Chris@16: } Chris@16: Chris@16: // increment Chris@16: void increment() Chris@16: { Chris@16: m_Match=this->do_find(m_Match.end(),m_End); Chris@16: } Chris@16: Chris@16: // comparison Chris@16: bool equal( const find_iterator& Other ) const Chris@16: { Chris@16: bool bEof=eof(); Chris@16: bool bOtherEof=Other.eof(); Chris@16: Chris@16: return bEof || bOtherEof ? bEof==bOtherEof : Chris@16: ( Chris@16: m_Match==Other.m_Match && Chris@16: m_End==Other.m_End Chris@16: ); Chris@16: } Chris@16: Chris@16: public: Chris@16: // operations Chris@16: Chris@16: //! Eof check Chris@16: /*! Chris@16: Check the eof condition. Eof condition means that Chris@16: there is nothing more to be searched i.e. find_iterator Chris@16: is after the last match. Chris@16: */ Chris@16: bool eof() const Chris@16: { Chris@16: return Chris@16: this->is_null() || Chris@16: ( Chris@16: m_Match.begin() == m_End && Chris@16: m_Match.end() == m_End Chris@16: ); Chris@16: } Chris@16: Chris@16: private: Chris@16: // Attributes Chris@16: match_type m_Match; Chris@16: input_iterator_type m_End; Chris@16: }; Chris@16: Chris@16: //! find iterator construction helper Chris@16: /*! Chris@16: * Construct a find iterator to iterate through the specified string Chris@16: */ Chris@16: template Chris@16: inline find_iterator< Chris@16: BOOST_STRING_TYPENAME range_iterator::type> Chris@16: make_find_iterator( Chris@16: RangeT& Collection, Chris@16: FinderT Finder) Chris@16: { Chris@16: return find_iterator::type>( Chris@16: Collection, Finder); Chris@16: } Chris@16: Chris@16: // split iterator -----------------------------------------------// Chris@16: Chris@16: //! split_iterator Chris@16: /*! Chris@16: Split iterator encapsulates a Finder and allows Chris@16: for incremental searching in a string. Chris@16: Unlike the find iterator, split iterator iterates Chris@16: through gaps between matches. Chris@16: Chris@16: Find iterator is a readable forward traversal iterator. Chris@16: Chris@16: Dereferencing the iterator yields an iterator_range delimiting Chris@16: the current match. Chris@16: */ Chris@16: template Chris@16: class split_iterator : Chris@16: public iterator_facade< Chris@16: split_iterator, Chris@16: const iterator_range, Chris@16: forward_traversal_tag >, Chris@16: private detail::find_iterator_base Chris@16: { Chris@16: private: Chris@16: // facade support Chris@16: friend class ::boost::iterator_core_access; Chris@16: Chris@16: private: Chris@16: // typedefs Chris@16: Chris@16: typedef detail::find_iterator_base base_type; Chris@16: typedef BOOST_STRING_TYPENAME Chris@16: base_type::input_iterator_type input_iterator_type; Chris@16: typedef BOOST_STRING_TYPENAME Chris@16: base_type::match_type match_type; Chris@16: Chris@16: public: Chris@16: //! Default constructor Chris@16: /*! Chris@16: Construct null iterator. All null iterators are equal. Chris@16: Chris@16: \post eof()==true Chris@16: */ Chris@101: split_iterator() : Chris@101: m_Next(), Chris@101: m_End(), Chris@101: m_bEof(true) Chris@101: {} Chris@101: Chris@16: //! Copy constructor Chris@16: /*! Chris@16: Construct a copy of the split_iterator Chris@16: */ Chris@16: split_iterator( const split_iterator& Other ) : Chris@16: base_type(Other), Chris@16: m_Match(Other.m_Match), Chris@16: m_Next(Other.m_Next), Chris@16: m_End(Other.m_End), Chris@16: m_bEof(Other.m_bEof) Chris@16: {} Chris@16: Chris@16: //! Constructor Chris@16: /*! Chris@16: Construct new split_iterator for a given finder Chris@16: and a range. Chris@16: */ Chris@16: template Chris@16: split_iterator( Chris@16: IteratorT Begin, Chris@16: IteratorT End, Chris@16: FinderT Finder ) : Chris@16: detail::find_iterator_base(Finder,0), Chris@16: m_Match(Begin,Begin), Chris@16: m_Next(Begin), Chris@16: m_End(End), Chris@16: m_bEof(false) Chris@16: { Chris@16: // force the correct behavior for empty sequences and yield at least one token Chris@16: if(Begin!=End) Chris@16: { Chris@16: increment(); Chris@16: } Chris@16: } Chris@16: //! Constructor Chris@16: /*! Chris@16: Construct new split_iterator for a given finder Chris@16: and a collection. Chris@16: */ Chris@16: template Chris@16: split_iterator( Chris@16: RangeT& Col, Chris@16: FinderT Finder ) : Chris@16: detail::find_iterator_base(Finder,0), Chris@16: m_bEof(false) Chris@16: { Chris@16: iterator_range::type> lit_col(::boost::as_literal(Col)); Chris@16: m_Match=make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col)); Chris@16: m_Next=::boost::begin(lit_col); Chris@16: m_End=::boost::end(lit_col); Chris@16: Chris@16: // force the correct behavior for empty sequences and yield at least one token Chris@16: if(m_Next!=m_End) Chris@16: { Chris@16: increment(); Chris@16: } Chris@16: } Chris@16: Chris@16: Chris@16: private: Chris@16: // iterator operations Chris@16: Chris@16: // dereference Chris@16: const match_type& dereference() const Chris@16: { Chris@16: return m_Match; Chris@16: } Chris@16: Chris@16: // increment Chris@16: void increment() Chris@16: { Chris@16: match_type FindMatch=this->do_find( m_Next, m_End ); Chris@16: Chris@16: if(FindMatch.begin()==m_End && FindMatch.end()==m_End) Chris@16: { Chris@16: if(m_Match.end()==m_End) Chris@16: { Chris@16: // Mark iterator as eof Chris@16: m_bEof=true; Chris@16: } Chris@16: } Chris@16: Chris@16: m_Match=match_type( m_Next, FindMatch.begin() ); Chris@16: m_Next=FindMatch.end(); Chris@16: } Chris@16: Chris@16: // comparison Chris@16: bool equal( const split_iterator& Other ) const Chris@16: { Chris@16: bool bEof=eof(); Chris@16: bool bOtherEof=Other.eof(); Chris@16: Chris@16: return bEof || bOtherEof ? bEof==bOtherEof : Chris@16: ( Chris@16: m_Match==Other.m_Match && Chris@16: m_Next==Other.m_Next && Chris@16: m_End==Other.m_End Chris@16: ); Chris@16: } Chris@16: Chris@16: public: Chris@16: // operations Chris@16: Chris@16: //! Eof check Chris@16: /*! Chris@16: Check the eof condition. Eof condition means that Chris@16: there is nothing more to be searched i.e. find_iterator Chris@16: is after the last match. Chris@16: */ Chris@16: bool eof() const Chris@16: { Chris@16: return this->is_null() || m_bEof; Chris@16: } Chris@16: Chris@16: private: Chris@16: // Attributes Chris@16: match_type m_Match; Chris@16: input_iterator_type m_Next; Chris@16: input_iterator_type m_End; Chris@16: bool m_bEof; Chris@16: }; Chris@16: Chris@16: //! split iterator construction helper Chris@16: /*! Chris@16: * Construct a split iterator to iterate through the specified collection Chris@16: */ Chris@16: template Chris@16: inline split_iterator< Chris@16: BOOST_STRING_TYPENAME range_iterator::type> Chris@16: make_split_iterator( Chris@16: RangeT& Collection, Chris@16: FinderT Finder) Chris@16: { Chris@16: return split_iterator::type>( Chris@16: Collection, Finder); Chris@16: } Chris@16: Chris@16: Chris@16: } // namespace algorithm Chris@16: Chris@16: // pull names to the boost namespace Chris@16: using algorithm::find_iterator; Chris@16: using algorithm::make_find_iterator; Chris@16: using algorithm::split_iterator; Chris@16: using algorithm::make_split_iterator; Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: Chris@16: #endif // BOOST_STRING_FIND_ITERATOR_HPP