File indexing completed on 2025-01-30 09:59:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef BOOST_REGEX_V4_MATCH_RESULTS_HPP
0020 #define BOOST_REGEX_V4_MATCH_RESULTS_HPP
0021
0022 #ifdef BOOST_MSVC
0023 #pragma warning(push)
0024 #pragma warning(disable: 4103)
0025 #endif
0026 #ifdef BOOST_HAS_ABI_HEADERS
0027 # include BOOST_ABI_PREFIX
0028 #endif
0029 #ifdef BOOST_MSVC
0030 #pragma warning(pop)
0031 #endif
0032
0033 namespace boost{
0034 #ifdef BOOST_MSVC
0035 #pragma warning(push)
0036 #pragma warning(disable : 4251)
0037 #if BOOST_MSVC < 1700
0038 # pragma warning(disable : 4231)
0039 #endif
0040 # if BOOST_MSVC < 1600
0041 # pragma warning(disable : 4660)
0042 # endif
0043 #endif
0044
0045 namespace BOOST_REGEX_DETAIL_NS{
0046
0047 class named_subexpressions;
0048
0049 }
0050
0051 template <class BidiIterator, class Allocator>
0052 class match_results
0053 {
0054 private:
0055 #ifndef BOOST_NO_STD_ALLOCATOR
0056 typedef std::vector<sub_match<BidiIterator>, Allocator> vector_type;
0057 #else
0058 typedef std::vector<sub_match<BidiIterator> > vector_type;
0059 #endif
0060 public:
0061 typedef sub_match<BidiIterator> value_type;
0062 #ifndef BOOST_NO_CXX11_ALLOCATOR
0063 typedef typename std::allocator_traits<Allocator>::value_type const & const_reference;
0064 #elif !defined(BOOST_NO_STD_ALLOCATOR) && !(defined(BOOST_MSVC) && defined(_STLPORT_VERSION))
0065 typedef typename Allocator::const_reference const_reference;
0066 #else
0067 typedef const value_type& const_reference;
0068 #endif
0069 typedef const_reference reference;
0070 typedef typename vector_type::const_iterator const_iterator;
0071 typedef const_iterator iterator;
0072 typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<
0073 BidiIterator>::difference_type difference_type;
0074 #ifdef BOOST_NO_CXX11_ALLOCATOR
0075 typedef typename Allocator::size_type size_type;
0076 #else
0077 typedef typename std::allocator_traits<Allocator>::size_type size_type;
0078 #endif
0079 typedef Allocator allocator_type;
0080 typedef typename BOOST_REGEX_DETAIL_NS::regex_iterator_traits<
0081 BidiIterator>::value_type char_type;
0082 typedef std::basic_string<char_type> string_type;
0083 typedef BOOST_REGEX_DETAIL_NS::named_subexpressions named_sub_type;
0084
0085
0086 explicit match_results(const Allocator& a = Allocator())
0087 #ifndef BOOST_NO_STD_ALLOCATOR
0088 : m_subs(a), m_base(), m_null(), m_last_closed_paren(0), m_is_singular(true) {}
0089 #else
0090 : m_subs(), m_base(), m_null(), m_last_closed_paren(0), m_is_singular(true) { (void)a; }
0091 #endif
0092
0093
0094
0095
0096
0097 match_results(const match_results& m)
0098 : m_subs(m.m_subs), m_base(), m_null(), m_named_subs(m.m_named_subs), m_last_closed_paren(m.m_last_closed_paren), m_is_singular(m.m_is_singular)
0099 {
0100 if(!m_is_singular)
0101 {
0102 m_base = m.m_base;
0103 m_null = m.m_null;
0104 }
0105 }
0106 match_results& operator=(const match_results& m)
0107 {
0108 m_subs = m.m_subs;
0109 m_named_subs = m.m_named_subs;
0110 m_last_closed_paren = m.m_last_closed_paren;
0111 m_is_singular = m.m_is_singular;
0112 if(!m_is_singular)
0113 {
0114 m_base = m.m_base;
0115 m_null = m.m_null;
0116 }
0117 return *this;
0118 }
0119 ~match_results(){}
0120
0121
0122 size_type size() const
0123 { return empty() ? 0 : m_subs.size() - 2; }
0124 size_type max_size() const
0125 { return m_subs.max_size(); }
0126 bool empty() const
0127 { return m_subs.size() < 2; }
0128
0129 difference_type length(int sub = 0) const
0130 {
0131 if(m_is_singular)
0132 raise_logic_error();
0133 sub += 2;
0134 if((sub < (int)m_subs.size()) && (sub > 0))
0135 return m_subs[sub].length();
0136 return 0;
0137 }
0138 difference_type length(const char_type* sub) const
0139 {
0140 if(m_is_singular)
0141 raise_logic_error();
0142 const char_type* sub_end = sub;
0143 while(*sub_end) ++sub_end;
0144 return length(named_subexpression_index(sub, sub_end));
0145 }
0146 template <class charT>
0147 difference_type length(const charT* sub) const
0148 {
0149 if(m_is_singular)
0150 raise_logic_error();
0151 const charT* sub_end = sub;
0152 while(*sub_end) ++sub_end;
0153 return length(named_subexpression_index(sub, sub_end));
0154 }
0155 template <class charT, class Traits, class A>
0156 difference_type length(const std::basic_string<charT, Traits, A>& sub) const
0157 {
0158 return length(sub.c_str());
0159 }
0160 difference_type position(size_type sub = 0) const
0161 {
0162 if(m_is_singular)
0163 raise_logic_error();
0164 sub += 2;
0165 if(sub < m_subs.size())
0166 {
0167 const sub_match<BidiIterator>& s = m_subs[sub];
0168 if(s.matched || (sub == 2))
0169 {
0170 return ::boost::BOOST_REGEX_DETAIL_NS::distance((BidiIterator)(m_base), (BidiIterator)(s.first));
0171 }
0172 }
0173 return ~static_cast<difference_type>(0);
0174 }
0175 difference_type position(const char_type* sub) const
0176 {
0177 const char_type* sub_end = sub;
0178 while(*sub_end) ++sub_end;
0179 return position(named_subexpression_index(sub, sub_end));
0180 }
0181 template <class charT>
0182 difference_type position(const charT* sub) const
0183 {
0184 const charT* sub_end = sub;
0185 while(*sub_end) ++sub_end;
0186 return position(named_subexpression_index(sub, sub_end));
0187 }
0188 template <class charT, class Traits, class A>
0189 difference_type position(const std::basic_string<charT, Traits, A>& sub) const
0190 {
0191 return position(sub.c_str());
0192 }
0193 string_type str(int sub = 0) const
0194 {
0195 if(m_is_singular)
0196 raise_logic_error();
0197 sub += 2;
0198 string_type result;
0199 if(sub < (int)m_subs.size() && (sub > 0))
0200 {
0201 const sub_match<BidiIterator>& s = m_subs[sub];
0202 if(s.matched)
0203 {
0204 result = s.str();
0205 }
0206 }
0207 return result;
0208 }
0209 string_type str(const char_type* sub) const
0210 {
0211 return (*this)[sub].str();
0212 }
0213 template <class Traits, class A>
0214 string_type str(const std::basic_string<char_type, Traits, A>& sub) const
0215 {
0216 return (*this)[sub].str();
0217 }
0218 template <class charT>
0219 string_type str(const charT* sub) const
0220 {
0221 return (*this)[sub].str();
0222 }
0223 template <class charT, class Traits, class A>
0224 string_type str(const std::basic_string<charT, Traits, A>& sub) const
0225 {
0226 return (*this)[sub].str();
0227 }
0228 const_reference operator[](int sub) const
0229 {
0230 if(m_is_singular && m_subs.empty())
0231 raise_logic_error();
0232 sub += 2;
0233 if(sub < (int)m_subs.size() && (sub >= 0))
0234 {
0235 return m_subs[sub];
0236 }
0237 return m_null;
0238 }
0239
0240
0241
0242 const_reference named_subexpression(const char_type* i, const char_type* j) const
0243 {
0244
0245
0246
0247 if(m_is_singular)
0248 raise_logic_error();
0249 BOOST_REGEX_DETAIL_NS::named_subexpressions::range_type r = m_named_subs->equal_range(i, j);
0250 while((r.first != r.second) && ((*this)[r.first->index].matched == false))
0251 ++r.first;
0252 return r.first != r.second ? (*this)[r.first->index] : m_null;
0253 }
0254 template <class charT>
0255 const_reference named_subexpression(const charT* i, const charT* j) const
0256 {
0257 BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
0258 if(i == j)
0259 return m_null;
0260 std::vector<char_type> s;
0261 while(i != j)
0262 s.insert(s.end(), *i++);
0263 return named_subexpression(&*s.begin(), &*s.begin() + s.size());
0264 }
0265 int named_subexpression_index(const char_type* i, const char_type* j) const
0266 {
0267
0268
0269
0270
0271
0272 if(m_is_singular)
0273 raise_logic_error();
0274 BOOST_REGEX_DETAIL_NS::named_subexpressions::range_type s, r;
0275 s = r = m_named_subs->equal_range(i, j);
0276 while((r.first != r.second) && ((*this)[r.first->index].matched == false))
0277 ++r.first;
0278 if(r.first == r.second)
0279 r = s;
0280 return r.first != r.second ? r.first->index : -20;
0281 }
0282 template <class charT>
0283 int named_subexpression_index(const charT* i, const charT* j) const
0284 {
0285 BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
0286 if(i == j)
0287 return -20;
0288 std::vector<char_type> s;
0289 while(i != j)
0290 s.insert(s.end(), *i++);
0291 return named_subexpression_index(&*s.begin(), &*s.begin() + s.size());
0292 }
0293 template <class Traits, class A>
0294 const_reference operator[](const std::basic_string<char_type, Traits, A>& s) const
0295 {
0296 return named_subexpression(s.c_str(), s.c_str() + s.size());
0297 }
0298 const_reference operator[](const char_type* p) const
0299 {
0300 const char_type* e = p;
0301 while(*e) ++e;
0302 return named_subexpression(p, e);
0303 }
0304
0305 template <class charT>
0306 const_reference operator[](const charT* p) const
0307 {
0308 BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
0309 if(*p == 0)
0310 return m_null;
0311 std::vector<char_type> s;
0312 while(*p)
0313 s.insert(s.end(), *p++);
0314 return named_subexpression(&*s.begin(), &*s.begin() + s.size());
0315 }
0316 template <class charT, class Traits, class A>
0317 const_reference operator[](const std::basic_string<charT, Traits, A>& ns) const
0318 {
0319 BOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
0320 if(ns.empty())
0321 return m_null;
0322 std::vector<char_type> s;
0323 for(unsigned i = 0; i < ns.size(); ++i)
0324 s.insert(s.end(), ns[i]);
0325 return named_subexpression(&*s.begin(), &*s.begin() + s.size());
0326 }
0327
0328 const_reference prefix() const
0329 {
0330 if(m_is_singular)
0331 raise_logic_error();
0332 return (*this)[-1];
0333 }
0334
0335 const_reference suffix() const
0336 {
0337 if(m_is_singular)
0338 raise_logic_error();
0339 return (*this)[-2];
0340 }
0341 const_iterator begin() const
0342 {
0343 return (m_subs.size() > 2) ? (m_subs.begin() + 2) : m_subs.end();
0344 }
0345 const_iterator end() const
0346 {
0347 return m_subs.end();
0348 }
0349
0350 template <class OutputIterator, class Functor>
0351 OutputIterator format(OutputIterator out,
0352 Functor fmt,
0353 match_flag_type flags = format_default) const
0354 {
0355 if(m_is_singular)
0356 raise_logic_error();
0357 typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator>::type F;
0358 F func(fmt);
0359 return func(*this, out, flags);
0360 }
0361 template <class Functor>
0362 string_type format(Functor fmt, match_flag_type flags = format_default) const
0363 {
0364 if(m_is_singular)
0365 raise_logic_error();
0366 std::basic_string<char_type> result;
0367 BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > i(result);
0368
0369 typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > >::type F;
0370 F func(fmt);
0371
0372 func(*this, i, flags);
0373 return result;
0374 }
0375
0376 template <class OutputIterator, class Functor, class RegexT>
0377 OutputIterator format(OutputIterator out,
0378 Functor fmt,
0379 match_flag_type flags,
0380 const RegexT& re) const
0381 {
0382 if(m_is_singular)
0383 raise_logic_error();
0384 typedef ::boost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;
0385 typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator, traits_type>::type F;
0386 F func(fmt);
0387 return func(*this, out, flags, re.get_traits());
0388 }
0389 template <class RegexT, class Functor>
0390 string_type format(Functor fmt,
0391 match_flag_type flags,
0392 const RegexT& re) const
0393 {
0394 if(m_is_singular)
0395 raise_logic_error();
0396 typedef ::boost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;
0397 std::basic_string<char_type> result;
0398 BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> > i(result);
0399
0400 typedef typename BOOST_REGEX_DETAIL_NS::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, BOOST_REGEX_DETAIL_NS::string_out_iterator<std::basic_string<char_type> >, traits_type >::type F;
0401 F func(fmt);
0402
0403 func(*this, i, flags, re.get_traits());
0404 return result;
0405 }
0406
0407 const_reference get_last_closed_paren()const
0408 {
0409 if(m_is_singular)
0410 raise_logic_error();
0411 return m_last_closed_paren == 0 ? m_null : (*this)[m_last_closed_paren];
0412 }
0413
0414 allocator_type get_allocator() const
0415 {
0416 #ifndef BOOST_NO_STD_ALLOCATOR
0417 return m_subs.get_allocator();
0418 #else
0419 return allocator_type();
0420 #endif
0421 }
0422 void swap(match_results& that)
0423 {
0424 std::swap(m_subs, that.m_subs);
0425 std::swap(m_named_subs, that.m_named_subs);
0426 std::swap(m_last_closed_paren, that.m_last_closed_paren);
0427 if(m_is_singular)
0428 {
0429 if(!that.m_is_singular)
0430 {
0431 m_base = that.m_base;
0432 m_null = that.m_null;
0433 }
0434 }
0435 else if(that.m_is_singular)
0436 {
0437 that.m_base = m_base;
0438 that.m_null = m_null;
0439 }
0440 else
0441 {
0442 std::swap(m_base, that.m_base);
0443 std::swap(m_null, that.m_null);
0444 }
0445 std::swap(m_is_singular, that.m_is_singular);
0446 }
0447 bool operator==(const match_results& that)const
0448 {
0449 if(m_is_singular)
0450 {
0451 return that.m_is_singular;
0452 }
0453 else if(that.m_is_singular)
0454 {
0455 return false;
0456 }
0457 return (m_subs == that.m_subs) && (m_base == that.m_base) && (m_last_closed_paren == that.m_last_closed_paren);
0458 }
0459 bool operator!=(const match_results& that)const
0460 { return !(*this == that); }
0461
0462 #ifdef BOOST_REGEX_MATCH_EXTRA
0463 typedef typename sub_match<BidiIterator>::capture_sequence_type capture_sequence_type;
0464
0465 const capture_sequence_type& captures(int i)const
0466 {
0467 if(m_is_singular)
0468 raise_logic_error();
0469 return (*this)[i].captures();
0470 }
0471 #endif
0472
0473
0474
0475 void BOOST_REGEX_CALL set_second(BidiIterator i)
0476 {
0477 BOOST_REGEX_ASSERT(m_subs.size() > 2);
0478 m_subs[2].second = i;
0479 m_subs[2].matched = true;
0480 m_subs[0].first = i;
0481 m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
0482 m_null.first = i;
0483 m_null.second = i;
0484 m_null.matched = false;
0485 m_is_singular = false;
0486 }
0487
0488 void BOOST_REGEX_CALL set_second(BidiIterator i, size_type pos, bool m = true, bool escape_k = false)
0489 {
0490 if(pos)
0491 m_last_closed_paren = static_cast<int>(pos);
0492 pos += 2;
0493 BOOST_REGEX_ASSERT(m_subs.size() > pos);
0494 m_subs[pos].second = i;
0495 m_subs[pos].matched = m;
0496 if((pos == 2) && !escape_k)
0497 {
0498 m_subs[0].first = i;
0499 m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
0500 m_null.first = i;
0501 m_null.second = i;
0502 m_null.matched = false;
0503 m_is_singular = false;
0504 }
0505 }
0506 void BOOST_REGEX_CALL set_size(size_type n, BidiIterator i, BidiIterator j)
0507 {
0508 value_type v(j);
0509 size_type len = m_subs.size();
0510 if(len > n + 2)
0511 {
0512 m_subs.erase(m_subs.begin()+n+2, m_subs.end());
0513 std::fill(m_subs.begin(), m_subs.end(), v);
0514 }
0515 else
0516 {
0517 std::fill(m_subs.begin(), m_subs.end(), v);
0518 if(n+2 != len)
0519 m_subs.insert(m_subs.end(), n+2-len, v);
0520 }
0521 m_subs[1].first = i;
0522 m_last_closed_paren = 0;
0523 }
0524 void BOOST_REGEX_CALL set_base(BidiIterator pos)
0525 {
0526 m_base = pos;
0527 }
0528 BidiIterator base()const
0529 {
0530 return m_base;
0531 }
0532 void BOOST_REGEX_CALL set_first(BidiIterator i)
0533 {
0534 BOOST_REGEX_ASSERT(m_subs.size() > 2);
0535
0536 m_subs[1].second = i;
0537 m_subs[1].matched = (m_subs[1].first != i);
0538
0539 m_subs[2].first = i;
0540
0541 for(size_type n = 3; n < m_subs.size(); ++n)
0542 {
0543 m_subs[n].first = m_subs[n].second = m_subs[0].second;
0544 m_subs[n].matched = false;
0545 }
0546 }
0547 void BOOST_REGEX_CALL set_first(BidiIterator i, size_type pos, bool escape_k = false)
0548 {
0549 BOOST_REGEX_ASSERT(pos+2 < m_subs.size());
0550 if(pos || escape_k)
0551 {
0552 m_subs[pos+2].first = i;
0553 if(escape_k)
0554 {
0555 m_subs[1].second = i;
0556 m_subs[1].matched = (m_subs[1].first != m_subs[1].second);
0557 }
0558 }
0559 else
0560 set_first(i);
0561 }
0562 void BOOST_REGEX_CALL maybe_assign(const match_results<BidiIterator, Allocator>& m);
0563
0564 void BOOST_REGEX_CALL set_named_subs(boost::shared_ptr<named_sub_type> subs)
0565 {
0566 m_named_subs = subs;
0567 }
0568
0569 private:
0570
0571
0572
0573 static void raise_logic_error()
0574 {
0575 std::logic_error e("Attempt to access an uninitialized boost::match_results<> class.");
0576 boost::throw_exception(e);
0577 }
0578
0579
0580 vector_type m_subs;
0581 BidiIterator m_base;
0582 sub_match<BidiIterator> m_null;
0583 boost::shared_ptr<named_sub_type> m_named_subs;
0584 int m_last_closed_paren;
0585 bool m_is_singular;
0586 };
0587
0588 template <class BidiIterator, class Allocator>
0589 void BOOST_REGEX_CALL match_results<BidiIterator, Allocator>::maybe_assign(const match_results<BidiIterator, Allocator>& m)
0590 {
0591 if(m_is_singular)
0592 {
0593 *this = m;
0594 return;
0595 }
0596 const_iterator p1, p2;
0597 p1 = begin();
0598 p2 = m.begin();
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609 BidiIterator l_end = this->suffix().second;
0610 BidiIterator l_base = (p1->first == l_end) ? this->prefix().first : (*this)[0].first;
0611 difference_type len1 = 0;
0612 difference_type len2 = 0;
0613 difference_type base1 = 0;
0614 difference_type base2 = 0;
0615 std::size_t i;
0616 for(i = 0; i < size(); ++i, ++p1, ++p2)
0617 {
0618
0619
0620
0621
0622
0623
0624
0625 if(p1->first == l_end)
0626 {
0627 if(p2->first != l_end)
0628 {
0629
0630
0631 base1 = 1;
0632 base2 = 0;
0633 break;
0634 }
0635 else
0636 {
0637
0638
0639 if((p1->matched == false) && (p2->matched == true))
0640 break;
0641 if((p1->matched == true) && (p2->matched == false))
0642 return;
0643 continue;
0644 }
0645 }
0646 else if(p2->first == l_end)
0647 {
0648
0649 return;
0650 }
0651 base1 = ::boost::BOOST_REGEX_DETAIL_NS::distance(l_base, p1->first);
0652 base2 = ::boost::BOOST_REGEX_DETAIL_NS::distance(l_base, p2->first);
0653 BOOST_REGEX_ASSERT(base1 >= 0);
0654 BOOST_REGEX_ASSERT(base2 >= 0);
0655 if(base1 < base2) return;
0656 if(base2 < base1) break;
0657
0658 len1 = ::boost::BOOST_REGEX_DETAIL_NS::distance((BidiIterator)p1->first, (BidiIterator)p1->second);
0659 len2 = ::boost::BOOST_REGEX_DETAIL_NS::distance((BidiIterator)p2->first, (BidiIterator)p2->second);
0660 BOOST_REGEX_ASSERT(len1 >= 0);
0661 BOOST_REGEX_ASSERT(len2 >= 0);
0662 if((len1 != len2) || ((p1->matched == false) && (p2->matched == true)))
0663 break;
0664 if((p1->matched == true) && (p2->matched == false))
0665 return;
0666 }
0667 if(i == size())
0668 return;
0669 if(base2 < base1)
0670 *this = m;
0671 else if((len2 > len1) || ((p1->matched == false) && (p2->matched == true)) )
0672 *this = m;
0673 }
0674
0675 template <class BidiIterator, class Allocator>
0676 void swap(match_results<BidiIterator, Allocator>& a, match_results<BidiIterator, Allocator>& b)
0677 {
0678 a.swap(b);
0679 }
0680
0681 #ifndef BOOST_NO_STD_LOCALE
0682 template <class charT, class traits, class BidiIterator, class Allocator>
0683 std::basic_ostream<charT, traits>&
0684 operator << (std::basic_ostream<charT, traits>& os,
0685 const match_results<BidiIterator, Allocator>& s)
0686 {
0687 return (os << s.str());
0688 }
0689 #else
0690 template <class BidiIterator, class Allocator>
0691 std::ostream& operator << (std::ostream& os,
0692 const match_results<BidiIterator, Allocator>& s)
0693 {
0694 return (os << s.str());
0695 }
0696 #endif
0697
0698 #ifdef BOOST_MSVC
0699 #pragma warning(pop)
0700 #endif
0701 }
0702
0703 #ifdef BOOST_MSVC
0704 #pragma warning(push)
0705 #pragma warning(disable: 4103)
0706 #endif
0707 #ifdef BOOST_HAS_ABI_HEADERS
0708 # include BOOST_ABI_SUFFIX
0709 #endif
0710 #ifdef BOOST_MSVC
0711 #pragma warning(pop)
0712 #endif
0713
0714 #endif
0715
0716