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