Chris@16: /* Chris@16: * Chris@16: * Copyright (c) 1998-2002 Chris@16: * John Maddock Chris@16: * Chris@16: * Use, modification and distribution are subject to the Chris@16: * Boost Software License, Version 1.0. (See accompanying file Chris@16: * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: * Chris@16: */ Chris@16: Chris@16: /* Chris@16: * LOCATION: see http://www.boost.org for most recent version. Chris@16: * FILE sub_match.cpp Chris@16: * VERSION see Chris@16: * DESCRIPTION: Declares template class sub_match. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_REGEX_V4_SUB_MATCH_HPP Chris@16: #define BOOST_REGEX_V4_SUB_MATCH_HPP Chris@16: Chris@16: #ifdef BOOST_MSVC Chris@16: #pragma warning(push) Chris@16: #pragma warning(disable: 4103) Chris@16: #endif Chris@16: #ifdef BOOST_HAS_ABI_HEADERS Chris@16: # include BOOST_ABI_PREFIX Chris@16: #endif Chris@16: #ifdef BOOST_MSVC Chris@16: #pragma warning(pop) Chris@16: #endif Chris@16: Chris@16: namespace boost{ Chris@16: Chris@16: template Chris@16: struct sub_match : public std::pair Chris@16: { Chris@16: typedef typename re_detail::regex_iterator_traits::value_type value_type; Chris@101: #if defined(BOOST_NO_STD_ITERATOR_TRAITS) Chris@16: typedef std::ptrdiff_t difference_type; Chris@16: #else Chris@16: typedef typename re_detail::regex_iterator_traits::difference_type difference_type; Chris@16: #endif Chris@16: typedef BidiIterator iterator_type; Chris@16: typedef BidiIterator iterator; Chris@16: typedef BidiIterator const_iterator; Chris@16: Chris@16: bool matched; Chris@16: Chris@16: sub_match() : std::pair(), matched(false) {} Chris@16: sub_match(BidiIterator i) : std::pair(i, i), matched(false) {} Chris@16: #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\ Chris@16: && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)\ Chris@16: && !BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) Chris@16: template Chris@16: operator std::basic_string ()const Chris@16: { Chris@16: return matched ? std::basic_string(this->first, this->second) : std::basic_string(); Chris@16: } Chris@16: #else Chris@16: operator std::basic_string ()const Chris@16: { Chris@16: return str(); Chris@16: } Chris@16: #endif Chris@16: difference_type BOOST_REGEX_CALL length()const Chris@16: { Chris@16: difference_type n = matched ? ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second) : 0; Chris@16: return n; Chris@16: } Chris@16: std::basic_string str()const Chris@16: { Chris@16: std::basic_string result; Chris@16: if(matched) Chris@16: { Chris@16: std::size_t len = ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second); Chris@16: result.reserve(len); Chris@16: BidiIterator i = this->first; Chris@16: while(i != this->second) Chris@16: { Chris@16: result.append(1, *i); Chris@16: ++i; Chris@16: } Chris@16: } Chris@16: return result; Chris@16: } Chris@16: int compare(const sub_match& s)const Chris@16: { Chris@16: if(matched != s.matched) Chris@16: return static_cast(matched) - static_cast(s.matched); Chris@16: return str().compare(s.str()); Chris@16: } Chris@16: int compare(const std::basic_string& s)const Chris@16: { Chris@16: return str().compare(s); Chris@16: } Chris@16: int compare(const value_type* p)const Chris@16: { Chris@16: return str().compare(p); Chris@16: } Chris@16: Chris@16: bool operator==(const sub_match& that)const Chris@16: { return compare(that) == 0; } Chris@16: bool BOOST_REGEX_CALL operator !=(const sub_match& that)const Chris@16: { return compare(that) != 0; } Chris@16: bool operator<(const sub_match& that)const Chris@16: { return compare(that) < 0; } Chris@16: bool operator>(const sub_match& that)const Chris@16: { return compare(that) > 0; } Chris@16: bool operator<=(const sub_match& that)const Chris@16: { return compare(that) <= 0; } Chris@16: bool operator>=(const sub_match& that)const Chris@16: { return compare(that) >= 0; } Chris@16: Chris@16: #ifdef BOOST_REGEX_MATCH_EXTRA Chris@16: typedef std::vector > capture_sequence_type; Chris@16: Chris@16: const capture_sequence_type& captures()const Chris@16: { Chris@16: if(!m_captures) Chris@16: m_captures.reset(new capture_sequence_type()); Chris@16: return *m_captures; Chris@16: } Chris@16: // Chris@16: // Private implementation API: DO NOT USE! Chris@16: // Chris@16: capture_sequence_type& get_captures()const Chris@16: { Chris@16: if(!m_captures) Chris@16: m_captures.reset(new capture_sequence_type()); Chris@16: return *m_captures; Chris@16: } Chris@16: Chris@16: private: Chris@16: mutable boost::scoped_ptr m_captures; Chris@16: public: Chris@16: Chris@16: #endif Chris@16: sub_match(const sub_match& that, bool Chris@16: #ifdef BOOST_REGEX_MATCH_EXTRA Chris@16: deep_copy Chris@16: #endif Chris@16: = true Chris@16: ) Chris@16: : std::pair(that), Chris@16: matched(that.matched) Chris@16: { Chris@16: #ifdef BOOST_REGEX_MATCH_EXTRA Chris@16: if(that.m_captures) Chris@16: if(deep_copy) Chris@16: m_captures.reset(new capture_sequence_type(*(that.m_captures))); Chris@16: #endif Chris@16: } Chris@16: sub_match& operator=(const sub_match& that) Chris@16: { Chris@16: this->first = that.first; Chris@16: this->second = that.second; Chris@16: matched = that.matched; Chris@16: #ifdef BOOST_REGEX_MATCH_EXTRA Chris@16: if(that.m_captures) Chris@16: get_captures() = *(that.m_captures); Chris@16: #endif Chris@16: return *this; Chris@16: } Chris@16: Chris@16: Chris@16: #ifdef BOOST_OLD_REGEX_H Chris@16: // Chris@16: // the following are deprecated, do not use!! Chris@16: // Chris@16: operator int()const; Chris@16: operator unsigned int()const; Chris@16: operator short()const Chris@16: { Chris@16: return (short)(int)(*this); Chris@16: } Chris@16: operator unsigned short()const Chris@16: { Chris@16: return (unsigned short)(unsigned int)(*this); Chris@16: } Chris@16: #endif Chris@16: }; Chris@16: Chris@16: typedef sub_match csub_match; Chris@16: typedef sub_match ssub_match; Chris@16: #ifndef BOOST_NO_WREGEX Chris@16: typedef sub_match wcsub_match; Chris@16: typedef sub_match wssub_match; Chris@16: #endif Chris@16: Chris@16: // comparison to std::basic_string<> part 1: Chris@16: template Chris@16: inline bool operator == (const std::basic_string::value_type, traits, Allocator>& s, Chris@16: const sub_match& m) Chris@16: { return s.compare(m.str()) == 0; } Chris@16: template Chris@16: inline bool operator != (const std::basic_string::value_type, traits, Allocator>& s, Chris@16: const sub_match& m) Chris@16: { return s.compare(m.str()) != 0; } Chris@16: template Chris@16: inline bool operator < (const std::basic_string::value_type, traits, Allocator>& s, Chris@16: const sub_match& m) Chris@16: { return s.compare(m.str()) < 0; } Chris@16: template Chris@16: inline bool operator <= (const std::basic_string::value_type, traits, Allocator>& s, Chris@16: const sub_match& m) Chris@16: { return s.compare(m.str()) <= 0; } Chris@16: template Chris@16: inline bool operator >= (const std::basic_string::value_type, traits, Allocator>& s, Chris@16: const sub_match& m) Chris@16: { return s.compare(m.str()) >= 0; } Chris@16: template Chris@16: inline bool operator > (const std::basic_string::value_type, traits, Allocator>& s, Chris@16: const sub_match& m) Chris@16: { return s.compare(m.str()) > 0; } Chris@16: // comparison to std::basic_string<> part 2: Chris@16: template Chris@16: inline bool operator == (const sub_match& m, Chris@16: const std::basic_string::value_type, traits, Allocator>& s) Chris@16: { return m.str().compare(s) == 0; } Chris@16: template Chris@16: inline bool operator != (const sub_match& m, Chris@16: const std::basic_string::value_type, traits, Allocator>& s) Chris@16: { return m.str().compare(s) != 0; } Chris@16: template Chris@16: inline bool operator < (const sub_match& m, Chris@16: const std::basic_string::value_type, traits, Allocator>& s) Chris@16: { return m.str().compare(s) < 0; } Chris@16: template Chris@16: inline bool operator > (const sub_match& m, Chris@16: const std::basic_string::value_type, traits, Allocator>& s) Chris@16: { return m.str().compare(s) > 0; } Chris@16: template Chris@16: inline bool operator <= (const sub_match& m, Chris@16: const std::basic_string::value_type, traits, Allocator>& s) Chris@16: { return m.str().compare(s) <= 0; } Chris@16: template Chris@16: inline bool operator >= (const sub_match& m, Chris@16: const std::basic_string::value_type, traits, Allocator>& s) Chris@16: { return m.str().compare(s) >= 0; } Chris@16: // comparison to const charT* part 1: Chris@16: template Chris@16: inline bool operator == (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const* s) Chris@16: { return m.str().compare(s) == 0; } Chris@16: template Chris@16: inline bool operator != (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const* s) Chris@16: { return m.str().compare(s) != 0; } Chris@16: template Chris@16: inline bool operator > (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const* s) Chris@16: { return m.str().compare(s) > 0; } Chris@16: template Chris@16: inline bool operator < (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const* s) Chris@16: { return m.str().compare(s) < 0; } Chris@16: template Chris@16: inline bool operator >= (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const* s) Chris@16: { return m.str().compare(s) >= 0; } Chris@16: template Chris@16: inline bool operator <= (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const* s) Chris@16: { return m.str().compare(s) <= 0; } Chris@16: // comparison to const charT* part 2: Chris@16: template Chris@16: inline bool operator == (typename re_detail::regex_iterator_traits::value_type const* s, Chris@16: const sub_match& m) Chris@16: { return m.str().compare(s) == 0; } Chris@16: template Chris@16: inline bool operator != (typename re_detail::regex_iterator_traits::value_type const* s, Chris@16: const sub_match& m) Chris@16: { return m.str().compare(s) != 0; } Chris@16: template Chris@16: inline bool operator < (typename re_detail::regex_iterator_traits::value_type const* s, Chris@16: const sub_match& m) Chris@16: { return m.str().compare(s) > 0; } Chris@16: template Chris@16: inline bool operator > (typename re_detail::regex_iterator_traits::value_type const* s, Chris@16: const sub_match& m) Chris@16: { return m.str().compare(s) < 0; } Chris@16: template Chris@16: inline bool operator <= (typename re_detail::regex_iterator_traits::value_type const* s, Chris@16: const sub_match& m) Chris@16: { return m.str().compare(s) >= 0; } Chris@16: template Chris@16: inline bool operator >= (typename re_detail::regex_iterator_traits::value_type const* s, Chris@16: const sub_match& m) Chris@16: { return m.str().compare(s) <= 0; } Chris@16: Chris@16: // comparison to const charT& part 1: Chris@16: template Chris@16: inline bool operator == (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const& s) Chris@16: { return m.str().compare(0, m.length(), &s, 1) == 0; } Chris@16: template Chris@16: inline bool operator != (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const& s) Chris@16: { return m.str().compare(0, m.length(), &s, 1) != 0; } Chris@16: template Chris@16: inline bool operator > (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const& s) Chris@16: { return m.str().compare(0, m.length(), &s, 1) > 0; } Chris@16: template Chris@16: inline bool operator < (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const& s) Chris@16: { return m.str().compare(0, m.length(), &s, 1) < 0; } Chris@16: template Chris@16: inline bool operator >= (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const& s) Chris@16: { return m.str().compare(0, m.length(), &s, 1) >= 0; } Chris@16: template Chris@16: inline bool operator <= (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const& s) Chris@16: { return m.str().compare(0, m.length(), &s, 1) <= 0; } Chris@16: // comparison to const charT* part 2: Chris@16: template Chris@16: inline bool operator == (typename re_detail::regex_iterator_traits::value_type const& s, Chris@16: const sub_match& m) Chris@16: { return m.str().compare(0, m.length(), &s, 1) == 0; } Chris@16: template Chris@16: inline bool operator != (typename re_detail::regex_iterator_traits::value_type const& s, Chris@16: const sub_match& m) Chris@16: { return m.str().compare(0, m.length(), &s, 1) != 0; } Chris@16: template Chris@16: inline bool operator < (typename re_detail::regex_iterator_traits::value_type const& s, Chris@16: const sub_match& m) Chris@16: { return m.str().compare(0, m.length(), &s, 1) > 0; } Chris@16: template Chris@16: inline bool operator > (typename re_detail::regex_iterator_traits::value_type const& s, Chris@16: const sub_match& m) Chris@16: { return m.str().compare(0, m.length(), &s, 1) < 0; } Chris@16: template Chris@16: inline bool operator <= (typename re_detail::regex_iterator_traits::value_type const& s, Chris@16: const sub_match& m) Chris@16: { return m.str().compare(0, m.length(), &s, 1) >= 0; } Chris@16: template Chris@16: inline bool operator >= (typename re_detail::regex_iterator_traits::value_type const& s, Chris@16: const sub_match& m) Chris@16: { return m.str().compare(0, m.length(), &s, 1) <= 0; } Chris@16: Chris@16: // addition operators: Chris@16: template Chris@16: inline std::basic_string::value_type, traits, Allocator> Chris@16: operator + (const std::basic_string::value_type, traits, Allocator>& s, Chris@16: const sub_match& m) Chris@16: { Chris@16: std::basic_string::value_type, traits, Allocator> result; Chris@16: result.reserve(s.size() + m.length() + 1); Chris@16: return result.append(s).append(m.first, m.second); Chris@16: } Chris@16: template Chris@16: inline std::basic_string::value_type, traits, Allocator> Chris@16: operator + (const sub_match& m, Chris@16: const std::basic_string::value_type, traits, Allocator>& s) Chris@16: { Chris@16: std::basic_string::value_type, traits, Allocator> result; Chris@16: result.reserve(s.size() + m.length() + 1); Chris@16: return result.append(m.first, m.second).append(s); Chris@16: } Chris@16: #if !(defined(__GNUC__) && defined(BOOST_NO_STD_LOCALE)) Chris@16: template Chris@16: inline std::basic_string::value_type> Chris@16: operator + (typename re_detail::regex_iterator_traits::value_type const* s, Chris@16: const sub_match& m) Chris@16: { Chris@16: std::basic_string::value_type> result; Chris@16: result.reserve(std::char_traits::value_type>::length(s) + m.length() + 1); Chris@16: return result.append(s).append(m.first, m.second); Chris@16: } Chris@16: template Chris@16: inline std::basic_string::value_type> Chris@16: operator + (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const * s) Chris@16: { Chris@16: std::basic_string::value_type> result; Chris@16: result.reserve(std::char_traits::value_type>::length(s) + m.length() + 1); Chris@16: return result.append(m.first, m.second).append(s); Chris@16: } Chris@16: #else Chris@16: // worwaround versions: Chris@16: template Chris@16: inline std::basic_string::value_type> Chris@16: operator + (typename re_detail::regex_iterator_traits::value_type const* s, Chris@16: const sub_match& m) Chris@16: { Chris@16: return s + m.str(); Chris@16: } Chris@16: template Chris@16: inline std::basic_string::value_type> Chris@16: operator + (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const * s) Chris@16: { Chris@16: return m.str() + s; Chris@16: } Chris@16: #endif Chris@16: template Chris@16: inline std::basic_string::value_type> Chris@16: operator + (typename re_detail::regex_iterator_traits::value_type const& s, Chris@16: const sub_match& m) Chris@16: { Chris@16: std::basic_string::value_type> result; Chris@16: result.reserve(m.length() + 2); Chris@16: return result.append(1, s).append(m.first, m.second); Chris@16: } Chris@16: template Chris@16: inline std::basic_string::value_type> Chris@16: operator + (const sub_match& m, Chris@16: typename re_detail::regex_iterator_traits::value_type const& s) Chris@16: { Chris@16: std::basic_string::value_type> result; Chris@16: result.reserve(m.length() + 2); Chris@16: return result.append(m.first, m.second).append(1, s); Chris@16: } Chris@16: template Chris@16: inline std::basic_string::value_type> Chris@16: operator + (const sub_match& m1, Chris@16: const sub_match& m2) Chris@16: { Chris@16: std::basic_string::value_type> result; Chris@16: result.reserve(m1.length() + m2.length() + 1); Chris@16: return result.append(m1.first, m1.second).append(m2.first, m2.second); Chris@16: } Chris@16: #ifndef BOOST_NO_STD_LOCALE Chris@16: template Chris@16: std::basic_ostream& Chris@16: operator << (std::basic_ostream& os, Chris@16: const sub_match& s) Chris@16: { Chris@16: return (os << s.str()); Chris@16: } Chris@16: #else Chris@16: template Chris@16: std::ostream& operator << (std::ostream& os, Chris@16: const sub_match& s) Chris@16: { Chris@16: return (os << s.str()); Chris@16: } Chris@16: #endif Chris@16: Chris@16: #ifdef BOOST_OLD_REGEX_H Chris@16: namespace re_detail{ Chris@16: template Chris@16: int do_toi(BidiIterator i, BidiIterator j, char c, int radix) Chris@16: { Chris@16: std::string s(i, j); Chris@16: char* p; Chris@16: int result = std::strtol(s.c_str(), &p, radix); Chris@16: if(*p)raise_regex_exception("Bad sub-expression"); Chris@16: return result; Chris@16: } Chris@16: Chris@16: // Chris@16: // helper: Chris@16: template Chris@16: int do_toi(I& i, I j, charT c) Chris@16: { Chris@16: int result = 0; Chris@16: while((i != j) && (isdigit(*i))) Chris@16: { Chris@16: result = result*10 + (*i - '0'); Chris@16: ++i; Chris@16: } Chris@16: return result; Chris@16: } Chris@16: } Chris@16: Chris@16: Chris@16: template Chris@16: sub_match::operator int()const Chris@16: { Chris@16: BidiIterator i = first; Chris@16: BidiIterator j = second; Chris@16: if(i == j)raise_regex_exception("Bad sub-expression"); Chris@16: int neg = 1; Chris@16: if((i != j) && (*i == '-')) Chris@16: { Chris@16: neg = -1; Chris@16: ++i; Chris@16: } Chris@16: neg *= re_detail::do_toi(i, j, *i); Chris@16: if(i != j)raise_regex_exception("Bad sub-expression"); Chris@16: return neg; Chris@16: } Chris@16: template Chris@16: sub_match::operator unsigned int()const Chris@16: { Chris@16: BidiIterator i = first; Chris@16: BidiIterator j = second; Chris@16: if(i == j) Chris@16: raise_regex_exception("Bad sub-expression"); Chris@16: return re_detail::do_toi(i, j, *first); Chris@16: } Chris@16: #endif Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #ifdef BOOST_MSVC Chris@16: #pragma warning(push) Chris@16: #pragma warning(disable: 4103) Chris@16: #endif Chris@16: #ifdef BOOST_HAS_ABI_HEADERS Chris@16: # include BOOST_ABI_SUFFIX Chris@16: #endif Chris@16: #ifdef BOOST_MSVC Chris@16: #pragma warning(pop) Chris@16: #endif Chris@16: Chris@16: #endif Chris@16: