📄 regex.hpp
字号:
// helper:
template <class I, class charT>
int do_toi(I& i, I j, charT c)
{
int result = 0;
while((i != j) && (isdigit(*i)))
{
result = result*10 + (*i - '0');
++i;
}
return result;
}
}
template <class iterator>
sub_match<iterator>::operator int()const
{
iterator i = first;
iterator j = second;
#ifndef BOOST_NO_EXCEPTIONS
if(i == j)throw bad_pattern("Bad sub-expression");
#endif
BOOST_REGEX_NOEH_ASSERT(i != j)
int neg = 1;
if((i != j) && (*i == '-'))
{
neg = -1;
++i;
}
neg *= re_detail::do_toi(i, j, *i);
#ifndef BOOST_NO_EXCEPTIONS
if(i != j)throw bad_pattern("Bad sub-expression");
#endif
BOOST_REGEX_NOEH_ASSERT(i == j)
return neg;
}
template <class iterator>
sub_match<iterator>::operator unsigned int()const
{
iterator i = first;
iterator j = second;
#ifndef BOOST_NO_EXCEPTIONS
if(i == j)
throw bad_pattern("Bad sub-expression");
#endif
BOOST_REGEX_NOEH_ASSERT(i != j)
return re_detail::do_toi(i, j, *first);
}
#endif
namespace re_detail{
template <class iterator, class Allocator = BOOST_DEFAULT_ALLOCATOR(typename def_alloc_param_traits<iterator>::type) >
class match_results_base
{
public:
typedef Allocator alloc_type;
typedef typename boost::detail::rebind_allocator<iterator, Allocator>::type iterator_alloc;
typedef typename iterator_alloc::size_type size_type;
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
typedef typename std::iterator_traits<iterator>::difference_type difference_type;
typedef typename std::iterator_traits<iterator>::value_type char_type;
#else
typedef std::ptrdiff_t difference_type;
typedef typename re_detail::regex_iterator_traits<iterator>::value_type char_type;
#endif
typedef sub_match<iterator> value_type;
typedef iterator iterator_type;
protected:
typedef typename boost::detail::rebind_allocator<char, Allocator>::type c_alloc;
struct c_reference : public c_alloc
{
std::size_t cmatches;
unsigned count;
sub_match<iterator> head, tail, re_null;
unsigned int lines;
iterator line_pos, base;
c_reference(const Allocator& a)
: c_alloc(a), cmatches(0), count(0), lines(0) { }
bool operator==(const c_reference& that)const
{
return (cmatches == that.cmatches) &&
(count == that.count) &&
(head == that.head) &&
(tail == that.tail) &&
(lines == that.lines) &&
(base == that.base);
}
bool operator!=(const c_reference& that)const
{ return !(*this == that); }
};
c_reference* ref;
void BOOST_REGEX_CALL cow();
// protected contructor for derived class...
match_results_base(bool){}
void BOOST_REGEX_CALL m_free();
public:
match_results_base(const Allocator& a = Allocator());
match_results_base(const match_results_base& m)
{
ref = m.ref;
++(ref->count);
}
match_results_base& BOOST_REGEX_CALL operator=(const match_results_base& m);
~match_results_base()
{
m_free();
}
size_type BOOST_REGEX_CALL size()const
{
//return (*this)[0].matched ? ref->cmatches : 0;
return ref->cmatches;
}
const sub_match<iterator>& BOOST_REGEX_CALL operator[](int n) const
{
if((n >= 0) && ((unsigned int)n < ref->cmatches))
return *(sub_match<iterator>*)((char*)ref + sizeof(c_reference) + sizeof(sub_match<iterator>)*n);
return (n == -1) ? ref->head : (n == -2) ? ref->tail : ref->re_null;
}
Allocator BOOST_REGEX_CALL allocator()const;
difference_type BOOST_REGEX_CALL length(unsigned int sub = 0)const
{
jm_assert(ref->cmatches);
const sub_match<iterator>& m = (*this)[sub];
if(m.matched == false)
return 0;
difference_type n = boost::re_detail::distance((iterator)m.first, (iterator)m.second);
return n;
}
std::basic_string<char_type> str(int i)const
{
return static_cast<std::basic_string<char_type> >((*this)[i]);
}
unsigned int BOOST_REGEX_CALL line()const
{
return ref->lines;
}
difference_type BOOST_REGEX_CALL position(unsigned int sub = 0)const
{
jm_assert(ref->cmatches);
const sub_match<iterator>& s = (*this)[sub];
if(s.matched == false)
return -1;
difference_type n = boost::re_detail::distance((iterator)(ref->base), (iterator)(s.first));
return n;
}
iterator BOOST_REGEX_CALL line_start()const
{
return ref->line_pos;
}
void swap(match_results_base& that)
{
c_reference* t = that.ref;
that.ref = ref;
ref = t;
}
bool operator==(const match_results_base& that)const;
bool operator<(const match_results_base& that)const
{ return position() < that.position(); }
friend class match_results<iterator, Allocator>;
void BOOST_REGEX_CALL set_size(size_type n);
void BOOST_REGEX_CALL set_size(size_type n, iterator i, iterator j);
void BOOST_REGEX_CALL maybe_assign(const match_results_base& m);
void BOOST_REGEX_CALL init_fail(iterator i, iterator j);
void BOOST_REGEX_CALL set_first(iterator i);
void BOOST_REGEX_CALL set_first(iterator i, std::size_t pos);
void BOOST_REGEX_CALL set_second(iterator i)
{
cow();
((sub_match<iterator>*)(ref+1))->second = i;
((sub_match<iterator>*)(ref+1))->matched = true;
ref->tail.first = i;
ref->tail.matched = (ref->tail.first == ref->tail.second) ? false : true;
}
void BOOST_REGEX_CALL set_second(iterator i, std::size_t pos, bool m = true)
{
cow();
((sub_match<iterator>*)((char*)ref + sizeof(c_reference) + sizeof(sub_match<iterator>) * pos))->second = i;
((sub_match<iterator>*)((char*)ref + sizeof(c_reference) + sizeof(sub_match<iterator>) * pos))->matched = m;
if(pos == 0)
{
ref->tail.first = i;
ref->tail.matched = (ref->tail.first == ref->tail.second) ? false : true;
}
}
void BOOST_REGEX_CALL set_line(unsigned int i, iterator pos)
{
ref->lines = i;
ref->line_pos = pos;
}
void BOOST_REGEX_CALL set_base(iterator pos)
{
ref->base = pos;
}
};
template <class iterator, class Allocator>
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::set_first(iterator i)
{
cow();
ref->head.second = i;
ref->head.matched = (ref->head.first == ref->head.second) ? false : true;
sub_match<iterator>* p1 = (sub_match<iterator>*)(ref+1);
sub_match<iterator>* p2 = p1 + ref->cmatches;
p1->first = i;
p1->matched = false;
++p1;
while(p1 != p2)
{
p1->matched = false;
p1->first = ref->tail.second;
p1->second = ref->tail.second;
++p1;
}
}
template <class iterator, class Allocator>
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::set_first(iterator i, std::size_t pos)
{
cow();
((sub_match<iterator>*)((char*)ref + sizeof(c_reference) + sizeof(sub_match<iterator>) * pos))->first = i;
if(pos == 0)
{
ref->head.second = i;
ref->head.matched = (ref->head.first == ref->head.second) ? false : true;
sub_match<iterator>* p1 = (sub_match<iterator>*)(ref+1);
sub_match<iterator>* p2 = p1 + ref->cmatches;
p1->first = i;
p1->matched = false;
++p1;
while(p1 != p2)
{
p1->matched = false;
p1->first = ref->tail.second;
p1->second = ref->tail.second;
++p1;
}
}
}
template <class iterator, class Allocator>
match_results_base<iterator, Allocator>::match_results_base(const Allocator& a)
{
ref = (c_reference*)c_alloc(a).allocate(sizeof(sub_match<iterator>) + sizeof(c_reference));
BOOST_REGEX_NOEH_ASSERT(ref)
#ifndef BOOST_NO_EXCEPTIONS
try
{
#endif
new (ref) c_reference(a);
ref->cmatches = 1;
ref->count = 1;
// construct the sub_match<iterator>:
#ifndef BOOST_NO_EXCEPTIONS
try
{
#endif
new ((sub_match<iterator>*)(ref+1)) sub_match<iterator>();
#ifndef BOOST_NO_EXCEPTIONS
}
catch(...)
{
::boost::re_detail::pointer_destroy(ref);
throw;
}
}
catch(...)
{
c_alloc(a).deallocate((char*)(void*)ref, sizeof(sub_match<iterator>) + sizeof(c_reference));
throw;
}
#endif
}
template <class iterator, class Allocator>
Allocator BOOST_REGEX_CALL match_results_base<iterator, Allocator>::allocator()const
{
return *((c_alloc*)ref);
}
template <class iterator, class Allocator>
inline match_results_base<iterator, Allocator>& BOOST_REGEX_CALL match_results_base<iterator, Allocator>::operator=(const match_results_base<iterator, Allocator>& m)
{
if(ref != m.ref)
{
m_free();
ref = m.ref;
++(ref->count);
}
return *this;
}
template <class iterator, class Allocator>
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::m_free()
{
if(--(ref->count) == 0)
{
c_alloc a(*ref);
sub_match<iterator>* p1, *p2;
p1 = (sub_match<iterator>*)(ref+1);
p2 = p1 + ref->cmatches;
while(p1 != p2)
{
::boost::re_detail::pointer_destroy(p1);
++p1;
}
::boost::re_detail::pointer_destroy(ref);
a.deallocate((char*)(void*)ref, sizeof(sub_match<iterator>) * ref->cmatches + sizeof(c_reference));
}
}
template <class iterator, class Allocator>
bool match_results_base<iterator, Allocator>::operator==(const match_results_base<iterator, Allocator>& that)const
{
if(*ref != *(that.ref))
return false;
const sub_match<iterator>* p1 = (sub_match<iterator>*)(ref+1);
const sub_match<iterator>* p2 = p1 + ref->cmatches;
const sub_match<iterator>* p3 = (sub_match<iterator>*)(that.ref+1);
while(p1 != p2)
{
if(*p1 != *p3)
return false;
++p1;
++p3;
}
return true;
}
template <class iterator, class Allocator>
void BOOST_REGEX_CALL match_results_base<iterator, Allocator>::set_size(size_type n)
{
if(ref->cmatches != n)
{
c_reference* newref = (c_reference*)ref->allocate(sizeof(sub_match<iterator>) * n + sizeof(c_reference));
BOOST_REGEX_NOEH_ASSERT(newref)
#ifndef BOOST_NO_EXCEPTIONS
try
{
#endif
new (newref) c_reference(*ref);
newref->count = 1;
newref->cmatches = n;
sub_match<iterator>* p1, *p2;
p1 = (sub_match<iterator>*)(newref+1);
p2 = p1 + newref->cmatches;
#ifndef BOOST_NO_EXCEPTIONS
try
{
#endif
while(p1 != p2)
{
new (p1) sub_match<iterator>();
++p1;
}
m_free();
#ifndef BOOST_NO_EXCEPTIONS
}
catch(...)
{
p2 = (sub_match<iterator>*)(newref+1);
while(p2 != p1)
{
::boost::re_detail::pointer_destroy(p2);
++p2;
}
::boost::re_detail::pointer_destroy(ref);
throw;
}
#endif
ref = newref;
#ifndef BOOST_NO_EXCEPTIONS
}
catch(...)
{
ref->deallocate((char*)(void*)newref, sizeof(sub_match<iterator>) * n + sizeof(c_reference));
throw;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -