mirror of
https://github.com/boostorg/test.git
synced 2026-01-28 07:42:12 +00:00
input_iterator_adaptor simplified
token_iterator added [SVN r23028]
This commit is contained in:
@@ -35,7 +35,7 @@ template<typename CharT>
|
||||
class ifstream_holder {
|
||||
public:
|
||||
// Constructor
|
||||
explicit ifstream_holder( basic_cstring<CharT> file_name )
|
||||
explicit ifstream_holder( basic_cstring<CharT const> file_name )
|
||||
{
|
||||
if( file_name.is_empty() )
|
||||
return;
|
||||
@@ -60,10 +60,10 @@ template<typename CharT>
|
||||
class basic_ifstream_line_iterator : detail::ifstream_holder<CharT>, public basic_istream_line_iterator<CharT>
|
||||
{
|
||||
public:
|
||||
basic_ifstream_line_iterator( basic_cstring<CharT> file_name, CharT delimeter )
|
||||
basic_ifstream_line_iterator( basic_cstring<CharT const> file_name, CharT delimeter )
|
||||
: detail::ifstream_holder<CharT>( file_name ), basic_istream_line_iterator<CharT>( this->m_stream, delimeter ) {}
|
||||
|
||||
explicit basic_ifstream_line_iterator( basic_cstring<CharT> file_name = basic_cstring<CharT>() )
|
||||
explicit basic_ifstream_line_iterator( basic_cstring<CharT const> file_name = basic_cstring<CharT const>() )
|
||||
: detail::ifstream_holder<CharT>( file_name ), basic_istream_line_iterator<CharT>( this->m_stream ) {}
|
||||
};
|
||||
|
||||
@@ -78,6 +78,10 @@ typedef basic_ifstream_line_iterator<wchar_t> wifstream_line_iterator;
|
||||
// Revision History :
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.4 2004/06/05 11:03:12 rogeeff
|
||||
// input_iterator_adaptor simplified
|
||||
// token_iterator added
|
||||
//
|
||||
// Revision 1.3 2004/05/27 07:01:49 rogeeff
|
||||
// portability workarounds
|
||||
//
|
||||
|
||||
@@ -17,79 +17,49 @@
|
||||
|
||||
// Boost
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/mpl/void.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace unit_test {
|
||||
|
||||
namespace detail {
|
||||
// ************************************************************************** //
|
||||
// ************** input_iterator_core_access ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename T>
|
||||
struct value_type_ident
|
||||
class input_iterator_core_access
|
||||
{
|
||||
typedef T value_type;
|
||||
};
|
||||
#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
public:
|
||||
#else
|
||||
template <class I, class V, class R, class TC> friend class input_iterator_facade;
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
struct ref_type_ident
|
||||
{
|
||||
typedef T reference;
|
||||
};
|
||||
template <class Facade>
|
||||
static bool get( Facade& f )
|
||||
{
|
||||
return f.get();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
private:
|
||||
// objects of this class are useless
|
||||
input_iterator_core_access(); //undefined
|
||||
};
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** input_iterator_facade ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename ImplPolicy,typename Derived = mpl::void_,typename ValueType = mpl::void_,typename Reference = mpl::void_>
|
||||
class input_iterator_facade : public iterator_facade<
|
||||
typename mpl::if_<mpl::is_void_<Derived>,input_iterator_facade<ImplPolicy>,Derived>::type,
|
||||
typename mpl::if_<mpl::is_void_<ValueType>,ImplPolicy,detail::value_type_ident<ValueType> >::type::value_type,
|
||||
forward_traversal_tag,
|
||||
typename mpl::if_<mpl::is_void_<Reference>,ImplPolicy,detail::ref_type_ident<Reference> >::type::reference>
|
||||
template<typename Derived,
|
||||
typename ValueType,
|
||||
typename Reference = ValueType const&,
|
||||
typename Traversal = single_pass_traversal_tag>
|
||||
class input_iterator_facade : public iterator_facade<Derived,ValueType,Traversal,Reference>
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
explicit input_iterator_facade( ImplPolicy const& p = ImplPolicy() )
|
||||
: m_policy( p )
|
||||
{
|
||||
increment();
|
||||
}
|
||||
|
||||
//!! copy constructor/assigment - should we make rhs invalid after copy??
|
||||
// input_iterator_facade( input_iterator_facade const& rhs )
|
||||
// : m_policy( rhs.m_policy ), m_valid( rhs.m_valid )
|
||||
// {
|
||||
// const_cast<input_iterator_adaptor&>( rhs ).m_valid = false;
|
||||
// }
|
||||
//
|
||||
// void operator=( input_iterator_facade const& rhs )
|
||||
// {
|
||||
// m_policies = rhs.p_policies;
|
||||
// m_valid = rhs.m_valid;
|
||||
//
|
||||
// const_cast<input_iterator_adaptor&>( rhs ).m_valid = false;
|
||||
// }
|
||||
|
||||
//!! do we need reset method?
|
||||
// void reset()
|
||||
// {
|
||||
// m_valid = m_policy.intialize();
|
||||
//
|
||||
// increment();
|
||||
// }
|
||||
|
||||
protected: // provide access to the derived
|
||||
// Data members
|
||||
ImplPolicy m_policy;
|
||||
|
||||
private:
|
||||
typedef typename mpl::if_<mpl::is_void_<ValueType>,detail::value_type_ident<ValueType>,ImplPolicy>::type::value_type value_type;
|
||||
typedef typename mpl::if_<mpl::is_void_<Reference>,ImplPolicy,detail::ref_type_ident<Reference> >::type::reference reference;
|
||||
input_iterator_facade() : m_valid( false ), m_value() {}
|
||||
|
||||
protected:
|
||||
friend class iterator_core_access;
|
||||
|
||||
// iterator facade interface implementation
|
||||
@@ -97,23 +67,31 @@ private:
|
||||
{
|
||||
// we make post-end incrementation indefinetly safe
|
||||
if( m_valid )
|
||||
m_valid = m_policy.get();
|
||||
m_valid = input_iterator_core_access::get( *static_cast<Derived*>(this) );
|
||||
}
|
||||
bool equal( input_iterator_facade const& rhs ) const
|
||||
Reference dereference() const
|
||||
{
|
||||
// two invalid iterator equals, two valid need to be compared, invalid never equal to valid
|
||||
return !m_valid && !rhs.m_valid || m_valid && rhs.m_valid && m_policy.equal( rhs.m_policy );
|
||||
return m_value;
|
||||
}
|
||||
reference dereference() const
|
||||
{
|
||||
//!! should we call some kind of assert( m_valid ) here instead or do nothing???
|
||||
|
||||
// we pass m_valid inside the policy to decide what to do on attempt to dereference invalid iterator
|
||||
return m_policy.dereference( m_valid );
|
||||
protected: // provide access to the Derived
|
||||
void init()
|
||||
{
|
||||
m_valid = true;
|
||||
increment();
|
||||
}
|
||||
|
||||
// Data members
|
||||
bool m_valid;
|
||||
ValueType m_value;
|
||||
|
||||
private:
|
||||
// iterator facade interface implementation
|
||||
bool equal( input_iterator_facade const& rhs ) const
|
||||
{
|
||||
// two invalid iterator equals, inequal otherwise
|
||||
return !m_valid && !rhs.m_valid;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace unit_test
|
||||
@@ -124,6 +102,10 @@ private:
|
||||
// Revision History :
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.3 2004/06/05 11:03:12 rogeeff
|
||||
// input_iterator_adaptor simplified
|
||||
// token_iterator added
|
||||
//
|
||||
// Revision 1.2 2004/05/25 10:29:09 rogeeff
|
||||
// use standard getline
|
||||
// eliminate initialize
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
// Boost
|
||||
#include <boost/test/detail/basic_cstring/basic_cstring.hpp>
|
||||
#include <boost/test/detail/iterator/input_iterator_facade.hpp>
|
||||
#include <boost/shared_array.hpp>
|
||||
|
||||
// STL
|
||||
#include <iosfwd>
|
||||
@@ -31,44 +30,42 @@ namespace unit_test {
|
||||
// ************** basic_istream_line_iterator ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename CharT>
|
||||
class istream_line_iterator_impl {
|
||||
public:
|
||||
typedef basic_cstring<CharT const> value_type;
|
||||
typedef basic_cstring<CharT const> reference;
|
||||
|
||||
istream_line_iterator_impl( std::basic_istream<CharT>& input, CharT delimeter )
|
||||
: m_input_stream( &input ), m_delimeter( delimeter ) {}
|
||||
|
||||
bool get() { return std::getline( *m_input_stream, m_buffer, m_delimeter ); }
|
||||
reference dereference( bool valid ) const { return m_buffer; }
|
||||
bool equal( istream_line_iterator_impl const& ) const { return false; }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
std::basic_istream<CharT>* m_input_stream;
|
||||
std::basic_string<CharT> m_buffer;
|
||||
CharT m_delimeter;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//!! Should we support policy based delimitation
|
||||
|
||||
template<typename CharT>
|
||||
class basic_istream_line_iterator
|
||||
: public input_iterator_facade<detail::istream_line_iterator_impl<CharT>,basic_istream_line_iterator<CharT> > {
|
||||
typedef detail::istream_line_iterator_impl<CharT> impl;
|
||||
typedef input_iterator_facade<impl,basic_istream_line_iterator<CharT> > base;
|
||||
: public input_iterator_facade<basic_istream_line_iterator<CharT>,
|
||||
std::basic_string<CharT>,
|
||||
basic_cstring<CharT const> > {
|
||||
typedef input_iterator_facade<basic_istream_line_iterator<CharT>,
|
||||
std::basic_string<CharT>,
|
||||
basic_cstring<CharT const> > base;
|
||||
public:
|
||||
// Constructor
|
||||
// Constructors
|
||||
basic_istream_line_iterator() {}
|
||||
basic_istream_line_iterator( std::basic_istream<CharT>& input, CharT delimeter )
|
||||
: base( impl( input, delimeter ) ) {}
|
||||
|
||||
: m_input_stream( &input ), m_delimeter( delimeter )
|
||||
{
|
||||
init();
|
||||
}
|
||||
explicit basic_istream_line_iterator( std::basic_istream<CharT>& input )
|
||||
: base( impl( input, input.widen( '\n' ) ) ) {}
|
||||
: m_input_stream( &input ), m_delimeter( input.widen( '\n' ) )
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
private:
|
||||
friend class input_iterator_core_access;
|
||||
|
||||
// increment implementation
|
||||
bool get()
|
||||
{
|
||||
return std::getline( *m_input_stream, m_value, m_delimeter );
|
||||
}
|
||||
|
||||
// Data members
|
||||
std::basic_istream<CharT>* m_input_stream;
|
||||
CharT m_delimeter;
|
||||
};
|
||||
|
||||
typedef basic_istream_line_iterator<char> istream_line_iterator;
|
||||
@@ -82,6 +79,10 @@ typedef basic_istream_line_iterator<wchar_t> wistream_line_iterator;
|
||||
// Revision History :
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.4 2004/06/05 11:03:12 rogeeff
|
||||
// input_iterator_adaptor simplified
|
||||
// token_iterator added
|
||||
//
|
||||
// Revision 1.3 2004/05/27 07:01:49 rogeeff
|
||||
// portability workarounds
|
||||
//
|
||||
|
||||
559
include/boost/test/detail/iterator/token_iterator.hpp
Normal file
559
include/boost/test/detail/iterator/token_iterator.hpp
Normal file
@@ -0,0 +1,559 @@
|
||||
// (C) Copyright Gennadiy Rozental 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/libs/test for the library home page.
|
||||
//
|
||||
// File : $RCSfile$
|
||||
//
|
||||
// Version : $Revision$
|
||||
//
|
||||
// Description :
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TOKEN_ITERATOR_HPP
|
||||
#define BOOST_TOKEN_ITERATOR_HPP
|
||||
|
||||
// Boost
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
#include <boost/test/detail/iterator/input_iterator_facade.hpp>
|
||||
#include <boost/test/detail/basic_cstring/basic_cstring.hpp>
|
||||
|
||||
// STL
|
||||
#include <iosfwd>
|
||||
#include <cctype>
|
||||
|
||||
#ifdef BOOST_NO_STDC_NAMESPACE
|
||||
namespace std{ using ::ispunct; using ::isspace; }
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace unit_test {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** ti_delimeter_type ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
enum ti_delimeter_type { use_delim, use_ispunct, use_isspace };
|
||||
|
||||
namespace detail {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** delim_policy ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename CharT,typename CharCompare>
|
||||
class delim_policy {
|
||||
typedef basic_cstring<CharT const> cstring;
|
||||
public:
|
||||
// Constructor
|
||||
explicit delim_policy( ti_delimeter_type t = use_delim ) : m_type( t ) {}
|
||||
explicit delim_policy( cstring d, ti_delimeter_type t )
|
||||
{
|
||||
use_delimeters( d, t );
|
||||
}
|
||||
|
||||
void use_delimeters( cstring d, ti_delimeter_type t )
|
||||
{
|
||||
m_delimeters = d;
|
||||
m_type = d.is_empty() ? t : use_delim;
|
||||
}
|
||||
|
||||
bool operator()( CharT c )
|
||||
{
|
||||
switch( m_type ) {
|
||||
case use_delim: {
|
||||
typename cstring::iterator it = m_delimeters.begin();
|
||||
for( ; it != m_delimeters.end(); ++it )
|
||||
if( CharCompare()( *it, c ) )
|
||||
break;
|
||||
return it != m_delimeters.end();
|
||||
}
|
||||
case use_ispunct: return (std::ispunct)( c ) != 0;
|
||||
case use_isspace: return (std::isspace)( c ) != 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Data members
|
||||
cstring m_delimeters;
|
||||
ti_delimeter_type m_type;
|
||||
};
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** token_assigner ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename TraversalTag>
|
||||
struct token_assigner {
|
||||
template<typename Iterator, typename Token>
|
||||
static void assign( Iterator b, Iterator e, Token& t ) { t.assign( b, e ); }
|
||||
|
||||
template<typename Iterator, typename Token>
|
||||
static void append_move( Iterator& b, Token& t ) { ++b; }
|
||||
|
||||
template<typename Token>
|
||||
static void clear( Token& t ) {}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct token_assigner<single_pass_traversal_tag> {
|
||||
template<typename Iterator, typename Token>
|
||||
static void assign( Iterator b, Iterator e, Token& t ) {}
|
||||
|
||||
template<typename Iterator, typename Token>
|
||||
static void append_move( Iterator& b, Token& t ) { t += *b; ++b; }
|
||||
|
||||
template<typename Token>
|
||||
static void clear( Token& t ) { t.clear(); }
|
||||
};
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** default_char_compare ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename CharT>
|
||||
class default_char_compare {
|
||||
public:
|
||||
bool operator()( CharT c1, CharT c2 )
|
||||
{
|
||||
#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
|
||||
return std::string_char_traits<CharT>::eq( c1, c2 );
|
||||
#else
|
||||
return std::char_traits<CharT>::eq( c1, c2 );
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** dropped_delimeters_m ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename CharT>
|
||||
struct dropped_delimeters_m
|
||||
{
|
||||
explicit dropped_delimeters_m( basic_cstring<CharT const> delims )
|
||||
: m_delims( delims ) {}
|
||||
|
||||
template<typename CharCompare>
|
||||
void apply( delim_policy<CharT,CharCompare>& is_drop, delim_policy<CharT,CharCompare>&, bool ) const
|
||||
{
|
||||
is_drop.use_delimeters( m_delims, use_isspace );
|
||||
}
|
||||
|
||||
basic_cstring<CharT const> m_delims;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<>
|
||||
struct dropped_delimeters_m<ti_delimeter_type>
|
||||
{
|
||||
explicit dropped_delimeters_m( ti_delimeter_type type )
|
||||
: m_type( type ) {}
|
||||
|
||||
template<typename CharT, typename CharCompare>
|
||||
void apply( delim_policy<CharT,CharCompare>& is_drop, delim_policy<CharT,CharCompare>&, bool ) const
|
||||
{
|
||||
is_drop.use_delimeters( "", m_type );
|
||||
}
|
||||
|
||||
ti_delimeter_type m_type;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** kept_delimeters_m ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename CharT>
|
||||
struct kept_delimeters_m
|
||||
{
|
||||
explicit kept_delimeters_m( basic_cstring<CharT const> delims, ti_delimeter_type type = use_ispunct )
|
||||
: m_delims( delims ), m_type( type ) {}
|
||||
|
||||
template<typename CharCompare>
|
||||
void apply( delim_policy<CharT,CharCompare>&, delim_policy<CharT,CharCompare>& is_kept, bool ) const
|
||||
{
|
||||
is_kept.use_delimeters( m_delims, m_type );
|
||||
}
|
||||
|
||||
basic_cstring<CharT const> m_delims;
|
||||
ti_delimeter_type m_type;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<>
|
||||
struct kept_delimeters_m<ti_delimeter_type>
|
||||
{
|
||||
explicit kept_delimeters_m( ti_delimeter_type type )
|
||||
: m_type( type ) {}
|
||||
|
||||
template<typename CharT, typename CharCompare>
|
||||
void apply( delim_policy<CharT,CharCompare>&, delim_policy<CharT,CharCompare>& is_kept, bool ) const
|
||||
{
|
||||
is_kept.use_delimeters( "", m_type );
|
||||
}
|
||||
|
||||
ti_delimeter_type m_type;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** keep_empty_tokens_m ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
struct keep_empty_tokens_m
|
||||
{
|
||||
explicit keep_empty_tokens_m( bool v )
|
||||
: m_keep_empty_tokens( v ) {}
|
||||
|
||||
template<typename CharT,typename CharCompare>
|
||||
void apply( delim_policy<CharT,CharCompare>&, delim_policy<CharT,CharCompare>&, bool& keep_empty_tokens ) const
|
||||
{
|
||||
keep_empty_tokens = m_keep_empty_tokens;
|
||||
}
|
||||
|
||||
bool m_keep_empty_tokens;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** modifiers generators ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
static struct dropped_delimeters_generator {
|
||||
template<typename CharT>
|
||||
detail::dropped_delimeters_m<CharT>
|
||||
operator=( basic_cstring<CharT const> d ) { return detail::dropped_delimeters_m<CharT>( d ); }
|
||||
template<typename CharT>
|
||||
detail::dropped_delimeters_m<CharT>
|
||||
operator=( CharT const* d ) { return detail::dropped_delimeters_m<CharT>( basic_cstring<CharT const>( d ) ); }
|
||||
|
||||
detail::dropped_delimeters_m<ti_delimeter_type>
|
||||
operator=( ti_delimeter_type t ) { return detail::dropped_delimeters_m<ti_delimeter_type>( t ); }
|
||||
} dropped_delimeters;
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
static struct kept_delimeters_generator {
|
||||
template<typename CharT>
|
||||
detail::kept_delimeters_m<CharT>
|
||||
operator=( basic_cstring<CharT const> d ) { return detail::kept_delimeters_m<CharT>( d ); }
|
||||
template<typename CharT>
|
||||
detail::kept_delimeters_m<CharT>
|
||||
operator=( CharT const* d ) { return detail::kept_delimeters_m<CharT>( basic_cstring<CharT const>( d ) ); }
|
||||
|
||||
detail::kept_delimeters_m<ti_delimeter_type>
|
||||
operator=( ti_delimeter_type t ) { return detail::kept_delimeters_m<ti_delimeter_type>( t ); }
|
||||
} kept_delimeters;
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
static struct keep_empty_tokens_generator : detail::keep_empty_tokens_m {
|
||||
keep_empty_tokens_generator() : detail::keep_empty_tokens_m( true ) {}
|
||||
|
||||
detail::keep_empty_tokens_m
|
||||
operator=( bool v ) { return detail::keep_empty_tokens_m( v ); }
|
||||
} keep_empty_tokens;
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** token_iterator_base ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename Derived,
|
||||
typename CharT,
|
||||
typename CharCompare = detail::default_char_compare<CharT>,
|
||||
typename ValueType = basic_cstring<CharT const>,
|
||||
typename Reference = basic_cstring<CharT const>,
|
||||
typename Traversal = forward_traversal_tag>
|
||||
class token_iterator_base
|
||||
: public input_iterator_facade<Derived,ValueType,Reference,Traversal> {
|
||||
typedef basic_cstring<CharT const> cstring;
|
||||
typedef detail::delim_policy<CharT,CharCompare> delim_policy;
|
||||
typedef input_iterator_facade<Derived,ValueType,Reference,Traversal> base;
|
||||
public:
|
||||
// Constructor
|
||||
explicit token_iterator_base()
|
||||
: m_is_dropped( use_isspace ),
|
||||
m_is_kept( use_ispunct ),
|
||||
m_keep_empty_tokens( false ),
|
||||
m_token_produced( false )
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
template<typename Modifier>
|
||||
token_iterator_base&
|
||||
use( Modifier const& m )
|
||||
{
|
||||
m.apply( m_is_dropped, m_is_kept, m_keep_empty_tokens );
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Iter>
|
||||
bool get( Iter& begin, Iter end )
|
||||
{
|
||||
typedef detail::token_assigner<BOOST_DEDUCED_TYPENAME iterator_traversal<Iter>::type> Assigner;
|
||||
Iter checkpoint;
|
||||
|
||||
Assigner::clear( m_value );
|
||||
|
||||
if( !m_keep_empty_tokens ) {
|
||||
while( begin != end && m_is_dropped( *begin ) )
|
||||
++begin;
|
||||
|
||||
if( begin == end )
|
||||
return false;
|
||||
|
||||
checkpoint = begin;
|
||||
|
||||
if( m_is_kept( *begin ) )
|
||||
Assigner::append_move( begin, m_value );
|
||||
else
|
||||
while( begin != end && !m_is_dropped( *begin ) && !m_is_kept( *begin ) )
|
||||
Assigner::append_move( begin, m_value );
|
||||
}
|
||||
else { // m_keep_empty_tokens ia true
|
||||
checkpoint = begin;
|
||||
|
||||
if( begin == end ) {
|
||||
if( m_token_produced )
|
||||
return false;
|
||||
|
||||
m_token_produced = true;
|
||||
}
|
||||
else if( m_is_kept( *begin ) ) {
|
||||
if( m_token_produced )
|
||||
Assigner::append_move( begin, m_value );
|
||||
|
||||
m_token_produced = !m_token_produced;
|
||||
}
|
||||
else if( !m_token_produced && m_is_dropped( *begin ) )
|
||||
m_token_produced = true;
|
||||
else {
|
||||
if( m_is_dropped( *begin ) )
|
||||
checkpoint = ++begin;
|
||||
|
||||
while( begin != end && !m_is_dropped( *begin ) && !m_is_kept( *begin ) )
|
||||
Assigner::append_move( begin, m_value );
|
||||
|
||||
m_token_produced = true;
|
||||
}
|
||||
}
|
||||
|
||||
Assigner::assign( checkpoint, begin, m_value );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// Data members
|
||||
delim_policy m_is_dropped;
|
||||
delim_policy m_is_kept;
|
||||
bool m_keep_empty_tokens;
|
||||
bool m_token_produced;
|
||||
};
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** basic_string_token_iterator ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename CharT,
|
||||
typename CharCompare = detail::default_char_compare<CharT> >
|
||||
class basic_string_token_iterator
|
||||
: public token_iterator_base<basic_string_token_iterator<CharT,CharCompare>,CharT,CharCompare> {
|
||||
typedef basic_cstring<CharT const> cstring;
|
||||
typedef token_iterator_base<basic_string_token_iterator<CharT,CharCompare>,CharT,CharCompare> base;
|
||||
public:
|
||||
explicit basic_string_token_iterator() {}
|
||||
explicit basic_string_token_iterator( cstring src )
|
||||
: m_src( src )
|
||||
{
|
||||
this->init();
|
||||
}
|
||||
|
||||
template<typename Src, typename M1>
|
||||
basic_string_token_iterator( Src src, M1 const& m1 )
|
||||
: m_src( src )
|
||||
{
|
||||
this->use( m1 );
|
||||
|
||||
this->init();
|
||||
}
|
||||
|
||||
template<typename Src, typename M1, typename M2>
|
||||
basic_string_token_iterator( Src src, M1 const& m1, M2 const& m2 )
|
||||
: m_src( src )
|
||||
{
|
||||
this->use( m1 );
|
||||
this->use( m2 );
|
||||
|
||||
this->init();
|
||||
}
|
||||
|
||||
template<typename Src, typename M1, typename M2, typename M3>
|
||||
basic_string_token_iterator( Src src, M1 const& m1, M2 const& m2, M3 const& m3 )
|
||||
: m_src( src )
|
||||
{
|
||||
this->use( m1 );
|
||||
this->use( m2 );
|
||||
this->use( m3 );
|
||||
|
||||
this->init();
|
||||
}
|
||||
|
||||
private:
|
||||
friend class input_iterator_core_access;
|
||||
|
||||
// input iterator implementation
|
||||
bool get()
|
||||
{
|
||||
typename cstring::iterator begin = m_src.begin();
|
||||
bool res = base::get( begin, m_src.end() );
|
||||
|
||||
m_src.assign( begin, m_src.end() );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// Data members
|
||||
cstring m_src;
|
||||
};
|
||||
|
||||
typedef basic_string_token_iterator<char> string_token_iterator;
|
||||
typedef basic_string_token_iterator<wchar_t> wstring_token_iterator;
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** range_token_iterator ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename Iter,
|
||||
typename CharCompare = detail::default_char_compare<BOOST_DEDUCED_TYPENAME iterator_value<Iter>::type>,
|
||||
typename ValueType = std::basic_string<BOOST_DEDUCED_TYPENAME iterator_value<Iter>::type>,
|
||||
typename Reference = ValueType const&>
|
||||
class range_token_iterator
|
||||
: public token_iterator_base<range_token_iterator<Iter,CharCompare,ValueType,Reference>,
|
||||
typename iterator_value<Iter>::type,CharCompare,ValueType,Reference> {
|
||||
typedef basic_cstring<typename ValueType::value_type> cstring;
|
||||
typedef token_iterator_base<range_token_iterator<Iter,CharCompare,ValueType,Reference>,
|
||||
typename iterator_value<Iter>::type,CharCompare,ValueType,Reference> base;
|
||||
public:
|
||||
explicit range_token_iterator() {}
|
||||
explicit range_token_iterator( Iter begin, Iter end = Iter() )
|
||||
: m_begin( begin ), m_end( end )
|
||||
{
|
||||
this->init();
|
||||
}
|
||||
|
||||
template<typename M1>
|
||||
range_token_iterator( Iter begin, Iter end, M1 const& m1 )
|
||||
: m_begin( begin ), m_end( end )
|
||||
{
|
||||
this->use( m1 );
|
||||
|
||||
this->init();
|
||||
}
|
||||
|
||||
template<typename M1,typename M2>
|
||||
range_token_iterator( Iter begin, Iter end, M1 const& m1, M2 const& m2 )
|
||||
: m_begin( begin ), m_end( end )
|
||||
{
|
||||
this->use( m1 );
|
||||
this->use( m2 );
|
||||
|
||||
this->init();
|
||||
}
|
||||
|
||||
template<typename M1,typename M2,typename M3>
|
||||
range_token_iterator( Iter begin, Iter end, M1 const& m1, M2 const& m2, M3 const& m3 )
|
||||
: m_begin( begin ), m_end( end )
|
||||
{
|
||||
this->use( m1 );
|
||||
this->use( m2 );
|
||||
this->use( m3 );
|
||||
|
||||
this->init();
|
||||
}
|
||||
|
||||
private:
|
||||
friend class input_iterator_core_access;
|
||||
|
||||
// input iterator implementation
|
||||
bool get()
|
||||
{
|
||||
return base::get( m_begin, m_end );
|
||||
}
|
||||
|
||||
// Data members
|
||||
Iter m_begin;
|
||||
Iter m_end;
|
||||
};
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** make_range_token_iterator ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename Iter>
|
||||
inline range_token_iterator<Iter>
|
||||
make_range_token_iterator( Iter begin, Iter end = Iter() )
|
||||
{
|
||||
return range_token_iterator<Iter>( begin, end );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename Iter,typename M1>
|
||||
inline range_token_iterator<Iter>
|
||||
make_range_token_iterator( Iter begin, Iter end, M1 const& m1 )
|
||||
{
|
||||
return range_token_iterator<Iter>( begin, end, m1 );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename Iter, typename M1, typename M2>
|
||||
inline range_token_iterator<Iter>
|
||||
make_range_token_iterator( Iter begin, Iter end, M1 const& m1, M2 const& m2 )
|
||||
{
|
||||
return range_token_iterator<Iter>( begin, end, m1, m2 );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename Iter,typename M1, typename M2, typename M3>
|
||||
inline range_token_iterator<Iter>
|
||||
make_range_token_iterator( Iter begin, Iter end, M1 const& m1, M2 const& m2, M3 const& m3 )
|
||||
{
|
||||
return range_token_iterator<Iter>( begin, end, m1, m2, m3 );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace unit_test
|
||||
|
||||
} // namespace boost
|
||||
|
||||
// ***************************************************************************
|
||||
// Revision History :
|
||||
//
|
||||
// $Log$
|
||||
// Revision 1.1 2004/06/05 11:03:12 rogeeff
|
||||
// input_iterator_adaptor simplified
|
||||
// token_iterator added
|
||||
//
|
||||
// ***************************************************************************
|
||||
|
||||
#endif // BOOST_TOKEN_ITERATOR_HPP
|
||||
|
||||
Reference in New Issue
Block a user