📄 regex_match.hpp
字号:
#if defined(BOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE)
} // namespace
#endif
template <class iterator>
void _skip_and_inc(unsigned int& clines, iterator& last_line, iterator& first, const iterator last)
{
while(first != last)
{
if(*first == '\n')
{
last_line = ++first;
++clines;
}
else
++first;
}
}
template <class iterator>
void _skip_and_dec(unsigned int& clines, iterator& last_line, iterator& first, iterator base, std::size_t len)
{
bool need_line = false;
for(std::size_t i = 0; i < len; ++i)
{
--first;
if(*first == '\n')
{
need_line = true;
--clines;
}
}
if(need_line)
{
last_line = first;
if(last_line != base)
--last_line;
else
return;
while((last_line != base) && (*last_line != '\n'))
--last_line;
if(*last_line == '\n')
++last_line;
}
}
template <class iterator>
inline void _inc_one(unsigned int& clines, iterator& last_line, iterator& first)
{
if(*first == '\n')
{
last_line = ++first;
++clines;
}
else
++first;
}
template <class iterator, class Allocator>
struct grep_search_predicate
{
match_results<iterator, Allocator>* pm;
grep_search_predicate(match_results<iterator, Allocator>* p) : pm(p) {}
bool operator()(const match_results<iterator, Allocator>& m)
{
*pm = static_cast<const match_results_base<iterator, Allocator>&>(m);
return false;
}
};
#if !defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
template <class iterator, class Allocator>
inline const match_results_base<iterator, Allocator>& grep_out_type(const grep_search_predicate<iterator, Allocator>& o, const Allocator&)
{
return *(o.pm);
}
#endif
template <class T, class Allocator>
inline const Allocator& grep_out_type(const T&, const Allocator& a)
{
return a;
}
#if defined(BOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE)
//
// Ugly ugly hack,
// template don't merge if they contain switch statements so declare these
// templates in unnamed namespace (ie with internal linkage), each translation
// unit then gets its own local copy, it works seemlessly but bloats the app.
namespace{
#endif
//
// reg_grep2:
// find all non-overlapping matches within the sequence first last:
//
template <class Predicate, class I, class charT, class traits, class A, class A2>
unsigned int reg_grep2(Predicate foo, I first, I last, const reg_expression<charT, traits, A>& e, unsigned flags, A2 a)
{
typedef access_t<charT, traits, A> access;
if(e.flags() & regbase::failbit)
return 0;
typedef typename traits::size_type traits_size_type;
typedef typename traits::uchar_type traits_uchar_type;
typedef typename is_byte<charT>::width_type width_type;
match_results<I, A2> m(grep_out_type(foo, a));
I restart;
m.set_size(e.mark_count(), first, last);
m.set_line(1, first);
m.set_base(first);
unsigned int clines = 1;
unsigned int cmatches = 0;
I last_line = first;
I next_base;
I base = first;
bool need_init;
bool leading_match = false;
const traits& traits_inst = e.get_traits();
// dwa 9/13/00 suppress incorrect MSVC warning - it claims this is never
// referenced
(void)traits_inst;
flags |= match_init;
_priv_match_data<I, A2> pd(m, first, last, e.size());
const unsigned char* _map = access::get_map(e);
unsigned int type;
if(first == last)
{
// special case, only test if can_be_null,
// don't dereference any pointers!!
if(access::first(e)->can_be_null)
{
if(query_match_aux(first, last, m, e, flags, pd, &restart))
{
foo(m);
++cmatches;
}
}
return cmatches;
}
// try one time whatever:
if( access::can_start(*first, _map, (unsigned char)mask_any) )
{
if(query_match_aux(first, last, m, e, flags, pd, &restart))
{
++cmatches;
leading_match = true;
if(foo(m) == false)
return cmatches;
if(m[0].second == last)
return cmatches;
// update to end of what matched
// trying to match again with match_not_null set if this
// is a null match...
need_init = true;
if(first == m[0].second)
{
next_base = m[0].second;
pd.temp_match.init_fail(next_base, last);
m.init_fail(next_base, last);
if(query_match_aux(first, last, m, e, flags | match_not_null, pd, &restart))
{
++cmatches;
if(foo(m) == false)
return cmatches;
}
else
{
need_init = false;
leading_match = false;
for(unsigned int i = 0; (restart != first) && (i < access::leading_length(e)); ++i, --restart)
{} // dwa 10/20/2000 - warning suppression for MWCW
if(restart != last)
++restart;
_skip_and_inc(clines, last_line, first, restart);
}
}
if(need_init)
{
_skip_and_inc(clines, last_line, first, m[0].second);
next_base = m[0].second;
pd.temp_match.init_fail(next_base, last);
m.init_fail(next_base, last);
}
}
else
{
for(unsigned int i = 0; (restart != first) && (i < access::leading_length(e)); ++i, --restart)
{} // dwa 10/20/2000 - warning suppression for MWCW
if(restart != last)
++restart;
_skip_and_inc(clines, last_line, first, restart);
}
}
else
_inc_one(clines, last_line, first);
flags |= match_prev_avail | match_not_bob;
// depending on what the first record is we may be able to
// optimise the search:
type = (flags & match_continuous) ?
static_cast<unsigned int>(regbase::restart_continue)
: static_cast<unsigned int>(access::restart_type(e));
if(type == regbase::restart_buf)
return cmatches;
switch(type)
{
case regbase::restart_lit:
case regbase::restart_fixed_lit:
{
const kmp_info<charT>* info = access::get_kmp(e);
int len = info->len;
const charT* x = info->pstr;
int j = 0;
bool icase = e.flags() & regbase::icase;
while (first != last)
{
while((j > -1) && (x[j] != traits_inst.translate(*first, icase)))
j = info->kmp_next[j];
_inc_one(clines, last_line, first);
++j;
if(j >= len)
{
if(type == regbase::restart_fixed_lit)
{
_skip_and_dec(clines, last_line, first, base, j);
restart = first;
std::advance(restart, len);
m.set_first(first);
m.set_second(restart);
m.set_line(clines, last_line);
++cmatches;
if(foo(m) == false)
return cmatches;
if(m[0].second == last)
return cmatches;
_skip_and_inc(clines, last_line, first, restart);
next_base = m[0].second;
pd.temp_match.init_fail(next_base, last);
m.init_fail(next_base, last);
j = 0;
}
else
{
restart = first;
_skip_and_dec(clines, last_line, first, base, j);
if(query_match_aux(first, last, m, e, flags, pd, &restart))
{
m.set_line(clines, last_line);
++cmatches;
if(foo(m) == false)
return cmatches;
if(m[0].second == last)
return cmatches;
// update to end of what matched
_skip_and_inc(clines, last_line, first, m[0].second);
next_base = m[0].second;
pd.temp_match.init_fail(next_base, last);
m.init_fail(next_base, last);
j = 0;
}
else
{
for(int k = 0; (restart != first) && (k < j); ++k, --restart)
{} // dwa 10/20/2000 - warning suppression for MWCW
if(restart != last)
++restart;
_skip_and_inc(clines, last_line, first, restart);
j = 0; //we could do better than this...
}
}
}
}
break;
}
case regbase::restart_any:
{
while(first != last)
{
if( access::can_start(*first, _map, (unsigned char)mask_any) )
{
if(query_match_aux(first, last, m, e, flags, pd, &restart))
{
m.set_line(clines, last_line);
++cmatches;
if(foo(m) == false)
return cmatches;
if(m[0].second == last)
return cmatches;
// update to end of what matched
// trying to match again with match_not_null set if this
// is a null match...
need_init = true;
if(first == m[0].second)
{
next_base = m[0].second;
pd.temp_match.init_fail(next_base, last);
m.init_fail(next_base, last);
if(query_match_aux(first, last, m, e, flags | match_not_null, pd, &restart))
{
m.set_line(clines, last_line);
++cmatches;
if(foo(m) == false)
return cmatches;
}
else
{
need_init = false;
for(unsigned int i = 0; (restart != first) && (i < access::leading_length(e)); ++i, --restart)
{} // dwa 10/20/2000 - warning suppression for MWCW
if(restart != last)
++restart;
_skip_and_inc(clines, last_line, first, restart);
}
}
if(need_init)
{
_skip_and_inc(clines, last_line, first, m[0].second);
next_base = m[0].second;
pd.temp_match.init_fail(next_base, last);
m.init_fail(next_base, last);
}
continue;
}
else
{
for(unsigned int i = 0; (restart != first) && (i < access::leading_length(e)); ++i, --restart)
{} // dwa 10/20/2000 - warning suppression for MWCW
if(restart != last)
++restart;
_skip_and_inc(clines, last_line, first, restart);
}
}
else
_inc_one(clines, last_line, first);
}
}
break;
case regbase::restart_word:
{
// do search optimised for word starts:
while(first != last)
{
--first;
if(*first == '\n')
--clines;
// skip the word characters:
while((first != last) && traits_inst.is_class(*first, traits::char_class_word))
++first;
// now skip the white space:
while((first != last) && (traits_inst.is_class(*first, traits::char_class_word) == false))
{
#ifdef __GNUC__
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -