diff --git a/include/boost/algorithm/string/detail/finder.hpp b/include/boost/algorithm/string/detail/finder.hpp index 2162264..4dc2fe7 100644 --- a/include/boost/algorithm/string/detail/finder.hpp +++ b/include/boost/algorithm/string/detail/finder.hpp @@ -90,7 +90,7 @@ namespace boost { // find last functor -----------------------------------------------// - // find the last match a subsequnce in the sequence ( functor ) + // find the last match a subseqeunce in the sequence ( functor ) /* Returns a pair marking the subsequence in the sequence. If the find fails, returns @@ -200,7 +200,7 @@ namespace boost { // find n-th functor -----------------------------------------------// - // find the n-th match of a subsequnce in the sequence ( functor ) + // find the n-th match of a subsequence in the sequence ( functor ) /* Returns a pair marking the subsequence in the sequence. If the find fails, returns @@ -212,12 +212,15 @@ namespace boost { 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, - unsigned int Nth, + int Nth, PredicateT Comp) : m_Search(begin(Search), end(Search)), m_Nth(Nth), @@ -225,7 +228,7 @@ namespace boost { nth_finderF( search_iterator_type SearchBegin, search_iterator_type SearchEnd, - unsigned int Nth, + int Nth, PredicateT Comp) : m_Search(SearchBegin, SearchEnd), m_Nth(Nth), @@ -237,6 +240,26 @@ namespace boost { 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 + find_forward( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N) const { typedef ForwardIteratorT input_iterator_type; typedef iterator_range result_type; @@ -245,13 +268,13 @@ namespace boost { if( boost::empty(m_Search) ) return result_type( End, End ); - // Instantiate find funtor + // 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<=m_Nth; ++n ) + for( unsigned int n=0; n<=N; ++n ) { // find next match M=first_finder( end(M), End ); @@ -266,14 +289,101 @@ namespace boost { return M; } + template< typename ForwardIteratorT > + iterator_range + find_backward( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N) const + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range 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, begin(M) ); + + if ( !M ) + { + // Subsequence not found, return + return M; + } + } + + return M; + } + + private: iterator_range m_Search; - unsigned int m_Nth; + int m_Nth; PredicateT m_Comp; }; // find head functor -----------------------------------------------// + // Find head implementation + template + iterator_range + find_head_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N ) + { + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return find_head_impl( Begin, End, N, category() ); + } + + template + iterator_range + find_head_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::forward_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + input_iterator_type It=Begin; + for( + unsigned int Index=0; + Index + iterator_range + find_head_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::random_access_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + if ( (End<=Begin) || ( static_cast(End-Begin) < N ) ) + return result_type( Begin, End ); + + return result_type(Begin,Begin+N); + } + + // find a head in the sequence ( functor ) /* This functor find a head of the specified range. For @@ -283,7 +393,7 @@ namespace boost { struct head_finderF { // Construction - head_finderF( unsigned int N ) : m_N(N) {} + head_finderF( int N ) : m_N(N) {} // Operation template< typename ForwardIteratorT > @@ -292,54 +402,99 @@ namespace boost { ForwardIteratorT Begin, ForwardIteratorT End ) const { - typedef BOOST_STRING_TYPENAME boost::detail:: - iterator_traits::iterator_category category; + if(m_N>=0) + { + return find_head_impl( Begin, End, m_N ); + } + else + { + iterator_range Res= + find_tail_impl( Begin, End, -m_N ); - return findit( Begin, End, category() ); + return make_iterator_range(Begin, Res.begin()); + } } private: - // Find operation implementation - template< typename ForwardIteratorT > - iterator_range - findit( - ForwardIteratorT Begin, - ForwardIteratorT End, - std::forward_iterator_tag ) const - { - typedef ForwardIteratorT input_iterator_type; - typedef iterator_range result_type; - - input_iterator_type It=Begin; - for( - unsigned int Index=0; - Index - iterator_range - findit( - ForwardIteratorT Begin, - ForwardIteratorT End, - std::random_access_iterator_tag ) const - { - typedef ForwardIteratorT input_iterator_type; - typedef iterator_range result_type; - - if ( (End<=Begin) || ( static_cast(End-Begin) < m_N ) ) - return result_type( Begin, End ); - - return result_type(Begin,Begin+m_N); - } - - private: - unsigned int m_N; + int m_N; }; // find tail functor -----------------------------------------------// + // Operation + template< typename ForwardIteratorT > + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N ) + { + typedef BOOST_STRING_TYPENAME boost::detail:: + iterator_traits::iterator_category category; + + return find_tail_impl( Begin, End, N, category() ); + } + + template< typename ForwardIteratorT > + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::forward_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range 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 + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::bidirectional_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + input_iterator_type It=End; + for( + unsigned int Index=0; + Index + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::random_access_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + if ( (End<=Begin) || ( static_cast(End-Begin) < N ) ) + return result_type( Begin, End ); + + return result_type( End-N, End ); + } + // find a tail in the sequence ( functor ) /* This functor find a tail of the specified range. For @@ -349,7 +504,7 @@ namespace boost { struct tail_finderF { // Construction - tail_finderF( unsigned int N ) : m_N(N) {} + tail_finderF( int N ) : m_N(N) {} // Operation template< typename ForwardIteratorT > @@ -358,74 +513,21 @@ namespace boost { ForwardIteratorT Begin, ForwardIteratorT End ) const { - typedef BOOST_STRING_TYPENAME boost::detail:: - iterator_traits::iterator_category category; + if(m_N>=0) + { + return find_tail_impl( Begin, End, m_N ); + } + else + { + iterator_range Res= + find_head_impl( Begin, End, -m_N ); - return findit( Begin, End, category() ); + return make_iterator_range(Res.end(), End); + } } private: - // Find operation implementation - template< typename ForwardIteratorT > - iterator_range - findit( - ForwardIteratorT Begin, - ForwardIteratorT End, - std::forward_iterator_tag ) const - { - typedef ForwardIteratorT input_iterator_type; - typedef iterator_range result_type; - - unsigned int Index=0; - input_iterator_type It=Begin; - input_iterator_type It2=Begin; - - // Advance It2 by N incremets - for( Index=0; Index - iterator_range - findit( - ForwardIteratorT Begin, - ForwardIteratorT End, - std::bidirectional_iterator_tag ) const - { - typedef ForwardIteratorT input_iterator_type; - typedef iterator_range result_type; - - input_iterator_type It=End; - for( - unsigned int Index=0; - Index - iterator_range - findit( - ForwardIteratorT Begin, - ForwardIteratorT End, - std::random_access_iterator_tag ) const - { - typedef ForwardIteratorT input_iterator_type; - typedef iterator_range result_type; - - if ( (End<=Begin) || ( static_cast(End-Begin) < m_N ) ) - return result_type( Begin, End ); - - return result_type( End-m_N, End ); - } - - - private: - unsigned int m_N; + int m_N; }; // find token functor -----------------------------------------------// @@ -475,7 +577,7 @@ namespace boost { } else { - // Advance by one possition + // Advance by one position ++It2; } diff --git a/include/boost/algorithm/string/erase.hpp b/include/boost/algorithm/string/erase.hpp index dd499d6..0915e72 100644 --- a/include/boost/algorithm/string/erase.hpp +++ b/include/boost/algorithm/string/erase.hpp @@ -400,7 +400,7 @@ namespace boost { OutputIteratorT Output, const Range1T& Input, const Range2T& Search, - unsigned int Nth ) + int Nth ) { return find_format_copy( Output, @@ -417,7 +417,7 @@ namespace boost { inline SequenceT erase_nth_copy( const SequenceT& Input, const RangeT& Search, - unsigned int Nth ) + int Nth ) { return find_format_copy( Input, @@ -438,7 +438,7 @@ namespace boost { inline void erase_nth( SequenceT& Input, const RangeT& Search, - unsigned int Nth ) + int Nth ) { find_format( Input, @@ -473,7 +473,7 @@ namespace boost { OutputIteratorT Output, const Range1T& Input, const Range2T& Search, - unsigned int Nth, + int Nth, const std::locale& Loc=std::locale() ) { return find_format_copy( @@ -491,7 +491,7 @@ namespace boost { inline SequenceT ierase_nth_copy( const SequenceT& Input, const RangeT& Search, - unsigned int Nth, + int Nth, const std::locale& Loc=std::locale() ) { return find_format_copy( @@ -514,7 +514,7 @@ namespace boost { inline void ierase_nth( SequenceT& Input, const RangeT& Search, - unsigned int Nth, + int Nth, const std::locale& Loc=std::locale() ) { find_format( @@ -687,7 +687,7 @@ namespace boost { inline OutputIteratorT erase_head_copy( OutputIteratorT Output, const RangeT& Input, - unsigned int N ) + int N ) { return find_format_copy( Output, @@ -703,7 +703,7 @@ namespace boost { template inline SequenceT erase_head_copy( const SequenceT& Input, - unsigned int N ) + int N ) { return find_format_copy( Input, @@ -723,7 +723,7 @@ namespace boost { template inline void erase_head( SequenceT& Input, - unsigned int N ) + int N ) { find_format( Input, @@ -755,7 +755,7 @@ namespace boost { inline OutputIteratorT erase_tail_copy( OutputIteratorT Output, const RangeT& Input, - unsigned int N ) + int N ) { return find_format_copy( Output, @@ -771,7 +771,7 @@ namespace boost { template inline SequenceT erase_tail_copy( const SequenceT& Input, - unsigned int N ) + int N ) { return find_format_copy( Input, @@ -791,7 +791,7 @@ namespace boost { template inline void erase_tail( SequenceT& Input, - unsigned int N ) + int N ) { find_format( Input, diff --git a/include/boost/algorithm/string/find.hpp b/include/boost/algorithm/string/find.hpp index 8a2d820..b5119ac 100644 --- a/include/boost/algorithm/string/find.hpp +++ b/include/boost/algorithm/string/find.hpp @@ -188,7 +188,7 @@ namespace boost { find_nth( Range1T& Input, const Range2T& Search, - unsigned int Nth) + int Nth) { return nth_finder(Search,Nth)( begin(Input),end(Input)); @@ -218,7 +218,7 @@ namespace boost { ifind_nth( Range1T& Input, const Range2T& Search, - unsigned int Nth, + int Nth, const std::locale& Loc=std::locale()) { return nth_finder(Search,Nth,is_iequal(Loc))( @@ -248,7 +248,7 @@ namespace boost { BOOST_STRING_TYPENAME range_result_iterator::type> find_head( RangeT& Input, - unsigned int N) + int N) { return head_finder(N)( begin(Input),end(Input)); @@ -278,7 +278,7 @@ namespace boost { BOOST_STRING_TYPENAME range_result_iterator::type> find_tail( RangeT& Input, - unsigned int N) + int N) { return tail_finder(N)( begin(Input),end(Input)); diff --git a/include/boost/algorithm/string/finder.hpp b/include/boost/algorithm/string/finder.hpp index 8c4962e..8ed21a7 100644 --- a/include/boost/algorithm/string/finder.hpp +++ b/include/boost/algorithm/string/finder.hpp @@ -132,7 +132,7 @@ namespace boost { is_equal> nth_finder( const ContainerT& Search, - unsigned int Nth) + int Nth) { return detail::nth_finderF< @@ -150,7 +150,7 @@ namespace boost { PredicateT> nth_finder( const ContainerT& Search, - unsigned int Nth, + int Nth, PredicateT Comp ) { return @@ -172,7 +172,7 @@ namespace boost { \return An instance of the \c head_finder object */ inline detail::head_finderF - head_finder( unsigned int N ) + head_finder( int N ) { return detail::head_finderF(N); } @@ -189,7 +189,7 @@ namespace boost { \return An instance of the \c tail_finder object */ inline detail::tail_finderF - tail_finder( unsigned int N ) + tail_finder( int N ) { return detail::tail_finderF(N); } diff --git a/include/boost/algorithm/string/replace.hpp b/include/boost/algorithm/string/replace.hpp index 768aa3d..3a5df1f 100644 --- a/include/boost/algorithm/string/replace.hpp +++ b/include/boost/algorithm/string/replace.hpp @@ -443,7 +443,7 @@ namespace boost { OutputIteratorT Output, const Range1T& Input, const Range2T& Search, - unsigned int Nth, + int Nth, const Range3T& Format ) { return find_format_copy( @@ -461,7 +461,7 @@ namespace boost { inline SequenceT replace_nth_copy( const SequenceT& Input, const Range1T& Search, - unsigned int Nth, + int Nth, const Range2T& Format ) { return find_format_copy( @@ -484,7 +484,7 @@ namespace boost { inline void replace_nth( SequenceT& Input, const Range1T& Search, - unsigned int Nth, + int Nth, const Range2T& Format ) { find_format( @@ -523,7 +523,7 @@ namespace boost { OutputIteratorT Output, const Range1T& Input, const Range2T& Search, - unsigned int Nth, + int Nth, const Range3T& Format, const std::locale& Loc=std::locale() ) { @@ -542,7 +542,7 @@ namespace boost { inline SequenceT ireplace_nth_copy( const SequenceT& Input, const Range1T& Search, - unsigned int Nth, + int Nth, const Range2T& Format, const std::locale& Loc=std::locale() ) { @@ -568,7 +568,7 @@ namespace boost { inline void ireplace_nth( SequenceT& Input, const Range1T& Search, - unsigned int Nth, + int Nth, const Range2T& Format, const std::locale& Loc=std::locale() ) { @@ -759,7 +759,7 @@ namespace boost { inline OutputIteratorT replace_head_copy( OutputIteratorT Output, const Range1T& Input, - unsigned int N, + int N, const Range2T& Format ) { return find_format_copy( @@ -776,7 +776,7 @@ namespace boost { template inline SequenceT replace_head_copy( const SequenceT& Input, - unsigned int N, + int N, const RangeT& Format ) { return find_format_copy( @@ -799,7 +799,7 @@ namespace boost { template inline void replace_head( SequenceT& Input, - unsigned int N, + int N, const RangeT& Format ) { find_format( @@ -835,7 +835,7 @@ namespace boost { inline OutputIteratorT replace_tail_copy( OutputIteratorT Output, const Range1T& Input, - unsigned int N, + int N, const Range2T& Format ) { return find_format_copy( @@ -852,7 +852,7 @@ namespace boost { template inline SequenceT replace_tail_copy( const SequenceT& Input, - unsigned int N, + int N, const RangeT& Format ) { return find_format_copy( @@ -875,7 +875,7 @@ namespace boost { template inline void replace_tail( SequenceT& Input, - unsigned int N, + int N, const RangeT& Format ) { find_format(