File indexing completed on 2025-12-16 10:08:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef BOOST_REGEX_V5_BASIC_REGEX_HPP
0020 #define BOOST_REGEX_V5_BASIC_REGEX_HPP
0021
0022 #include <vector>
0023
0024 namespace boost{
0025 #ifdef BOOST_REGEX_MSVC
0026 #pragma warning(push)
0027 #pragma warning(disable : 4251)
0028 #if BOOST_REGEX_MSVC < 1700
0029 # pragma warning(disable : 4231)
0030 #endif
0031 #if BOOST_REGEX_MSVC < 1600
0032 #pragma warning(disable : 4660)
0033 #endif
0034 #if BOOST_REGEX_MSVC < 1910
0035 #pragma warning(disable:4800)
0036 #endif
0037 #endif
0038
0039 namespace BOOST_REGEX_DETAIL_NS{
0040
0041
0042
0043
0044 template <class charT, class traits>
0045 class basic_regex_parser;
0046
0047 template <class I>
0048 void bubble_down_one(I first, I last)
0049 {
0050 if(first != last)
0051 {
0052 I next = last - 1;
0053 while((next != first) && (*next < *(next-1)))
0054 {
0055 (next-1)->swap(*next);
0056 --next;
0057 }
0058 }
0059 }
0060
0061 static const int hash_value_mask = 1 << (std::numeric_limits<int>::digits - 1);
0062
0063 template <class Iterator>
0064 inline int hash_value_from_capture_name(Iterator i, Iterator j)
0065 {
0066 std::size_t r = 0;
0067 while (i != j)
0068 {
0069 r ^= *i + 0x9e3779b9 + (r << 6) + (r >> 2);
0070 ++i;
0071 }
0072 r %= ((std::numeric_limits<int>::max)());
0073 return static_cast<int>(r) | hash_value_mask;
0074 }
0075
0076 class named_subexpressions
0077 {
0078 public:
0079 struct name
0080 {
0081 template <class charT>
0082 name(const charT* i, const charT* j, int idx)
0083 : index(idx)
0084 {
0085 hash = hash_value_from_capture_name(i, j);
0086 }
0087 name(int h, int idx)
0088 : index(idx), hash(h)
0089 {
0090 }
0091 int index;
0092 int hash;
0093 bool operator < (const name& other)const
0094 {
0095 return hash < other.hash;
0096 }
0097 bool operator == (const name& other)const
0098 {
0099 return hash == other.hash;
0100 }
0101 void swap(name& other)
0102 {
0103 std::swap(index, other.index);
0104 std::swap(hash, other.hash);
0105 }
0106 };
0107
0108 typedef std::vector<name>::const_iterator const_iterator;
0109 typedef std::pair<const_iterator, const_iterator> range_type;
0110
0111 named_subexpressions(){}
0112
0113 template <class charT>
0114 void set_name(const charT* i, const charT* j, int index)
0115 {
0116 m_sub_names.push_back(name(i, j, index));
0117 bubble_down_one(m_sub_names.begin(), m_sub_names.end());
0118 }
0119 template <class charT>
0120 int get_id(const charT* i, const charT* j)const
0121 {
0122 name t(i, j, 0);
0123 typename std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);
0124 if((pos != m_sub_names.end()) && (*pos == t))
0125 {
0126 return pos->index;
0127 }
0128 return -1;
0129 }
0130 template <class charT>
0131 range_type equal_range(const charT* i, const charT* j)const
0132 {
0133 name t(i, j, 0);
0134 return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);
0135 }
0136 int get_id(int h)const
0137 {
0138 name t(h, 0);
0139 std::vector<name>::const_iterator pos = std::lower_bound(m_sub_names.begin(), m_sub_names.end(), t);
0140 if((pos != m_sub_names.end()) && (*pos == t))
0141 {
0142 return pos->index;
0143 }
0144 return -1;
0145 }
0146 range_type equal_range(int h)const
0147 {
0148 name t(h, 0);
0149 return std::equal_range(m_sub_names.begin(), m_sub_names.end(), t);
0150 }
0151 private:
0152 std::vector<name> m_sub_names;
0153 };
0154
0155
0156
0157
0158
0159 template <class charT, class traits>
0160 struct regex_data : public named_subexpressions
0161 {
0162 typedef regex_constants::syntax_option_type flag_type;
0163 typedef std::size_t size_type;
0164
0165 regex_data(const ::std::shared_ptr<
0166 ::boost::regex_traits_wrapper<traits> >& t)
0167 : m_ptraits(t), m_flags(0), m_status(0), m_expression(0), m_expression_len(0),
0168 m_mark_count(0), m_first_state(0), m_restart_type(0),
0169 m_startmap{ 0 },
0170 m_can_be_null(0), m_word_mask(0), m_has_recursions(false), m_disable_match_any(false) {}
0171 regex_data()
0172 : m_ptraits(new ::boost::regex_traits_wrapper<traits>()), m_flags(0), m_status(0), m_expression(0), m_expression_len(0),
0173 m_mark_count(0), m_first_state(0), m_restart_type(0),
0174 m_startmap{ 0 },
0175 m_can_be_null(0), m_word_mask(0), m_has_recursions(false), m_disable_match_any(false) {}
0176
0177 ::std::shared_ptr<
0178 ::boost::regex_traits_wrapper<traits>
0179 > m_ptraits;
0180 flag_type m_flags;
0181 int m_status;
0182 const charT* m_expression;
0183 std::ptrdiff_t m_expression_len;
0184 size_type m_mark_count;
0185 BOOST_REGEX_DETAIL_NS::re_syntax_base* m_first_state;
0186 unsigned m_restart_type;
0187 unsigned char m_startmap[1 << CHAR_BIT];
0188 unsigned int m_can_be_null;
0189 BOOST_REGEX_DETAIL_NS::raw_storage m_data;
0190 typename traits::char_class_type m_word_mask;
0191 std::vector<
0192 std::pair<
0193 std::size_t, std::size_t> > m_subs;
0194 bool m_has_recursions;
0195 bool m_disable_match_any;
0196 };
0197
0198
0199
0200
0201 template <class charT, class traits>
0202 class basic_regex_implementation
0203 : public regex_data<charT, traits>
0204 {
0205 public:
0206 typedef regex_constants::syntax_option_type flag_type;
0207 typedef std::ptrdiff_t difference_type;
0208 typedef std::size_t size_type;
0209 typedef typename traits::locale_type locale_type;
0210 typedef const charT* const_iterator;
0211
0212 basic_regex_implementation(){}
0213 basic_regex_implementation(const ::std::shared_ptr<
0214 ::boost::regex_traits_wrapper<traits> >& t)
0215 : regex_data<charT, traits>(t) {}
0216 void assign(const charT* arg_first,
0217 const charT* arg_last,
0218 flag_type f)
0219 {
0220 regex_data<charT, traits>* pdat = this;
0221 basic_regex_parser<charT, traits> parser(pdat);
0222 parser.parse(arg_first, arg_last, f);
0223 }
0224
0225 locale_type imbue(locale_type l)
0226 {
0227 return this->m_ptraits->imbue(l);
0228 }
0229 locale_type getloc()const
0230 {
0231 return this->m_ptraits->getloc();
0232 }
0233 std::basic_string<charT> str()const
0234 {
0235 std::basic_string<charT> result;
0236 if(this->m_status == 0)
0237 result = std::basic_string<charT>(this->m_expression, this->m_expression_len);
0238 return result;
0239 }
0240 const_iterator expression()const
0241 {
0242 return this->m_expression;
0243 }
0244 std::pair<const_iterator, const_iterator> subexpression(std::size_t n)const
0245 {
0246 const std::pair<std::size_t, std::size_t>& pi = this->m_subs.at(n);
0247 std::pair<const_iterator, const_iterator> p(expression() + pi.first, expression() + pi.second);
0248 return p;
0249 }
0250
0251
0252 const_iterator begin()const
0253 {
0254 return (this->m_status ? 0 : this->m_expression);
0255 }
0256 const_iterator end()const
0257 {
0258 return (this->m_status ? 0 : this->m_expression + this->m_expression_len);
0259 }
0260 flag_type flags()const
0261 {
0262 return this->m_flags;
0263 }
0264 size_type size()const
0265 {
0266 return this->m_expression_len;
0267 }
0268 int status()const
0269 {
0270 return this->m_status;
0271 }
0272 size_type mark_count()const
0273 {
0274 return this->m_mark_count - 1;
0275 }
0276 const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const
0277 {
0278 return this->m_first_state;
0279 }
0280 unsigned get_restart_type()const
0281 {
0282 return this->m_restart_type;
0283 }
0284 const unsigned char* get_map()const
0285 {
0286 return this->m_startmap;
0287 }
0288 const ::boost::regex_traits_wrapper<traits>& get_traits()const
0289 {
0290 return *(this->m_ptraits);
0291 }
0292 bool can_be_null()const
0293 {
0294 return this->m_can_be_null;
0295 }
0296 const regex_data<charT, traits>& get_data()const
0297 {
0298 basic_regex_implementation<charT, traits> const* p = this;
0299 return *static_cast<const regex_data<charT, traits>*>(p);
0300 }
0301 };
0302
0303 }
0304
0305
0306
0307
0308
0309
0310 #ifdef BOOST_REGEX_NO_FWD
0311 template <class charT, class traits = regex_traits<charT> >
0312 #else
0313 template <class charT, class traits >
0314 #endif
0315 class basic_regex : public regbase
0316 {
0317 public:
0318
0319 typedef std::size_t traits_size_type;
0320 typedef typename traits::string_type traits_string_type;
0321 typedef charT char_type;
0322 typedef traits traits_type;
0323
0324 typedef charT value_type;
0325 typedef charT& reference;
0326 typedef const charT& const_reference;
0327 typedef const charT* const_iterator;
0328 typedef const_iterator iterator;
0329 typedef std::ptrdiff_t difference_type;
0330 typedef std::size_t size_type;
0331 typedef regex_constants::syntax_option_type flag_type;
0332
0333
0334
0335 typedef typename traits::locale_type locale_type;
0336
0337 public:
0338 explicit basic_regex(){}
0339 explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)
0340 {
0341 assign(p, f);
0342 }
0343 basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
0344 {
0345 assign(p1, p2, f);
0346 }
0347 basic_regex(const charT* p, size_type len, flag_type f)
0348 {
0349 assign(p, len, f);
0350 }
0351 basic_regex(const basic_regex& that)
0352 : m_pimpl(that.m_pimpl) {}
0353 ~basic_regex(){}
0354 basic_regex& operator=(const basic_regex& that)
0355 {
0356 return assign(that);
0357 }
0358 basic_regex& operator=(const charT* ptr)
0359 {
0360 return assign(ptr);
0361 }
0362
0363
0364
0365 basic_regex& assign(const basic_regex& that)
0366 {
0367 m_pimpl = that.m_pimpl;
0368 return *this;
0369 }
0370 basic_regex& assign(const charT* p, flag_type f = regex_constants::normal)
0371 {
0372 return assign(p, p + traits::length(p), f);
0373 }
0374 basic_regex& assign(const charT* p, size_type len, flag_type f)
0375 {
0376 return assign(p, p + len, f);
0377 }
0378 private:
0379 basic_regex& do_assign(const charT* p1,
0380 const charT* p2,
0381 flag_type f);
0382 public:
0383 basic_regex& assign(const charT* p1,
0384 const charT* p2,
0385 flag_type f = regex_constants::normal)
0386 {
0387 return do_assign(p1, p2, f);
0388 }
0389
0390 template <class ST, class SA>
0391 unsigned int set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
0392 {
0393 return set_expression(p.data(), p.data() + p.size(), f);
0394 }
0395
0396 template <class ST, class SA>
0397 explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
0398 {
0399 assign(p, f);
0400 }
0401
0402 template <class InputIterator>
0403 basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
0404 {
0405 typedef typename traits::string_type seq_type;
0406 seq_type a(arg_first, arg_last);
0407 if(!a.empty())
0408 assign(static_cast<const charT*>(&*a.begin()), static_cast<const charT*>(&*a.begin() + a.size()), f);
0409 else
0410 assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
0411 }
0412
0413 template <class ST, class SA>
0414 basic_regex& operator=(const std::basic_string<charT, ST, SA>& p)
0415 {
0416 return assign(p.data(), p.data() + p.size(), regex_constants::normal);
0417 }
0418
0419 template <class string_traits, class A>
0420 basic_regex& assign(
0421 const std::basic_string<charT, string_traits, A>& s,
0422 flag_type f = regex_constants::normal)
0423 {
0424 return assign(s.data(), s.data() + s.size(), f);
0425 }
0426
0427 template <class InputIterator>
0428 basic_regex& assign(InputIterator arg_first,
0429 InputIterator arg_last,
0430 flag_type f = regex_constants::normal)
0431 {
0432 typedef typename traits::string_type seq_type;
0433 seq_type a(arg_first, arg_last);
0434 if(a.size())
0435 {
0436 const charT* p1 = &*a.begin();
0437 const charT* p2 = &*a.begin() + a.size();
0438 return assign(p1, p2, f);
0439 }
0440 return assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
0441 }
0442
0443
0444
0445 locale_type imbue(locale_type l);
0446 locale_type getloc()const
0447 {
0448 return m_pimpl.get() ? m_pimpl->getloc() : locale_type();
0449 }
0450
0451
0452
0453
0454 flag_type getflags()const
0455 {
0456 return flags();
0457 }
0458 flag_type flags()const
0459 {
0460 return m_pimpl.get() ? m_pimpl->flags() : 0;
0461 }
0462
0463
0464 std::basic_string<charT> str()const
0465 {
0466 return m_pimpl.get() ? m_pimpl->str() : std::basic_string<charT>();
0467 }
0468
0469
0470 std::pair<const_iterator, const_iterator> subexpression(std::size_t n)const
0471 {
0472 #ifdef BOOST_REGEX_STANDALONE
0473 if (!m_pimpl.get())
0474 throw std::logic_error("Can't access subexpressions in an invalid regex.");
0475 #else
0476 if(!m_pimpl.get())
0477 boost::throw_exception(std::logic_error("Can't access subexpressions in an invalid regex."));
0478 #endif
0479 return m_pimpl->subexpression(n);
0480 }
0481 const_iterator begin()const
0482 {
0483 return (m_pimpl.get() ? m_pimpl->begin() : 0);
0484 }
0485 const_iterator end()const
0486 {
0487 return (m_pimpl.get() ? m_pimpl->end() : 0);
0488 }
0489
0490
0491 void swap(basic_regex& that)throw()
0492 {
0493 m_pimpl.swap(that.m_pimpl);
0494 }
0495
0496
0497 size_type size()const
0498 {
0499 return (m_pimpl.get() ? m_pimpl->size() : 0);
0500 }
0501
0502
0503 size_type max_size()const
0504 {
0505 return UINT_MAX;
0506 }
0507
0508
0509 bool empty()const
0510 {
0511 return (m_pimpl.get() ? 0 != m_pimpl->status() : true);
0512 }
0513
0514 size_type mark_count()const
0515 {
0516 return (m_pimpl.get() ? m_pimpl->mark_count() : 0);
0517 }
0518
0519 int status()const
0520 {
0521 return (m_pimpl.get() ? m_pimpl->status() : regex_constants::error_empty);
0522 }
0523
0524 int compare(const basic_regex& that) const
0525 {
0526 if(m_pimpl.get() == that.m_pimpl.get())
0527 return 0;
0528 if(!m_pimpl.get())
0529 return -1;
0530 if(!that.m_pimpl.get())
0531 return 1;
0532 if(status() != that.status())
0533 return status() - that.status();
0534 if(flags() != that.flags())
0535 return flags() - that.flags();
0536 return str().compare(that.str());
0537 }
0538 bool operator==(const basic_regex& e)const
0539 {
0540 return compare(e) == 0;
0541 }
0542 bool operator != (const basic_regex& e)const
0543 {
0544 return compare(e) != 0;
0545 }
0546 bool operator<(const basic_regex& e)const
0547 {
0548 return compare(e) < 0;
0549 }
0550 bool operator>(const basic_regex& e)const
0551 {
0552 return compare(e) > 0;
0553 }
0554 bool operator<=(const basic_regex& e)const
0555 {
0556 return compare(e) <= 0;
0557 }
0558 bool operator>=(const basic_regex& e)const
0559 {
0560 return compare(e) >= 0;
0561 }
0562
0563
0564
0565
0566 const charT* expression()const
0567 {
0568 return (m_pimpl.get() && !m_pimpl->status() ? m_pimpl->expression() : 0);
0569 }
0570 unsigned int set_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
0571 {
0572 assign(p1, p2, f | regex_constants::no_except);
0573 return status();
0574 }
0575 unsigned int set_expression(const charT* p, flag_type f = regex_constants::normal)
0576 {
0577 assign(p, f | regex_constants::no_except);
0578 return status();
0579 }
0580 unsigned int error_code()const
0581 {
0582 return status();
0583 }
0584
0585
0586
0587 const BOOST_REGEX_DETAIL_NS::re_syntax_base* get_first_state()const
0588 {
0589 BOOST_REGEX_ASSERT(0 != m_pimpl.get());
0590 return m_pimpl->get_first_state();
0591 }
0592 unsigned get_restart_type()const
0593 {
0594 BOOST_REGEX_ASSERT(0 != m_pimpl.get());
0595 return m_pimpl->get_restart_type();
0596 }
0597 const unsigned char* get_map()const
0598 {
0599 BOOST_REGEX_ASSERT(0 != m_pimpl.get());
0600 return m_pimpl->get_map();
0601 }
0602 const ::boost::regex_traits_wrapper<traits>& get_traits()const
0603 {
0604 BOOST_REGEX_ASSERT(0 != m_pimpl.get());
0605 return m_pimpl->get_traits();
0606 }
0607 bool can_be_null()const
0608 {
0609 BOOST_REGEX_ASSERT(0 != m_pimpl.get());
0610 return m_pimpl->can_be_null();
0611 }
0612 const BOOST_REGEX_DETAIL_NS::regex_data<charT, traits>& get_data()const
0613 {
0614 BOOST_REGEX_ASSERT(0 != m_pimpl.get());
0615 return m_pimpl->get_data();
0616 }
0617 std::shared_ptr<BOOST_REGEX_DETAIL_NS::named_subexpressions > get_named_subs()const
0618 {
0619 return m_pimpl;
0620 }
0621
0622 private:
0623 std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > m_pimpl;
0624 };
0625
0626
0627
0628
0629
0630
0631
0632 template <class charT, class traits>
0633 basic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,
0634 const charT* p2,
0635 flag_type f)
0636 {
0637 std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp;
0638 if(!m_pimpl.get())
0639 {
0640 temp = std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> >(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());
0641 }
0642 else
0643 {
0644 temp = std::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));
0645 }
0646 temp->assign(p1, p2, f);
0647 temp.swap(m_pimpl);
0648 return *this;
0649 }
0650
0651 template <class charT, class traits>
0652 typename basic_regex<charT, traits>::locale_type basic_regex<charT, traits>::imbue(locale_type l)
0653 {
0654 std::shared_ptr<BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits> > temp(new BOOST_REGEX_DETAIL_NS::basic_regex_implementation<charT, traits>());
0655 locale_type result = temp->imbue(l);
0656 temp.swap(m_pimpl);
0657 return result;
0658 }
0659
0660
0661
0662
0663 template <class charT, class traits>
0664 void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2)
0665 {
0666 e1.swap(e2);
0667 }
0668
0669 template <class charT, class traits, class traits2>
0670 std::basic_ostream<charT, traits>&
0671 operator << (std::basic_ostream<charT, traits>& os,
0672 const basic_regex<charT, traits2>& e)
0673 {
0674 return (os << e.str());
0675 }
0676
0677
0678
0679
0680
0681
0682 #ifdef BOOST_REGEX_NO_FWD
0683 template <class charT, class traits = regex_traits<charT> >
0684 #else
0685 template <class charT, class traits >
0686 #endif
0687 class reg_expression : public basic_regex<charT, traits>
0688 {
0689 public:
0690 typedef typename basic_regex<charT, traits>::flag_type flag_type;
0691 typedef typename basic_regex<charT, traits>::size_type size_type;
0692 explicit reg_expression(){}
0693 explicit reg_expression(const charT* p, flag_type f = regex_constants::normal)
0694 : basic_regex<charT, traits>(p, f){}
0695 reg_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
0696 : basic_regex<charT, traits>(p1, p2, f){}
0697 reg_expression(const charT* p, size_type len, flag_type f)
0698 : basic_regex<charT, traits>(p, len, f){}
0699 reg_expression(const reg_expression& that)
0700 : basic_regex<charT, traits>(that) {}
0701 ~reg_expression(){}
0702 reg_expression& operator=(const reg_expression& that)
0703 {
0704 return this->assign(that);
0705 }
0706
0707 template <class ST, class SA>
0708 explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
0709 : basic_regex<charT, traits>(p, f)
0710 {
0711 }
0712
0713 template <class InputIterator>
0714 reg_expression(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
0715 : basic_regex<charT, traits>(arg_first, arg_last, f)
0716 {
0717 }
0718
0719 template <class ST, class SA>
0720 reg_expression& operator=(const std::basic_string<charT, ST, SA>& p)
0721 {
0722 this->assign(p);
0723 return *this;
0724 }
0725
0726 };
0727
0728 #ifdef BOOST_REGEX_MSVC
0729 #pragma warning (pop)
0730 #endif
0731
0732 }
0733
0734 #endif