📄 regexpr2.cpp
字号:
}
static void operator delete( void *, regex_arena & )
{
}
};
// This class is used to speed up character set matching by providing
// a bitset that spans the ASCII range. std::bitset is not used because
// the range-checking slows it down.
// Note: The division and modulus operations are optimized by the compiler
// into bit-shift operations.
class ascii_bitvector
{
typedef unsigned int elem_type;
enum
{
CBELEM = CHAR_BIT * sizeof( elem_type ), // count of bits per element
CELEMS = ( UCHAR_MAX+1 ) / CBELEM // number of element in array
};
elem_type m_rg[ CELEMS ];
// Used to inline operations like: bv1 |= ~bv2; without creating temp bit vectors.
struct not_ascii_bitvector
{
ascii_bitvector const & m_ref;
not_ascii_bitvector( ascii_bitvector const & ref )
: m_ref( ref ) {}
private:
not_ascii_bitvector & operator=( not_ascii_bitvector const & );
};
ascii_bitvector( ascii_bitvector const & );
ascii_bitvector & operator=( ascii_bitvector const & );
public:
ascii_bitvector()
{
zero();
}
void zero()
{
std::fill_n( m_rg, ARRAYSIZE( m_rg ), 0 );
}
void set( unsigned char ch )
{
m_rg[ ( ch / CBELEM ) ] |= ( ( elem_type )1U << ( ch % CBELEM ) );
}
bool operator[]( unsigned char ch ) const
{
return 0 != ( m_rg[ ( ch / CBELEM ) ] & ( ( elem_type )1U << ( ch % CBELEM ) ) );
}
not_ascii_bitvector const operator~() const
{
return not_ascii_bitvector( *this );
}
ascii_bitvector & operator|=( ascii_bitvector const & that )
{
for( int i=0; i<CELEMS; ++i )
m_rg[ i ] |= that.m_rg[ i ];
return *this;
}
ascii_bitvector & operator|=( not_ascii_bitvector const & that )
{
for( int i=0; i<CELEMS; ++i )
m_rg[ i ] |= ~that.m_ref.m_rg[ i ];
return *this;
}
};
typedef std::pair<wchar_t, wchar_t> range_type;
// determines if one range is less then another.
// used in binary search of range vector
struct range_less
{
bool operator()( range_type const & rg1, range_type const & rg2 ) const
{
return rg1.second < rg2.first;
}
};
// A singly-linked list, which works even if the allocator
// has per-instance state.
template< typename T, typename AllocT=std::allocator<T> >
class slist
{
struct cons
{
T car;
cons * cdr;
cons( T const & t, cons * nxt )
: car( t )
, cdr( nxt )
{
}
};
typedef typename rebind<AllocT, cons>::type cons_allocator;
typedef typename rebind<AllocT, char>::type char_allocator;
#if !defined(_MSC_VER) | 1200 < _MCS_VER
// Use the empty base optimization to avoid reserving
// space for the allocator if it is empty.
struct slist_impl : cons_allocator
{
cons * m_lst;
slist_impl( cons_allocator const & alloc, cons *lst )
: cons_allocator( alloc )
, m_lst( lst )
{
}
cons_allocator & allocator()
{
return *this;
}
};
#else
struct slist_impl
{
cons_allocator m_alloc;
cons *m_lst;
slist_impl( cons_allocator const & alloc, cons *lst )
: m_alloc( alloc )
, m_lst( lst )
{
}
cons_allocator & allocator()
{
return m_alloc;
}
};
#endif
slist_impl m_impl;
// find the previous node in the list (*prev(lst)==lst)
cons ** prev( cons *lst, cons *hint = 0 )
{
if( m_impl.m_lst == lst )
return &m_impl.m_lst;
if( !hint || hint->cdr != lst )
for( hint=m_impl.m_lst; hint->cdr != lst; hint=hint->cdr )
{}
return &hint->cdr;
}
public:
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef T const* const_pointer;
typedef T const& const_reference;
typedef size_t size_type;
struct iterator : public std::iterator<std::forward_iterator_tag, T>
{
friend class slist<T,AllocT>;
explicit iterator( cons * pcons = 0 )
: m_pcons( pcons )
{
}
T & operator*() const
{
return m_pcons->car;
}
T * operator->() const
{
return &m_pcons->car;
}
iterator & operator++()
{
m_pcons = m_pcons->cdr;
return *this;
}
iterator operator++( int )
{
iterator i( *this );
++*this;
return i;
}
bool operator==( iterator it )
{
return m_pcons == it.m_pcons;
}
bool operator!=( iterator it )
{
return m_pcons != it.m_pcons;
}
private:
cons * m_pcons;
};
// not ideal, but good enough for gov'ment work....
typedef iterator const_iterator;
explicit slist( char_allocator const & al = char_allocator() )
: m_impl( convert_allocator<cons>( al, 0 ), 0 )
{
}
~slist()
{
clear();
}
void clear()
{
for( cons *nxt; m_impl.m_lst; m_impl.m_lst=nxt )
{
nxt = m_impl.m_lst->cdr;
m_impl.allocator().destroy( m_impl.m_lst );
m_impl.allocator().deallocate( m_impl.m_lst, 1 );
}
}
void push_front( T const & t )
{
cons * lst = m_impl.allocator().allocate( 1, 0 );
try
{
m_impl.allocator().construct( lst, cons( t, m_impl.m_lst ) );
}
catch(...)
{
m_impl.allocator().deallocate( lst, 1 );
throw;
}
m_impl.m_lst = lst;
}
template< typename PredT >
void sort( PredT pred )
{
// simple insertion sort
cons *rst=m_impl.m_lst;
m_impl.m_lst = 0;
while( rst )
{
cons *cur=m_impl.m_lst, *prv=0;
while( cur && ! pred( rst->car, cur->car ) )
prv=cur, cur=cur->cdr;
if( prv )
prv->cdr=rst, rst=rst->cdr, prv->cdr->cdr=cur;
else
m_impl.m_lst=rst, rst=rst->cdr, m_impl.m_lst->cdr=cur;
}
}
void sort()
{
this->sort( std::less<T>() );
}
iterator begin() const
{
return iterator( m_impl.m_lst );
}
iterator end() const
{
return iterator();
}
bool empty() const
{
return 0 == m_impl.m_lst;
}
size_t size() const
{
size_t len=0;
for( cons *lst=m_impl.m_lst; lst; lst=lst->cdr, ++len )
{}
return len;
}
iterator erase( iterator it, iterator hint = iterator() )
{
cons **prv = prev( it.m_pcons, hint.m_pcons ); // *prv==it.p
*prv = it.m_pcons->cdr;
m_impl.allocator().destroy( it.m_pcons );
m_impl.allocator().deallocate( it.m_pcons, 1 );
return iterator( *prv );
}
void reverse()
{
cons *prv=0, *nxt;
while( m_impl.m_lst )
nxt = m_impl.m_lst->cdr, m_impl.m_lst->cdr = prv, prv = m_impl.m_lst, m_impl.m_lst = nxt;
m_impl.m_lst = prv;
}
};
template< typename AllocT >
struct basic_charset;
template< typename CharT >
struct posixcharsoff_pred
{
CharT m_ch;
posixcharsoff_pred( CharT ch )
: m_ch( ch )
{
}
bool operator()( regex_ctype_t desc ) const
{
return ! local_isctype( m_ch, desc );
}
static int local_isctype( char ch, regex_ctype_t desc )
{
return regex_isctype( ch, desc );
}
static int local_isctype( wchar_t ch, regex_ctype_t desc )
{
return regex_iswctype( ch, desc );
}
};
template< typename CharT, bool CaseT >
struct in_charset_pred
{
CharT m_ch;
in_charset_pred( CharT ch )
: m_ch( ch )
{
}
template< typename AllocT >
bool operator()( basic_charset<AllocT> const * pcs ) const
{
REGEX_VC6( return pcs->in( m_ch COMMA bool2type<CaseT>() ); )
REGEX_NVC6( return pcs->template in<CaseT>( m_ch ); )
}
};
template< typename AllocT >
struct basic_charset
{
typedef basic_charset<std::allocator<char> > other_type;
typedef slist<range_type,std::allocator<char> > other_ranges_type;
typedef slist<range_type,AllocT> ranges_type;
typedef slist<regex_ctype_t,AllocT> posixcharsoff_type;
typedef slist<other_type const*,AllocT> nestedcharsets_type;
typedef typename rebind<AllocT, char>::type char_allocator_type;
bool m_fcompliment;
bool m_fskip_extended_check;
ascii_bitvector m_ascii_bitvector;
regex_ctype_t m_posixcharson;
ranges_type m_ranges;
posixcharsoff_type m_posixcharsoff;
nestedcharsets_type m_nestedcharsets;
explicit basic_charset( char_allocator_type const & al = char_allocator_type() )
: m_fcompliment( false )
, m_fskip_extended_check( false )
, m_ascii_bitvector()
, m_posixcharson( wct_zero )
, m_ranges( al )
, m_posixcharsoff( al )
, m_nestedcharsets( al )
{
}
// We'll be inheriting from this, so a virtual d'tor is regretably necessary.
virtual ~basic_charset()
{
}
void clear()
{
m_fcompliment = false;
m_fskip_extended_check = false;
m_ascii_bitvector.zero();
m_posixcharson = wct_zero;
m_ranges.clear();
m_posixcharsoff.clear();
m_nestedcharsets.clear();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -