📄 regexpr2.cpp
字号:
}
template< typename CI >
inline assertion<CI> * create_eos( REGEX_FLAGS, regex_arena & arena )
{
return new( arena ) assert_op<CI, peos_t<true_t> >();
}
template< typename CI >
inline assertion<CI> * create_eoz( REGEX_FLAGS, regex_arena & arena )
{
return new( arena ) assert_op<CI, eos_t<true_t> >();
}
template< typename CI >
inline assertion<CI> * create_bol( REGEX_FLAGS flags, regex_arena & arena )
{
switch( MULTILINE & flags )
{
case 0:
return new( arena ) assert_op<CI, bos_t<true_t> >();
case MULTILINE:
return new( arena ) assert_op<CI, bol_t<true_t> >();
default:
__assume( 0 ); // tells the compiler that this is unreachable
}
}
template< typename CI >
inline assertion<CI> * create_eol( REGEX_FLAGS flags, regex_arena & arena )
{
switch( MULTILINE & flags )
{
case 0:
return new( arena ) assert_op<CI, peos_t<true_t> >();
case MULTILINE:
return new( arena ) assert_op<CI, eol_t<true_t> >();
default:
__assume( 0 ); // tells the compiler that this is unreachable
}
}
template< typename CI, typename SUB_EXPR = sub_expr<CI> >
class match_wrapper : public sub_expr<CI>
{
match_wrapper & operator=( match_wrapper const & );
public:
match_wrapper( SUB_EXPR * psub )
: m_psub( psub )
{
}
virtual ~match_wrapper()
{
_cleanup();
}
virtual width_type width_this( width_param<CI> & param )
{
return m_psub->width_this( param );
}
protected:
void _cleanup()
{
delete m_psub;
m_psub = NULL;
}
SUB_EXPR * m_psub;
};
template< typename CI, typename SUB_EXPR = sub_expr<CI> >
class match_quantifier : public match_wrapper<CI, SUB_EXPR>
{
match_quantifier & operator=( match_quantifier const & );
public:
match_quantifier( SUB_EXPR * psub, size_t lbound, size_t ubound )
: match_wrapper<CI, SUB_EXPR>( psub ), m_lbound( lbound ), m_ubound( ubound )
{
}
virtual width_type width_this( width_param<CI> & param )
{
width_type this_width = match_wrapper<CI, SUB_EXPR>::width_this( param );
width_type quant_width = { m_lbound, m_ubound };
return this_width * quant_width;
}
protected:
size_t const m_lbound;
size_t const m_ubound;
};
template< typename CI, typename SUB_EXPR >
class atom_quantifier : public match_quantifier<CI, SUB_EXPR>
{
atom_quantifier & operator=( atom_quantifier const & );
public:
atom_quantifier( SUB_EXPR * psub, size_t lbound, size_t ubound )
: match_quantifier<CI, SUB_EXPR>( psub, lbound, ubound )
{
}
protected:
void _push_frame( unsafe_stack * pstack, CI curr, size_t count ) const
{
std::pair<CI, size_t> p( curr, count );
pstack->push( p );
}
void _pop_frame( match_param<CI> & param ) const
{
std::pair<CI, size_t> p;
param.pstack->pop( p );
param.icur = p.first;
}
};
//template< typename CSTRINGS >
//struct inliner
//{
// template< typename SUB_EXPR, typename CI >
// __forceinline static bool iterative_match_this_( SUB_EXPR const * psub, match_param<CI> & param )
// {
// return psub->SUB_EXPR::iterative_match_this_( param );
// }
//};
//template<>
//struct inliner<true_t>
//{
// template< typename SUB_EXPR, typename CI >
// __forceinline static bool iterative_match_this_( SUB_EXPR const * psub, match_param<CI> & param )
// {
// return psub->SUB_EXPR::iterative_match_this_c( param );
// }
//};
template< typename CI, typename SUB_EXPR >
class max_atom_quantifier : public atom_quantifier<CI, SUB_EXPR>
{
max_atom_quantifier & operator=( max_atom_quantifier const & );
public:
max_atom_quantifier( SUB_EXPR * psub, size_t lbound, size_t ubound )
: atom_quantifier<CI, SUB_EXPR>( psub, lbound, ubound )
{
}
// Why a macro instead of a template, you ask? Performance. Due to a known
// bug in the VC7 inline heuristic, I cannot get VC7 to inline the calls to
// m_psub methods unless I use these macros. And the performance win is
// nothing to sneeze at. It's on the order of a 25% speed up to use a macro
// here instead of a template.
#define DECLARE_RECURSIVE_MATCH_ALL(cstrings,ext) \
virtual bool recursive_match_all ## ext( match_param<CI> & param, CI icur ) const \
{ \
/* In an ideal world, istart and cdiff would be members of a union */ \
/* to conserve stack, but I don't know if CI is a POD type or not. */ \
CI istart = icur; \
ptrdiff_t cdiff = 0; /* must be a signed integral type */ \
size_t cmatches = 0; \
/* greedily match as much as we can*/ \
if( m_ubound && m_psub->SUB_EXPR::recursive_match_this ## ext( param, icur ) ) \
{ \
if( 0 == ( cdiff = -std::distance( istart, icur ) ) ) \
return recursive_match_next_( param, icur, cstrings() ); \
while( ++cmatches < m_ubound && m_psub->SUB_EXPR::recursive_match_this ## ext( param, icur ) ); \
} \
if( m_lbound > cmatches ) \
return false; \
/* try matching the rest of the pattern, and back off if necessary */ \
for( ; ; --cmatches, std::advance( icur, ( int ) cdiff ) ) \
{ \
if( recursive_match_next_( param, icur, cstrings() ) ) \
return true; \
if( m_lbound == cmatches ) \
return false; \
} \
}
#define DECLARE_ITERATIVE_MATCH_THIS(ext) \
virtual bool iterative_match_this ## ext( match_param<CI> & param ) const \
{ \
CI istart = param.icur; \
size_t cmatches = 0; \
if( m_ubound && m_psub->SUB_EXPR::iterative_match_this ## ext( param ) ) \
{ \
if( 0 == std::distance( istart, param.icur ) ) \
{ \
cmatches = m_lbound; \
} \
else \
{ \
while( ++cmatches < m_ubound && m_psub->SUB_EXPR::iterative_match_this ## ext( param ) ); \
} \
} \
if( cmatches >= m_lbound ) \
{ \
_push_frame( param.pstack, istart, cmatches ); \
param.next = next(); \
return true; \
} \
param.icur = istart; \
return false; \
}
#define DECLARE_ITERATIVE_REMATCH_THIS(ext) \
virtual bool iterative_rematch_this ## ext( match_param<CI> & param ) const \
{ \
size_t & cmatches = param.pstack->top( static_init<std::pair<CI, size_t> >::value ).second; \
if( m_lbound != cmatches ) \
{ \
--cmatches; \
m_psub->SUB_EXPR::iterative_rematch_this ## ext( param ); \
param.next = next(); \
return true; \
} \
_pop_frame( param ); \
return false; \
}
DECLARE_RECURSIVE_MATCH_ALL(false_t,_)
DECLARE_RECURSIVE_MATCH_ALL(true_t,_c)
DECLARE_ITERATIVE_MATCH_THIS(_)
DECLARE_ITERATIVE_MATCH_THIS(_c)
DECLARE_ITERATIVE_REMATCH_THIS(_)
DECLARE_ITERATIVE_REMATCH_THIS(_c)
//template< typename CSTRINGS >
//__forceinline bool _iterative_match_this( match_param<CI> & param ) const
//{
// CI istart = param.icur;
// size_t cmatches = 0;
// if( m_ubound && inliner<CSTRINGS>::iterative_match_this_( m_psub, param ) )
// {
// if( 0 == std::distance( istart, param.icur ) )
// {
// cmatches = m_lbound;
// }
// else
// {
// while( ++cmatches < m_ubound && inliner<CSTRINGS>::iterative_match_this_( m_psub, param ) );
// }
// }
// if( cmatches >= m_lbound )
// {
// _push_frame( param.pstack, istart, cmatches );
// param.next = next();
// return true;
// }
// param.icur = istart;
// return false;
//}
//virtual bool iterative_match_this_( match_param<CI> & param ) const
//{
// return _iterative_match_this<false_t>( param );
//}
//virtual bool iterative_match_this_c( match_param<CI> & param ) const
//{
// return _iterative_match_this<true_t>( param );
//}
#undef DECLARE_RECURSIVE_MATCH_ALL
#undef DECLARE_ITERATIVE_MATCH_THIS
#undef DECLARE_ITERATIVE_REMATCH_THIS
};
template< typename CI, typename SUB_EXPR >
class min_atom_quantifier : public atom_quantifier<CI, SUB_EXPR>
{
min_atom_quantifier & operator=( min_atom_quantifier const & );
public:
min_atom_quantifier( SUB_EXPR * psub, size_t lbound, size_t ubound )
: atom_quantifier<CI, SUB_EXPR>( psub, lbound, ubound )
{
}
// Why a macro instead of a template, you ask? Performance. Due to a known
// bug in the VC7 inline heuristic, I cannot get VC7 to inline the calls to
// m_psub methods unless I use these macros. And the performance win is
// nothing to sneeze at. It's on the order of a 25% speed up to use a macro
// here instead of a template.
#define DECLARE_RECURSIVE_MATCH_ALL(cstrings,ext) \
virtual bool recursive_match_all ## ext( match_param<CI> & param, CI icur ) const \
{ \
CI icur_tmp = icur; \
size_t cmatches = 0; \
if( m_psub->SUB_EXPR::recursive_match_this ## ext( param, icur_tmp ) ) \
{ \
if( icur_tmp == icur ) \
return recursive_match_next_( param, icur, cstrings() ); \
if( m_lbound ) \
{ \
icur = icur_tmp; \
++cmatches; \
} \
for( ; cmatches < m_lbound; ++cmatches ) \
{ \
if( ! m_psub->SUB_EXPR::recursive_match_this ## ext( param, icur ) ) \
return false; \
} \
} \
else if( m_lbound ) \
{ \
return false; \
} \
do \
{ \
if( recursive_match_next_( param, icur, cstrings() ) ) \
return true; \
} \
while( cmatches < m_ubound && \
( ++cmatches, m_psub->SUB_EXPR::recursive_match_this ## ext( param, icur ) ) ); \
return false; \
}
#define DECLARE_ITERATIVE_MATCH_THIS(ext) \
virtual bool iterative_match_this ## ext( match_param<CI> & param ) const \
{ \
CI istart = param.icur; \
size_t cmatches = 0; \
if( m_psub->SUB_EXPR::iterative_match_this ## ext( param ) ) \
{ \
if( 0 == std::distance( istart, param.icur ) ) \
{ \
cmatches = m_ubound; \
} \
else if( m_lbound ) \
{ \
for( ++cmatches; cmatches < m_lbound; ++cmatches ) \
{ \
if( ! m_psub->SUB_EXPR::iterative_match_this ## ext( param ) ) \
{ \
param.icur = istart; \
return false; \
} \
} \
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -