⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 regex.hpp

📁 boost库提供标准的C++ API 配合dev c++使用,功能更加强大
💻 HPP
📖 第 1 页 / 共 4 页
字号:
// 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 + -