You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
383 lines
12 KiB
383 lines
12 KiB
// Boost string_algo library find_iterator.hpp header file ---------------------------// |
|
|
|
// Copyright Pavol Droba 2002-2004. |
|
// |
|
// 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_FIND_ITERATOR_HPP |
|
#define BOOST_STRING_FIND_ITERATOR_HPP |
|
|
|
#include <boost/algorithm/string/config.hpp> |
|
#include <boost/iterator/iterator_facade.hpp> |
|
#include <boost/iterator/iterator_categories.hpp> |
|
|
|
#include <boost/range/iterator_range.hpp> |
|
#include <boost/range/begin.hpp> |
|
#include <boost/range/end.hpp> |
|
#include <boost/range/iterator.hpp> |
|
#include <boost/range/as_literal.hpp> |
|
|
|
#include <boost/algorithm/string/detail/find_iterator.hpp> |
|
|
|
/*! \file |
|
Defines find iterator classes. Find iterator repeatedly applies a Finder |
|
to the specified input string to search for matches. Dereferencing |
|
the iterator yields the current match or a range between the last and the current |
|
match depending on the iterator used. |
|
*/ |
|
|
|
namespace boost { |
|
namespace algorithm { |
|
|
|
// find_iterator -----------------------------------------------// |
|
|
|
//! find_iterator |
|
/*! |
|
Find iterator encapsulates a Finder and allows |
|
for incremental searching in a string. |
|
Each increment moves the iterator to the next match. |
|
|
|
Find iterator is a readable forward traversal iterator. |
|
|
|
Dereferencing the iterator yields an iterator_range delimiting |
|
the current match. |
|
*/ |
|
template<typename IteratorT> |
|
class find_iterator : |
|
public iterator_facade< |
|
find_iterator<IteratorT>, |
|
const iterator_range<IteratorT>, |
|
forward_traversal_tag >, |
|
private detail::find_iterator_base<IteratorT> |
|
{ |
|
private: |
|
// facade support |
|
friend class ::boost::iterator_core_access; |
|
|
|
private: |
|
// typedefs |
|
|
|
typedef detail::find_iterator_base<IteratorT> base_type; |
|
typedef BOOST_STRING_TYPENAME |
|
base_type::input_iterator_type input_iterator_type; |
|
typedef BOOST_STRING_TYPENAME |
|
base_type::match_type match_type; |
|
|
|
public: |
|
//! Default constructor |
|
/*! |
|
Construct null iterator. All null iterators are equal. |
|
|
|
\post eof()==true |
|
*/ |
|
find_iterator() {} |
|
|
|
//! Copy constructor |
|
/*! |
|
Construct a copy of the find_iterator |
|
*/ |
|
find_iterator( const find_iterator& Other ) : |
|
base_type(Other), |
|
m_Match(Other.m_Match), |
|
m_End(Other.m_End) {} |
|
|
|
//! Constructor |
|
/*! |
|
Construct new find_iterator for a given finder |
|
and a range. |
|
*/ |
|
template<typename FinderT> |
|
find_iterator( |
|
IteratorT Begin, |
|
IteratorT End, |
|
FinderT Finder ) : |
|
detail::find_iterator_base<IteratorT>(Finder,0), |
|
m_Match(Begin,Begin), |
|
m_End(End) |
|
{ |
|
increment(); |
|
} |
|
|
|
//! Constructor |
|
/*! |
|
Construct new find_iterator for a given finder |
|
and a range. |
|
*/ |
|
template<typename FinderT, typename RangeT> |
|
find_iterator( |
|
RangeT& Col, |
|
FinderT Finder ) : |
|
detail::find_iterator_base<IteratorT>(Finder,0) |
|
{ |
|
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col)); |
|
m_Match=::boost::make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col)); |
|
m_End=::boost::end(lit_col); |
|
|
|
increment(); |
|
} |
|
|
|
private: |
|
// iterator operations |
|
|
|
// dereference |
|
const match_type& dereference() const |
|
{ |
|
return m_Match; |
|
} |
|
|
|
// increment |
|
void increment() |
|
{ |
|
m_Match=this->do_find(m_Match.end(),m_End); |
|
} |
|
|
|
// comparison |
|
bool equal( const find_iterator& Other ) const |
|
{ |
|
bool bEof=eof(); |
|
bool bOtherEof=Other.eof(); |
|
|
|
return bEof || bOtherEof ? bEof==bOtherEof : |
|
( |
|
m_Match==Other.m_Match && |
|
m_End==Other.m_End |
|
); |
|
} |
|
|
|
public: |
|
// operations |
|
|
|
//! Eof check |
|
/*! |
|
Check the eof condition. Eof condition means that |
|
there is nothing more to be searched i.e. find_iterator |
|
is after the last match. |
|
*/ |
|
bool eof() const |
|
{ |
|
return |
|
this->is_null() || |
|
( |
|
m_Match.begin() == m_End && |
|
m_Match.end() == m_End |
|
); |
|
} |
|
|
|
private: |
|
// Attributes |
|
match_type m_Match; |
|
input_iterator_type m_End; |
|
}; |
|
|
|
//! find iterator construction helper |
|
/*! |
|
* Construct a find iterator to iterate through the specified string |
|
*/ |
|
template<typename RangeT, typename FinderT> |
|
inline find_iterator< |
|
BOOST_STRING_TYPENAME range_iterator<RangeT>::type> |
|
make_find_iterator( |
|
RangeT& Collection, |
|
FinderT Finder) |
|
{ |
|
return find_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>( |
|
Collection, Finder); |
|
} |
|
|
|
// split iterator -----------------------------------------------// |
|
|
|
//! split_iterator |
|
/*! |
|
Split iterator encapsulates a Finder and allows |
|
for incremental searching in a string. |
|
Unlike the find iterator, split iterator iterates |
|
through gaps between matches. |
|
|
|
Find iterator is a readable forward traversal iterator. |
|
|
|
Dereferencing the iterator yields an iterator_range delimiting |
|
the current match. |
|
*/ |
|
template<typename IteratorT> |
|
class split_iterator : |
|
public iterator_facade< |
|
split_iterator<IteratorT>, |
|
const iterator_range<IteratorT>, |
|
forward_traversal_tag >, |
|
private detail::find_iterator_base<IteratorT> |
|
{ |
|
private: |
|
// facade support |
|
friend class ::boost::iterator_core_access; |
|
|
|
private: |
|
// typedefs |
|
|
|
typedef detail::find_iterator_base<IteratorT> base_type; |
|
typedef BOOST_STRING_TYPENAME |
|
base_type::input_iterator_type input_iterator_type; |
|
typedef BOOST_STRING_TYPENAME |
|
base_type::match_type match_type; |
|
|
|
public: |
|
//! Default constructor |
|
/*! |
|
Construct null iterator. All null iterators are equal. |
|
|
|
\post eof()==true |
|
*/ |
|
split_iterator() {} |
|
//! Copy constructor |
|
/*! |
|
Construct a copy of the split_iterator |
|
*/ |
|
split_iterator( const split_iterator& Other ) : |
|
base_type(Other), |
|
m_Match(Other.m_Match), |
|
m_Next(Other.m_Next), |
|
m_End(Other.m_End), |
|
m_bEof(Other.m_bEof) |
|
{} |
|
|
|
//! Constructor |
|
/*! |
|
Construct new split_iterator for a given finder |
|
and a range. |
|
*/ |
|
template<typename FinderT> |
|
split_iterator( |
|
IteratorT Begin, |
|
IteratorT End, |
|
FinderT Finder ) : |
|
detail::find_iterator_base<IteratorT>(Finder,0), |
|
m_Match(Begin,Begin), |
|
m_Next(Begin), |
|
m_End(End), |
|
m_bEof(false) |
|
{ |
|
// force the correct behavior for empty sequences and yield at least one token |
|
if(Begin!=End) |
|
{ |
|
increment(); |
|
} |
|
} |
|
//! Constructor |
|
/*! |
|
Construct new split_iterator for a given finder |
|
and a collection. |
|
*/ |
|
template<typename FinderT, typename RangeT> |
|
split_iterator( |
|
RangeT& Col, |
|
FinderT Finder ) : |
|
detail::find_iterator_base<IteratorT>(Finder,0), |
|
m_bEof(false) |
|
{ |
|
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col)); |
|
m_Match=make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col)); |
|
m_Next=::boost::begin(lit_col); |
|
m_End=::boost::end(lit_col); |
|
|
|
// force the correct behavior for empty sequences and yield at least one token |
|
if(m_Next!=m_End) |
|
{ |
|
increment(); |
|
} |
|
} |
|
|
|
|
|
private: |
|
// iterator operations |
|
|
|
// dereference |
|
const match_type& dereference() const |
|
{ |
|
return m_Match; |
|
} |
|
|
|
// increment |
|
void increment() |
|
{ |
|
match_type FindMatch=this->do_find( m_Next, m_End ); |
|
|
|
if(FindMatch.begin()==m_End && FindMatch.end()==m_End) |
|
{ |
|
if(m_Match.end()==m_End) |
|
{ |
|
// Mark iterator as eof |
|
m_bEof=true; |
|
} |
|
} |
|
|
|
m_Match=match_type( m_Next, FindMatch.begin() ); |
|
m_Next=FindMatch.end(); |
|
} |
|
|
|
// comparison |
|
bool equal( const split_iterator& Other ) const |
|
{ |
|
bool bEof=eof(); |
|
bool bOtherEof=Other.eof(); |
|
|
|
return bEof || bOtherEof ? bEof==bOtherEof : |
|
( |
|
m_Match==Other.m_Match && |
|
m_Next==Other.m_Next && |
|
m_End==Other.m_End |
|
); |
|
} |
|
|
|
public: |
|
// operations |
|
|
|
//! Eof check |
|
/*! |
|
Check the eof condition. Eof condition means that |
|
there is nothing more to be searched i.e. find_iterator |
|
is after the last match. |
|
*/ |
|
bool eof() const |
|
{ |
|
return this->is_null() || m_bEof; |
|
} |
|
|
|
private: |
|
// Attributes |
|
match_type m_Match; |
|
input_iterator_type m_Next; |
|
input_iterator_type m_End; |
|
bool m_bEof; |
|
}; |
|
|
|
//! split iterator construction helper |
|
/*! |
|
* Construct a split iterator to iterate through the specified collection |
|
*/ |
|
template<typename RangeT, typename FinderT> |
|
inline split_iterator< |
|
BOOST_STRING_TYPENAME range_iterator<RangeT>::type> |
|
make_split_iterator( |
|
RangeT& Collection, |
|
FinderT Finder) |
|
{ |
|
return split_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>( |
|
Collection, Finder); |
|
} |
|
|
|
|
|
} // namespace algorithm |
|
|
|
// pull names to the boost namespace |
|
using algorithm::find_iterator; |
|
using algorithm::make_find_iterator; |
|
using algorithm::split_iterator; |
|
using algorithm::make_split_iterator; |
|
|
|
} // namespace boost |
|
|
|
|
|
#endif // BOOST_STRING_FIND_ITERATOR_HPP
|
|
|