| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787 | /* * * Copyright (c) 1998-2004 John Maddock * Copyright 2011 Garmin Ltd. or its subsidiaries * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * */ /*  *   LOCATION:    see http://www.boost.org/ for most recent version.  *   FILE         basic_regex.cpp  *   VERSION      see <boost/version.hpp>  *   DESCRIPTION: Declares template class basic_regex.  */#ifndef BOOST_REGEX_V4_BASIC_REGEX_HPP#define BOOST_REGEX_V4_BASIC_REGEX_HPP#include <boost/type_traits/is_same.hpp>#include <boost/container_hash/hash.hpp>#ifdef BOOST_MSVC#pragma warning(push)#pragma warning(disable: 4103)#endif#ifdef BOOST_HAS_ABI_HEADERS#  include BOOST_ABI_PREFIX#endif#ifdef BOOST_MSVC#pragma warning(pop)#endifnamespace boost{#ifdef BOOST_MSVC#pragma warning(push)#pragma warning(disable : 4251)#if BOOST_MSVC < 1700#     pragma warning(disable : 4231)#endif#if BOOST_MSVC < 1600#pragma warning(disable : 4660)#endif#if BOOST_MSVC < 1910#pragma warning(disable:4800)#endif#endifnamespace BOOST_REGEX_DETAIL_NS{//// forward declaration, we will need this one later://template <class charT, class traits>class basic_regex_parser;template <class I>void bubble_down_one(I first, I last){   if(first != last)   {      I next = last - 1;      while((next != first) && (*next < *(next-1)))      {         (next-1)->swap(*next);         --next;      }   }}template <class Iterator>inline int hash_value_from_capture_name(Iterator i, Iterator j){   std::size_t r = boost::hash_range(i, j);   r %= ((std::numeric_limits<int>::max)() - 10001);   r += 10000;   return static_cast<int>(r);}class named_subexpressions{public:   struct name   {      template <class charT>      name(const charT* i, const charT* j, int idx)         : index(idx)       {          hash = hash_value_from_capture_name(i, j);       }      name(int h, int idx)         : index(idx), hash(h)      {       }      int index;      int hash;      bool operator < (const name& other)const      {         return hash < other.hash;      }      bool operator == (const name& other)const      {         return hash == other.hash;       }      void swap(name& other)      {         std::swap(index, other.index);         std::swap(hash, other.hash);      }   };   typedef std::vector<name>::const_iterator const_iterator;   typedef std::pair<const_iterator, const_iterator> range_type;   named_subexpressions(){}   template <class charT>   void set_name(const charT* i, const charT* j, int index)   {      m_sub_names.push_back(name(i, j, index));      bubble_down_one(m_sub_names.begin(), m_sub_names.end());   }   template <class charT>   int get_id(const charT* i, const charT* j)const   {      name t(i, j, 0);      typename std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);      if((pos != m_sub_names.end()) && (*pos == t))      {         return pos->index;      }      return -1;   }   template <class charT>   range_type equal_range(const charT* i, const charT* j)const   {      name t(i, j, 0);      return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);   }   int get_id(int h)const   {      name t(h, 0);      std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);      if((pos != m_sub_names.end()) && (*pos == t))      {         return pos->index;      }      return -1;   }   range_type equal_range(int h)const   {      name t(h, 0);      return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);   }private:   std::vector<name> m_sub_names;};//// class regex_data:// represents the data we wish to expose to the matching algorithms.//template <class charT, class traits>struct regex_data : public named_subexpressions{   typedef regex_constants::syntax_option_type   flag_type;   typedef std::size_t                           size_type;     regex_data(const ::boost::shared_ptr<      ::boost::regex_traits_wrapper<traits> >& t)       : m_ptraits(t), m_expression(0), m_expression_len(0), m_disable_match_any(false) {}   regex_data()       : m_ptraits(new ::boost::regex_traits_wrapper<traits>()), m_expression(0), m_expression_len(0), m_disable_match_any(false) {}   ::boost::shared_ptr<      ::boost::regex_traits_wrapper<traits>      >                        m_ptraits;                 // traits class instance   flag_type                   m_flags;                   // flags with which we were compiled   int                         m_status;                  // error code (0 implies OK).   const charT*                m_expression;              // the original expression   std::ptrdiff_t              m_expression_len;          // the length of the original expression   size_type                   m_mark_count;              // the number of marked sub-expressions   BOOST_REGEX_DETAIL_NS::re_syntax_base*  m_first_state;             // the first state of the machine   unsigned                    m_restart_type;            // search optimisation type   unsigned char               m_startmap[1 << CHAR_BIT]; // which characters can start a match   unsigned int                m_can_be_null;             // whether we can match a null string   BOOST_REGEX_DETAIL_NS::raw_storage      m_data;                    // the buffer in which our states are constructed   typename traits::char_class_type    m_word_mask;       // mask used to determine if a character is a word character   std::vector<      std::pair<      std::size_t, std::size_t> > m_subs;                 // Position of sub-expressions within the *string*.   bool                        m_has_recursions;          // whether we have recursive expressions;   bool                        m_disable_match_any;       // when set we need to disable the match_any flag as it causes different/buggy behaviour.};//// class basic_regex_implementation// pimpl implementation class for basic_regex.//template <class charT, class traits>class basic_regex_implementation   : public regex_data<charT, traits>{public:   typedef regex_constants::syntax_option_type   flag_type;   typedef std::ptrdiff_t                        difference_type;   typedef std::size_t                           size_type;    typedef typename traits::locale_type          locale_type;   typedef const charT*                          const_iterator;   basic_regex_implementation(){}   basic_regex_implementation(const ::boost::shared_ptr<      ::boost::regex_traits_wrapper<traits> >& t)      : regex_data<charT, traits>(t) {}   void assign(const charT* arg_first,                          const charT* arg_last,                          flag_type f)   {      regex_data<charT, traits>* pdat = this;      basic_regex_parser<charT, traits> parser(pdat);      parser.parse(arg_first, arg_last, f);   }   locale_type BOOST_REGEX_CALL imbue(locale_type l)   {       return this->m_ptraits->imbue(l);    }   locale_type BOOST_REGEX_CALL getloc()const   {       return this->m_ptraits->getloc();    }   std::basic_string<charT> BOOST_REGEX_CALL str()const   {      std::basic_string<charT> result;      if(this->m_status == 0)         result = std::basic_string<charT>(this->m_expression, this->m_expression_len);      return result;   }   const_iterator BOOST_REGEX_CALL expression()const   {      return this->m_expression;   }   std::pair<const_iterator, const_iterator> BOOST_REGEX_CALL subexpression(std::size_t n)const   {      const std::pair<std::size_t, std::size_t>& pi = this->m_subs.at(n);      std::pair<const_iterator, const_iterator> p(expression() + pi.first, expression() + pi.second);      return p;   }   //   // begin, end:   const_iterator BOOST_REGEX_CALL begin()const   {       return (this->m_status ? 0 : this->m_expression);    }   const_iterator BOOST_REGEX_CALL end()const   {       return (this->m_status ? 0 : this->m_expression + this->m_expression_len);    }   flag_type BOOST_REGEX_CALL flags()const   {      return this->m_flags;   }   size_type BOOST_REGEX_CALL size()const   {      return this->m_expression_len;   }   int BOOST_REGEX_CALL status()const   {      return this->m_status;   }   size_type BOOST_REGEX_CALL mark_count()const   {      return this->m_mark_count - 1;   }   const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const   {      return this->m_first_state;   }   unsigned get_restart_type()const   {      return this->m_restart_type;   }   const unsigned char* get_map()const   {      return this->m_startmap;   }   const ::boost::regex_traits_wrapper<traits>& get_traits()const   {      return *(this->m_ptraits);   }   bool can_be_null()const   {      return this->m_can_be_null;   }   const regex_data<charT, traits>& get_data()const   {      basic_regex_implementation<charT, traits> const* p = this;      return *static_cast<const regex_data<charT, traits>*>(p);   }};} // namespace BOOST_REGEX_DETAIL_NS//// class basic_regex:// represents the compiled// regular expression://#ifdef BOOST_REGEX_NO_FWDtemplate <class charT, class traits = regex_traits<charT> >#elsetemplate <class charT, class traits >#endifclass basic_regex : public regbase{public:   // typedefs:   typedef std::size_t                           traits_size_type;   typedef typename traits::string_type          traits_string_type;   typedef charT                                 char_type;   typedef traits                                traits_type;   typedef charT                                 value_type;   typedef charT&                                reference;   typedef const charT&                          const_reference;   typedef const charT*                          const_iterator;   typedef const_iterator                        iterator;   typedef std::ptrdiff_t                        difference_type;   typedef std::size_t                           size_type;      typedef regex_constants::syntax_option_type   flag_type;   // locale_type   // placeholder for actual locale type used by the   // traits class to localise *this.   typedef typename traits::locale_type          locale_type;   public:   explicit basic_regex(){}   explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)   {      assign(p, f);   }   basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)   {      assign(p1, p2, f);   }   basic_regex(const charT* p, size_type len, flag_type f)   {      assign(p, len, f);   }   basic_regex(const basic_regex& that)      : m_pimpl(that.m_pimpl) {}   ~basic_regex(){}   basic_regex& BOOST_REGEX_CALL operator=(const basic_regex& that)   {      return assign(that);   }   basic_regex& BOOST_REGEX_CALL operator=(const charT* ptr)   {      return assign(ptr);   }   //   // assign:   basic_regex& assign(const basic_regex& that)   {       m_pimpl = that.m_pimpl;      return *this;    }   basic_regex& assign(const charT* p, flag_type f = regex_constants::normal)   {      return assign(p, p + traits::length(p), f);   }   basic_regex& assign(const charT* p, size_type len, flag_type f)   {      return assign(p, p + len, f);   }private:   basic_regex& do_assign(const charT* p1,                          const charT* p2,                          flag_type f);public:   basic_regex& assign(const charT* p1,                          const charT* p2,                          flag_type f = regex_constants::normal)   {      return do_assign(p1, p2, f);   }#if !defined(BOOST_NO_MEMBER_TEMPLATES)   template <class ST, class SA>   unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)   {       return set_expression(p.data(), p.data() + p.size(), f);    }   template <class ST, class SA>   explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)   {       assign(p, f);    }   template <class InputIterator>   basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)   {      typedef typename traits::string_type seq_type;      seq_type a(arg_first, arg_last);      if(a.size())         assign(static_cast<const charT*>(&*a.begin()), static_cast<const charT*>(&*a.begin() + a.size()), f);      else         assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);   }   template <class ST, class SA>   basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)   {      return assign(p.data(), p.data() + p.size(), regex_constants::normal);   }   template <class string_traits, class A>   basic_regex& BOOST_REGEX_CALL assign(       const std::basic_string<charT, string_traits, A>& s,       flag_type f = regex_constants::normal)   {      return assign(s.data(), s.data() + s.size(), f);   }   template <class InputIterator>   basic_regex& BOOST_REGEX_CALL assign(InputIterator arg_first,                          InputIterator arg_last,                          flag_type f = regex_constants::normal)   {      typedef typename traits::string_type seq_type;      seq_type a(arg_first, arg_last);      if(a.size())      {         const charT* p1 = &*a.begin();         const charT* p2 = &*a.begin() + a.size();         return assign(p1, p2, f);      }      return assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);   }#else   unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)   {       return set_expression(p.data(), p.data() + p.size(), f);    }   basic_regex(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)   {       assign(p, f);    }   basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)   {      return assign(p.data(), p.data() + p.size(), regex_constants::normal);   }   basic_regex& BOOST_REGEX_CALL assign(       const std::basic_string<charT>& s,       flag_type f = regex_constants::normal)   {      return assign(s.data(), s.data() + s.size(), f);   }#endif   //   // locale:   locale_type BOOST_REGEX_CALL imbue(locale_type l);   locale_type BOOST_REGEX_CALL getloc()const   {       return m_pimpl.get() ? m_pimpl->getloc() : locale_type();    }   //   // getflags:   // retained for backwards compatibility only, "flags"   // is now the preferred name:   flag_type BOOST_REGEX_CALL getflags()const   {       return flags();   }   flag_type BOOST_REGEX_CALL flags()const   {       return m_pimpl.get() ? m_pimpl->flags() : 0;   }   //   // str:   std::basic_string<charT> BOOST_REGEX_CALL str()const   {      return m_pimpl.get() ? m_pimpl->str() : std::basic_string<charT>();   }   //   // begin, end, subexpression:   std::pair<const_iterator, const_iterator> BOOST_REGEX_CALL subexpression(std::size_t n)const   {      if(!m_pimpl.get())         boost::throw_exception(std::logic_error("Can't access subexpressions in an invalid regex."));      return m_pimpl->subexpression(n);   }   const_iterator BOOST_REGEX_CALL begin()const   {       return (m_pimpl.get() ? m_pimpl->begin() : 0);    }   const_iterator BOOST_REGEX_CALL end()const   {       return (m_pimpl.get() ? m_pimpl->end() : 0);    }   //   // swap:   void BOOST_REGEX_CALL swap(basic_regex& that)throw()   {      m_pimpl.swap(that.m_pimpl);   }   //   // size:   size_type BOOST_REGEX_CALL size()const   {       return (m_pimpl.get() ? m_pimpl->size() : 0);    }   //   // max_size:   size_type BOOST_REGEX_CALL max_size()const   {       return UINT_MAX;    }   //   // empty:   bool BOOST_REGEX_CALL empty()const   {       return (m_pimpl.get() ? 0 != m_pimpl->status() : true);    }   size_type BOOST_REGEX_CALL mark_count()const    {       return (m_pimpl.get() ? m_pimpl->mark_count() : 0);    }   int status()const   {      return (m_pimpl.get() ? m_pimpl->status() : regex_constants::error_empty);   }   int BOOST_REGEX_CALL compare(const basic_regex& that) const   {      if(m_pimpl.get() == that.m_pimpl.get())         return 0;      if(!m_pimpl.get())         return -1;      if(!that.m_pimpl.get())         return 1;      if(status() != that.status())         return status() - that.status();      if(flags() != that.flags())         return flags() - that.flags();      return str().compare(that.str());   }   bool BOOST_REGEX_CALL operator==(const basic_regex& e)const   {       return compare(e) == 0;    }   bool BOOST_REGEX_CALL operator != (const basic_regex& e)const   {       return compare(e) != 0;    }   bool BOOST_REGEX_CALL operator<(const basic_regex& e)const   {       return compare(e) < 0;    }   bool BOOST_REGEX_CALL operator>(const basic_regex& e)const   {       return compare(e) > 0;    }   bool BOOST_REGEX_CALL operator<=(const basic_regex& e)const   {       return compare(e) <= 0;    }   bool BOOST_REGEX_CALL operator>=(const basic_regex& e)const   {       return compare(e) >= 0;    }   //   // The following are deprecated as public interfaces   // but are available for compatibility with earlier versions.   const charT* BOOST_REGEX_CALL expression()const    {       return (m_pimpl.get() && !m_pimpl->status() ? m_pimpl->expression() : 0);    }   unsigned int BOOST_REGEX_CALL set_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)   {      assign(p1, p2, f | regex_constants::no_except);      return status();   }   unsigned int BOOST_REGEX_CALL set_expression(const charT* p, flag_type f = regex_constants::normal)    {       assign(p, f | regex_constants::no_except);       return status();   }   unsigned int BOOST_REGEX_CALL error_code()const   {      return status();   }   //   // private access methods:   //   const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const   {      BOOST_ASSERT(0 != m_pimpl.get());      return m_pimpl->get_first_state();   }   unsigned get_restart_type()const   {      BOOST_ASSERT(0 != m_pimpl.get());      return m_pimpl->get_restart_type();   }   const unsigned char* get_map()const   {      BOOST_ASSERT(0 != m_pimpl.get());      return m_pimpl->get_map();   }   const ::boost::regex_traits_wrapper<traits>& get_traits()const   {      BOOST_ASSERT(0 != m_pimpl.get());      return m_pimpl->get_traits();   }   bool can_be_null()const   {      BOOST_ASSERT(0 != m_pimpl.get());      return m_pimpl->can_be_null();   }   const BOOST_REGEX_DETAIL_NS::regex_data<charT, traits>& get_data()const   {      BOOST_ASSERT(0 != m_pimpl.get());      return m_pimpl->get_data();   }   boost::shared_ptr<BOOST_REGEX_DETAIL_NS::named_subexpressions > get_named_subs()const   {      return m_pimpl;   }private:   shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > m_pimpl;};//// out of line members;// these are the only members that mutate the basic_regex object,// and are designed to provide the strong exception guarentee// (in the event of a throw, the state of the object remains unchanged).//template <class charT, class traits>basic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,                        const charT* p2,                        flag_type f){   shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp;   if(!m_pimpl.get())   {      temp = shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());   }   else   {      temp = shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>(m_pimpl->m_ptraits));   }   temp->assign(p1, p2, f);   temp.swap(m_pimpl);   return *this;}template <class charT, class traits>typename basic_regex<charT, traits>::locale_type BOOST_REGEX_CALL basic_regex<charT, traits>::imbue(locale_type l){    shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());   locale_type result = temp->imbue(l);   temp.swap(m_pimpl);   return result;}//// non-members://template <class charT, class traits>void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2){   e1.swap(e2);}#ifndef BOOST_NO_STD_LOCALEtemplate <class charT, class traits, class traits2>std::basic_ostream<charT, traits>&    operator << (std::basic_ostream<charT, traits>& os,                 const basic_regex<charT, traits2>& e){   return (os << e.str());}#elsetemplate <class traits>std::ostream& operator << (std::ostream& os, const basic_regex<char, traits>& e){   return (os << e.str());}#endif//// class reg_expression:// this is provided for backwards compatibility only,// it is deprecated, no not use!//#ifdef BOOST_REGEX_NO_FWDtemplate <class charT, class traits = regex_traits<charT> >#elsetemplate <class charT, class traits >#endifclass reg_expression : public basic_regex<charT, traits>{public:   typedef typename basic_regex<charT, traits>::flag_type flag_type;   typedef typename basic_regex<charT, traits>::size_type size_type;   explicit reg_expression(){}   explicit reg_expression(const charT* p, flag_type f = regex_constants::normal)      : basic_regex<charT, traits>(p, f){}   reg_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)      : basic_regex<charT, traits>(p1, p2, f){}   reg_expression(const charT* p, size_type len, flag_type f)      : basic_regex<charT, traits>(p, len, f){}   reg_expression(const reg_expression& that)      : basic_regex<charT, traits>(that) {}   ~reg_expression(){}   reg_expression& BOOST_REGEX_CALL operator=(const reg_expression& that)   {      return this->assign(that);   }#if !defined(BOOST_NO_MEMBER_TEMPLATES)   template <class ST, class SA>   explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)   : basic_regex<charT, traits>(p, f)   {    }   template <class InputIterator>   reg_expression(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)   : basic_regex<charT, traits>(arg_first, arg_last, f)   {   }   template <class ST, class SA>   reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)   {      this->assign(p);      return *this;   }#else   explicit reg_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)   : basic_regex<charT, traits>(p, f)   {    }   reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)   {      this->assign(p);      return *this;   }#endif};#ifdef BOOST_MSVC#pragma warning (pop)#endif} // namespace boost#ifdef BOOST_MSVC#pragma warning(push)#pragma warning(disable: 4103)#endif#ifdef BOOST_HAS_ABI_HEADERS#  include BOOST_ABI_SUFFIX#endif#ifdef BOOST_MSVC#pragma warning(pop)#endif#endif
 |