Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: /// \file sub_match.hpp Chris@16: /// Contains the definition of the class template sub_match\<\> Chris@16: /// and associated helper functions Chris@16: // Chris@16: // Copyright 2008 Eric Niebler. Distributed under the Boost Chris@16: // 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: #ifndef BOOST_XPRESSIVE_SUB_MATCH_HPP_EAN_10_04_2005 Chris@16: #define BOOST_XPRESSIVE_SUB_MATCH_HPP_EAN_10_04_2005 Chris@16: Chris@16: // MS compatible compilers support #pragma once Chris@101: #if defined(_MSC_VER) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@101: #include Chris@16: #include Chris@16: Chris@16: //{{AFX_DOC_COMMENT Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // This is a hack to get Doxygen to show the inheritance relation between Chris@16: // sub_match and std::pair. Chris@16: #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED Chris@16: /// INTERNAL ONLY Chris@16: namespace std Chris@16: { Chris@16: /// INTERNAL ONLY Chris@16: template struct pair {}; Chris@16: } Chris@16: #endif Chris@16: //}}AFX_DOC_COMMENT Chris@16: Chris@16: namespace boost { namespace xpressive Chris@16: { Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // sub_match Chris@16: // Chris@16: /// \brief Class template \c sub_match denotes the sequence of characters matched by a particular Chris@16: /// marked sub-expression. Chris@16: /// Chris@16: /// When the marked sub-expression denoted by an object of type \c sub_match\<\> participated in a Chris@16: /// regular expression match then member \c matched evaluates to \c true, and members \c first and \c second Chris@16: /// denote the range of characters [first,second) which formed that match. Otherwise \c matched is \c false, Chris@16: /// and members \c first and \c second contained undefined values. Chris@16: /// Chris@16: /// If an object of type \c sub_match\<\> represents sub-expression 0 - that is to say the whole match - Chris@16: /// then member \c matched is always \c true, unless a partial match was obtained as a result of the flag Chris@16: /// \c match_partial being passed to a regular expression algorithm, in which case member \c matched is Chris@16: /// \c false, and members \c first and \c second represent the character range that formed the partial match. Chris@16: template Chris@16: struct sub_match Chris@16: : std::pair Chris@16: { Chris@16: private: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: struct dummy { int i_; }; Chris@16: typedef int dummy::*bool_type; Chris@16: Chris@16: public: Chris@16: typedef typename iterator_value::type value_type; Chris@16: typedef typename iterator_difference::type difference_type; Chris@16: typedef typename detail::string_type::type string_type; Chris@16: typedef BidiIter iterator; Chris@16: Chris@16: sub_match() Chris@16: : std::pair() Chris@16: , matched(false) Chris@16: { Chris@16: } Chris@16: Chris@16: sub_match(BidiIter first, BidiIter second, bool matched_ = false) Chris@16: : std::pair(first, second) Chris@16: , matched(matched_) Chris@16: { Chris@16: } Chris@16: Chris@16: string_type str() const Chris@16: { Chris@16: return this->matched ? string_type(this->first, this->second) : string_type(); Chris@16: } Chris@16: Chris@16: operator string_type() const Chris@16: { Chris@16: return this->matched ? string_type(this->first, this->second) : string_type(); Chris@16: } Chris@16: Chris@16: difference_type length() const Chris@16: { Chris@16: return this->matched ? std::distance(this->first, this->second) : 0; Chris@16: } Chris@16: Chris@16: operator bool_type() const Chris@16: { Chris@16: return this->matched ? &dummy::i_ : 0; Chris@16: } Chris@16: Chris@16: bool operator !() const Chris@16: { Chris@16: return !this->matched; Chris@16: } Chris@16: Chris@16: /// \brief Performs a lexicographic string comparison Chris@16: /// \param str the string against which to compare Chris@16: /// \return the results of (*this).str().compare(str) Chris@16: int compare(string_type const &str) const Chris@16: { Chris@16: return this->str().compare(str); Chris@16: } Chris@16: Chris@16: /// \overload Chris@16: /// Chris@16: int compare(sub_match const &sub) const Chris@16: { Chris@16: return this->str().compare(sub.str()); Chris@16: } Chris@16: Chris@16: /// \overload Chris@16: /// Chris@16: int compare(value_type const *ptr) const Chris@16: { Chris@16: return this->str().compare(ptr); Chris@16: } Chris@16: Chris@16: /// \brief true if this sub-match participated in the full match. Chris@16: bool matched; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: /// \brief \c range_begin() to make \c sub_match\<\> a valid range Chris@16: /// \param sub the \c sub_match\<\> object denoting the range Chris@16: /// \return \c sub.first Chris@16: /// \pre \c sub.first is not singular Chris@16: template Chris@16: inline BidiIter range_begin(sub_match &sub) Chris@16: { Chris@16: return sub.first; Chris@16: } Chris@16: Chris@16: /// \overload Chris@16: /// Chris@16: template Chris@16: inline BidiIter range_begin(sub_match const &sub) Chris@16: { Chris@16: return sub.first; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: /// \brief \c range_end() to make \c sub_match\<\> a valid range Chris@16: /// \param sub the \c sub_match\<\> object denoting the range Chris@16: /// \return \c sub.second Chris@16: /// \pre \c sub.second is not singular Chris@16: template Chris@16: inline BidiIter range_end(sub_match &sub) Chris@16: { Chris@16: return sub.second; Chris@16: } Chris@16: Chris@16: /// \overload Chris@16: /// Chris@16: template Chris@16: inline BidiIter range_end(sub_match const &sub) Chris@16: { Chris@16: return sub.second; Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: /// \brief insertion operator for sending sub-matches to ostreams Chris@16: /// \param sout output stream. Chris@16: /// \param sub sub_match object to be written to the stream. Chris@16: /// \return sout \<\< sub.str() Chris@16: template Chris@16: inline std::basic_ostream &operator << Chris@16: ( Chris@16: std::basic_ostream &sout Chris@16: , sub_match const &sub Chris@16: ) Chris@16: { Chris@16: typedef typename iterator_value::type char_type; Chris@16: BOOST_MPL_ASSERT_MSG( Chris@16: (boost::is_same::value) Chris@16: , CHARACTER_TYPES_OF_STREAM_AND_SUB_MATCH_MUST_MATCH Chris@16: , (Char, char_type) Chris@16: ); Chris@16: if(sub.matched) Chris@16: { Chris@16: std::ostream_iterator iout(sout); Chris@16: std::copy(sub.first, sub.second, iout); Chris@16: } Chris@16: return sout; Chris@16: } Chris@16: Chris@16: Chris@16: // BUGBUG make these more efficient Chris@16: Chris@16: template Chris@16: bool operator == (sub_match const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs.compare(rhs) == 0; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator != (sub_match const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs.compare(rhs) != 0; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator < (sub_match const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs.compare(rhs) < 0; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator <= (sub_match const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs.compare(rhs) <= 0; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator >= (sub_match const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs.compare(rhs) >= 0; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator > (sub_match const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs.compare(rhs) > 0; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator == (typename iterator_value::type const *lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs == rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator != (typename iterator_value::type const *lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs != rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator < (typename iterator_value::type const *lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs < rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator > (typename iterator_value::type const *lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs> rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator >= (typename iterator_value::type const *lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs >= rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator <= (typename iterator_value::type const *lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs <= rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator == (sub_match const &lhs, typename iterator_value::type const *rhs) Chris@16: { Chris@16: return lhs.str() == rhs; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator != (sub_match const &lhs, typename iterator_value::type const *rhs) Chris@16: { Chris@16: return lhs.str() != rhs; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator < (sub_match const &lhs, typename iterator_value::type const *rhs) Chris@16: { Chris@16: return lhs.str() < rhs; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator > (sub_match const &lhs, typename iterator_value::type const *rhs) Chris@16: { Chris@16: return lhs.str() > rhs; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator >= (sub_match const &lhs, typename iterator_value::type const *rhs) Chris@16: { Chris@16: return lhs.str() >= rhs; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator <= (sub_match const &lhs, typename iterator_value::type const *rhs) Chris@16: { Chris@16: return lhs.str() <= rhs; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator == (typename iterator_value::type const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs == rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator != (typename iterator_value::type const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs != rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator < (typename iterator_value::type const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs < rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator > (typename iterator_value::type const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs> rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator >= (typename iterator_value::type const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs >= rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator <= (typename iterator_value::type const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs <= rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator == (sub_match const &lhs, typename iterator_value::type const &rhs) Chris@16: { Chris@16: return lhs.str() == rhs; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator != (sub_match const &lhs, typename iterator_value::type const &rhs) Chris@16: { Chris@16: return lhs.str() != rhs; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator < (sub_match const &lhs, typename iterator_value::type const &rhs) Chris@16: { Chris@16: return lhs.str() < rhs; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator > (sub_match const &lhs, typename iterator_value::type const &rhs) Chris@16: { Chris@16: return lhs.str() > rhs; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator >= (sub_match const &lhs, typename iterator_value::type const &rhs) Chris@16: { Chris@16: return lhs.str() >= rhs; Chris@16: } Chris@16: Chris@16: template Chris@16: bool operator <= (sub_match const &lhs, typename iterator_value::type const &rhs) Chris@16: { Chris@16: return lhs.str() <= rhs; Chris@16: } Chris@16: Chris@16: // Operator+ convenience function Chris@16: template Chris@16: typename sub_match::string_type Chris@16: operator + (sub_match const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs.str() + rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: typename sub_match::string_type Chris@16: operator + (sub_match const &lhs, typename iterator_value::type const &rhs) Chris@16: { Chris@16: return lhs.str() + rhs; Chris@16: } Chris@16: Chris@16: template Chris@16: typename sub_match::string_type Chris@16: operator + (typename iterator_value::type const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs + rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: typename sub_match::string_type Chris@16: operator + (sub_match const &lhs, typename iterator_value::type const *rhs) Chris@16: { Chris@16: return lhs.str() + rhs; Chris@16: } Chris@16: Chris@16: template Chris@16: typename sub_match::string_type Chris@16: operator + (typename iterator_value::type const *lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs + rhs.str(); Chris@16: } Chris@16: Chris@16: template Chris@16: typename sub_match::string_type Chris@16: operator + (sub_match const &lhs, typename sub_match::string_type const &rhs) Chris@16: { Chris@16: return lhs.str() + rhs; Chris@16: } Chris@16: Chris@16: template Chris@16: typename sub_match::string_type Chris@16: operator + (typename sub_match::string_type const &lhs, sub_match const &rhs) Chris@16: { Chris@16: return lhs + rhs.str(); Chris@16: } Chris@16: Chris@16: }} // namespace boost::xpressive Chris@16: Chris@16: // Hook the Boost.Range customization points to make sub_match a valid range. Chris@16: namespace boost Chris@16: { Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: template Chris@16: struct range_mutable_iterator > Chris@16: { Chris@16: typedef BidiIter type; Chris@16: }; Chris@16: Chris@16: /// INTERNAL ONLY Chris@16: /// Chris@16: template Chris@16: struct range_const_iterator > Chris@16: { Chris@16: typedef BidiIter type; Chris@16: }; Chris@16: } Chris@16: Chris@16: #endif