123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640 |
- // Boost string_algo library finder.hpp header file ---------------------------//
- // Copyright Pavol Droba 2002-2006.
- //
- // Distributed under 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)
- // See http://www.boost.org/ for updates, documentation, and revision history.
- #ifndef BOOST_STRING_FINDER_DETAIL_HPP
- #define BOOST_STRING_FINDER_DETAIL_HPP
- #include <boost/algorithm/string/config.hpp>
- #include <boost/algorithm/string/constants.hpp>
- #include <boost/detail/iterator.hpp>
- #include <boost/range/iterator_range_core.hpp>
- #include <boost/range/begin.hpp>
- #include <boost/range/end.hpp>
- #include <boost/range/empty.hpp>
- #include <boost/range/as_literal.hpp>
- namespace boost {
- namespace algorithm {
- namespace detail {
- // find first functor -----------------------------------------------//
- // find a subsequence in the sequence ( functor )
- /*
- Returns a pair <begin,end> marking the subsequence in the sequence.
- If the find fails, functor returns <End,End>
- */
- template<typename SearchIteratorT,typename PredicateT>
- struct first_finderF
- {
- typedef SearchIteratorT search_iterator_type;
- // Construction
- template< typename SearchT >
- first_finderF( const SearchT& Search, PredicateT Comp ) :
- m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {}
- first_finderF(
- search_iterator_type SearchBegin,
- search_iterator_type SearchEnd,
- PredicateT Comp ) :
- m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {}
- // Operation
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- operator()(
- ForwardIteratorT Begin,
- ForwardIteratorT End ) const
- {
- typedef iterator_range<ForwardIteratorT> result_type;
- typedef ForwardIteratorT input_iterator_type;
- // Outer loop
- for(input_iterator_type OuterIt=Begin;
- OuterIt!=End;
- ++OuterIt)
- {
- // Sanity check
- if( boost::empty(m_Search) )
- return result_type( End, End );
- input_iterator_type InnerIt=OuterIt;
- search_iterator_type SubstrIt=m_Search.begin();
- for(;
- InnerIt!=End && SubstrIt!=m_Search.end();
- ++InnerIt,++SubstrIt)
- {
- if( !( m_Comp(*InnerIt,*SubstrIt) ) )
- break;
- }
- // Substring matching succeeded
- if ( SubstrIt==m_Search.end() )
- return result_type( OuterIt, InnerIt );
- }
- return result_type( End, End );
- }
- private:
- iterator_range<search_iterator_type> m_Search;
- PredicateT m_Comp;
- };
- // find last functor -----------------------------------------------//
- // find the last match a subsequence in the sequence ( functor )
- /*
- Returns a pair <begin,end> marking the subsequence in the sequence.
- If the find fails, returns <End,End>
- */
- template<typename SearchIteratorT, typename PredicateT>
- struct last_finderF
- {
- typedef SearchIteratorT search_iterator_type;
- typedef first_finderF<
- search_iterator_type,
- PredicateT> first_finder_type;
- // Construction
- template< typename SearchT >
- last_finderF( const SearchT& Search, PredicateT Comp ) :
- m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {}
- last_finderF(
- search_iterator_type SearchBegin,
- search_iterator_type SearchEnd,
- PredicateT Comp ) :
- m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {}
- // Operation
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- operator()(
- ForwardIteratorT Begin,
- ForwardIteratorT End ) const
- {
- typedef iterator_range<ForwardIteratorT> result_type;
- if( boost::empty(m_Search) )
- return result_type( End, End );
- typedef BOOST_STRING_TYPENAME boost::detail::
- iterator_traits<ForwardIteratorT>::iterator_category category;
- return findit( Begin, End, category() );
- }
- private:
- // forward iterator
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- findit(
- ForwardIteratorT Begin,
- ForwardIteratorT End,
- std::forward_iterator_tag ) const
- {
- typedef iterator_range<ForwardIteratorT> result_type;
- first_finder_type first_finder(
- m_Search.begin(), m_Search.end(), m_Comp );
- result_type M=first_finder( Begin, End );
- result_type Last=M;
- while( M )
- {
- Last=M;
- M=first_finder( ::boost::end(M), End );
- }
- return Last;
- }
- // bidirectional iterator
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- findit(
- ForwardIteratorT Begin,
- ForwardIteratorT End,
- std::bidirectional_iterator_tag ) const
- {
- typedef iterator_range<ForwardIteratorT> result_type;
- typedef ForwardIteratorT input_iterator_type;
- // Outer loop
- for(input_iterator_type OuterIt=End;
- OuterIt!=Begin; )
- {
- input_iterator_type OuterIt2=--OuterIt;
- input_iterator_type InnerIt=OuterIt2;
- search_iterator_type SubstrIt=m_Search.begin();
- for(;
- InnerIt!=End && SubstrIt!=m_Search.end();
- ++InnerIt,++SubstrIt)
- {
- if( !( m_Comp(*InnerIt,*SubstrIt) ) )
- break;
- }
- // Substring matching succeeded
- if( SubstrIt==m_Search.end() )
- return result_type( OuterIt2, InnerIt );
- }
- return result_type( End, End );
- }
- private:
- iterator_range<search_iterator_type> m_Search;
- PredicateT m_Comp;
- };
- // find n-th functor -----------------------------------------------//
- // find the n-th match of a subsequence in the sequence ( functor )
- /*
- Returns a pair <begin,end> marking the subsequence in the sequence.
- If the find fails, returns <End,End>
- */
- template<typename SearchIteratorT, typename PredicateT>
- struct nth_finderF
- {
- typedef SearchIteratorT search_iterator_type;
- typedef first_finderF<
- search_iterator_type,
- PredicateT> first_finder_type;
- typedef last_finderF<
- search_iterator_type,
- PredicateT> last_finder_type;
- // Construction
- template< typename SearchT >
- nth_finderF(
- const SearchT& Search,
- int Nth,
- PredicateT Comp) :
- m_Search(::boost::begin(Search), ::boost::end(Search)),
- m_Nth(Nth),
- m_Comp(Comp) {}
- nth_finderF(
- search_iterator_type SearchBegin,
- search_iterator_type SearchEnd,
- int Nth,
- PredicateT Comp) :
- m_Search(SearchBegin, SearchEnd),
- m_Nth(Nth),
- m_Comp(Comp) {}
- // Operation
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- operator()(
- ForwardIteratorT Begin,
- ForwardIteratorT End ) const
- {
- if(m_Nth>=0)
- {
- return find_forward(Begin, End, m_Nth);
- }
- else
- {
- return find_backward(Begin, End, -m_Nth);
- }
- }
- private:
- // Implementation helpers
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- find_forward(
- ForwardIteratorT Begin,
- ForwardIteratorT End,
- unsigned int N) const
- {
- typedef iterator_range<ForwardIteratorT> result_type;
- // Sanity check
- if( boost::empty(m_Search) )
- return result_type( End, End );
- // Instantiate find functor
- first_finder_type first_finder(
- m_Search.begin(), m_Search.end(), m_Comp );
- result_type M( Begin, Begin );
- for( unsigned int n=0; n<=N; ++n )
- {
- // find next match
- M=first_finder( ::boost::end(M), End );
- if ( !M )
- {
- // Subsequence not found, return
- return M;
- }
- }
- return M;
- }
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- find_backward(
- ForwardIteratorT Begin,
- ForwardIteratorT End,
- unsigned int N) const
- {
- typedef iterator_range<ForwardIteratorT> result_type;
- // Sanity check
- if( boost::empty(m_Search) )
- return result_type( End, End );
- // Instantiate find functor
- last_finder_type last_finder(
- m_Search.begin(), m_Search.end(), m_Comp );
- result_type M( End, End );
- for( unsigned int n=1; n<=N; ++n )
- {
- // find next match
- M=last_finder( Begin, ::boost::begin(M) );
- if ( !M )
- {
- // Subsequence not found, return
- return M;
- }
- }
- return M;
- }
- private:
- iterator_range<search_iterator_type> m_Search;
- int m_Nth;
- PredicateT m_Comp;
- };
- // find head/tail implementation helpers ---------------------------//
- template<typename ForwardIteratorT>
- iterator_range<ForwardIteratorT>
- find_head_impl(
- ForwardIteratorT Begin,
- ForwardIteratorT End,
- unsigned int N,
- std::forward_iterator_tag )
- {
- typedef ForwardIteratorT input_iterator_type;
- typedef iterator_range<ForwardIteratorT> result_type;
- input_iterator_type It=Begin;
- for(
- unsigned int Index=0;
- Index<N && It!=End; ++Index,++It ) {};
- return result_type( Begin, It );
- }
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- find_head_impl(
- ForwardIteratorT Begin,
- ForwardIteratorT End,
- unsigned int N,
- std::random_access_iterator_tag )
- {
- typedef iterator_range<ForwardIteratorT> result_type;
- if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
- return result_type( Begin, End );
- return result_type(Begin,Begin+N);
- }
- // Find head implementation
- template<typename ForwardIteratorT>
- iterator_range<ForwardIteratorT>
- find_head_impl(
- ForwardIteratorT Begin,
- ForwardIteratorT End,
- unsigned int N )
- {
- typedef BOOST_STRING_TYPENAME boost::detail::
- iterator_traits<ForwardIteratorT>::iterator_category category;
- return ::boost::algorithm::detail::find_head_impl( Begin, End, N, category() );
- }
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- find_tail_impl(
- ForwardIteratorT Begin,
- ForwardIteratorT End,
- unsigned int N,
- std::forward_iterator_tag )
- {
- typedef ForwardIteratorT input_iterator_type;
- typedef iterator_range<ForwardIteratorT> result_type;
- unsigned int Index=0;
- input_iterator_type It=Begin;
- input_iterator_type It2=Begin;
- // Advance It2 by N increments
- for( Index=0; Index<N && It2!=End; ++Index,++It2 ) {};
- // Advance It, It2 to the end
- for(; It2!=End; ++It,++It2 ) {};
- return result_type( It, It2 );
- }
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- find_tail_impl(
- ForwardIteratorT Begin,
- ForwardIteratorT End,
- unsigned int N,
- std::bidirectional_iterator_tag )
- {
- typedef ForwardIteratorT input_iterator_type;
- typedef iterator_range<ForwardIteratorT> result_type;
- input_iterator_type It=End;
- for(
- unsigned int Index=0;
- Index<N && It!=Begin; ++Index,--It ) {};
- return result_type( It, End );
- }
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- find_tail_impl(
- ForwardIteratorT Begin,
- ForwardIteratorT End,
- unsigned int N,
- std::random_access_iterator_tag )
- {
- typedef iterator_range<ForwardIteratorT> result_type;
- if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
- return result_type( Begin, End );
- return result_type( End-N, End );
- }
- // Operation
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- find_tail_impl(
- ForwardIteratorT Begin,
- ForwardIteratorT End,
- unsigned int N )
- {
- typedef BOOST_STRING_TYPENAME boost::detail::
- iterator_traits<ForwardIteratorT>::iterator_category category;
- return ::boost::algorithm::detail::find_tail_impl( Begin, End, N, category() );
- }
- // find head functor -----------------------------------------------//
- // find a head in the sequence ( functor )
- /*
- This functor find a head of the specified range. For
- a specified N, the head is a subsequence of N starting
- elements of the range.
- */
- struct head_finderF
- {
- // Construction
- head_finderF( int N ) : m_N(N) {}
- // Operation
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- operator()(
- ForwardIteratorT Begin,
- ForwardIteratorT End ) const
- {
- if(m_N>=0)
- {
- return ::boost::algorithm::detail::find_head_impl( Begin, End, m_N );
- }
- else
- {
- iterator_range<ForwardIteratorT> Res=
- ::boost::algorithm::detail::find_tail_impl( Begin, End, -m_N );
- return ::boost::make_iterator_range(Begin, Res.begin());
- }
- }
- private:
- int m_N;
- };
- // find tail functor -----------------------------------------------//
- // find a tail in the sequence ( functor )
- /*
- This functor find a tail of the specified range. For
- a specified N, the head is a subsequence of N starting
- elements of the range.
- */
- struct tail_finderF
- {
- // Construction
- tail_finderF( int N ) : m_N(N) {}
- // Operation
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- operator()(
- ForwardIteratorT Begin,
- ForwardIteratorT End ) const
- {
- if(m_N>=0)
- {
- return ::boost::algorithm::detail::find_tail_impl( Begin, End, m_N );
- }
- else
- {
- iterator_range<ForwardIteratorT> Res=
- ::boost::algorithm::detail::find_head_impl( Begin, End, -m_N );
- return ::boost::make_iterator_range(Res.end(), End);
- }
- }
- private:
- int m_N;
- };
- // find token functor -----------------------------------------------//
- // find a token in a sequence ( functor )
- /*
- This find functor finds a token specified be a predicate
- in a sequence. It is equivalent of std::find algorithm,
- with an exception that it return range instead of a single
- iterator.
- If bCompress is set to true, adjacent matching tokens are
- concatenated into one match.
- */
- template< typename PredicateT >
- struct token_finderF
- {
- // Construction
- token_finderF(
- PredicateT Pred,
- token_compress_mode_type eCompress=token_compress_off ) :
- m_Pred(Pred), m_eCompress(eCompress) {}
- // Operation
- template< typename ForwardIteratorT >
- iterator_range<ForwardIteratorT>
- operator()(
- ForwardIteratorT Begin,
- ForwardIteratorT End ) const
- {
- typedef iterator_range<ForwardIteratorT> result_type;
- ForwardIteratorT It=std::find_if( Begin, End, m_Pred );
- if( It==End )
- {
- return result_type( End, End );
- }
- else
- {
- ForwardIteratorT It2=It;
- if( m_eCompress==token_compress_on )
- {
- // Find first non-matching character
- while( It2!=End && m_Pred(*It2) ) ++It2;
- }
- else
- {
- // Advance by one position
- ++It2;
- }
- return result_type( It, It2 );
- }
- }
- private:
- PredicateT m_Pred;
- token_compress_mode_type m_eCompress;
- };
- // find range functor -----------------------------------------------//
- // find a range in the sequence ( functor )
- /*
- This functor actually does not perform any find operation.
- It always returns given iterator range as a result.
- */
- template<typename ForwardIterator1T>
- struct range_finderF
- {
- typedef ForwardIterator1T input_iterator_type;
- typedef iterator_range<input_iterator_type> result_type;
- // Construction
- range_finderF(
- input_iterator_type Begin,
- input_iterator_type End ) : m_Range(Begin, End) {}
- range_finderF(const iterator_range<input_iterator_type>& Range) :
- m_Range(Range) {}
- // Operation
- template< typename ForwardIterator2T >
- iterator_range<ForwardIterator2T>
- operator()(
- ForwardIterator2T,
- ForwardIterator2T ) const
- {
- #if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 )
- return iterator_range<const ForwardIterator2T>(this->m_Range);
- #else
- return m_Range;
- #endif
- }
- private:
- iterator_range<input_iterator_type> m_Range;
- };
- } // namespace detail
- } // namespace algorithm
- } // namespace boost
- #endif // BOOST_STRING_FINDER_DETAIL_HPP
|