Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:02:37

0001 ///////////////////////////////////////////////////////////////////////////////
0002 /// \file sub_match.hpp
0003 /// Contains the definition of the class template sub_match\<\>
0004 /// and associated helper functions
0005 //
0006 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0007 //  Software License, Version 1.0. (See accompanying file
0008 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 
0010 #ifndef BOOST_XPRESSIVE_SUB_MATCH_HPP_EAN_10_04_2005
0011 #define BOOST_XPRESSIVE_SUB_MATCH_HPP_EAN_10_04_2005
0012 
0013 // MS compatible compilers support #pragma once
0014 #if defined(_MSC_VER)
0015 # pragma once
0016 #endif
0017 
0018 #include <iosfwd>
0019 #include <string>
0020 #include <utility>
0021 #include <iterator>
0022 #include <algorithm>
0023 #include <boost/mpl/assert.hpp>
0024 #include <boost/type_traits/is_same.hpp>
0025 #include <boost/iterator/iterator_traits.hpp>
0026 #include <boost/range/const_iterator.hpp>
0027 #include <boost/range/mutable_iterator.hpp>
0028 #include <boost/xpressive/detail/detail_fwd.hpp>
0029 
0030 //{{AFX_DOC_COMMENT
0031 ///////////////////////////////////////////////////////////////////////////////
0032 // This is a hack to get Doxygen to show the inheritance relation between
0033 // sub_match<T> and std::pair<T,T>.
0034 #ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED
0035 /// INTERNAL ONLY
0036 namespace std
0037 {
0038     /// INTERNAL ONLY
0039     template<typename, typename> struct pair {};
0040 }
0041 #endif
0042 //}}AFX_DOC_COMMENT
0043 
0044 namespace boost { namespace xpressive
0045 {
0046 
0047 ///////////////////////////////////////////////////////////////////////////////
0048 // sub_match
0049 //
0050 /// \brief Class template \c sub_match denotes the sequence of characters matched by a particular
0051 /// marked sub-expression.
0052 ///
0053 /// When the marked sub-expression denoted by an object of type \c sub_match\<\> participated in a
0054 /// regular expression match then member \c matched evaluates to \c true, and members \c first and \c second
0055 /// denote the range of characters <tt>[first,second)</tt> which formed that match. Otherwise \c matched is \c false,
0056 /// and members \c first and \c second contained undefined values.
0057 ///
0058 /// If an object of type \c sub_match\<\> represents sub-expression 0 - that is to say the whole match -
0059 /// then member \c matched is always \c true, unless a partial match was obtained as a result of the flag
0060 /// \c match_partial being passed to a regular expression algorithm, in which case member \c matched is
0061 /// \c false, and members \c first and \c second represent the character range that formed the partial match.
0062 template<typename BidiIter>
0063 struct sub_match
0064   : std::pair<BidiIter, BidiIter>
0065 {
0066 private:
0067     /// INTERNAL ONLY
0068     ///
0069     struct dummy { int i_; };
0070     typedef int dummy::*bool_type;
0071 
0072 public:
0073     typedef typename iterator_value<BidiIter>::type value_type;
0074     typedef typename iterator_difference<BidiIter>::type difference_type;
0075     typedef typename detail::string_type<value_type>::type string_type;
0076     typedef BidiIter iterator;
0077 
0078     sub_match()
0079       : std::pair<BidiIter, BidiIter>()
0080       , matched(false)
0081     {
0082     }
0083 
0084     sub_match(BidiIter first, BidiIter second, bool matched_ = false)
0085       : std::pair<BidiIter, BidiIter>(first, second)
0086       , matched(matched_)
0087     {
0088     }
0089 
0090     string_type str() const
0091     {
0092         return this->matched ? string_type(this->first, this->second) : string_type();
0093     }
0094 
0095     operator string_type() const
0096     {
0097         return this->matched ? string_type(this->first, this->second) : string_type();
0098     }
0099 
0100     difference_type length() const
0101     {
0102         return this->matched ? std::distance(this->first, this->second) : 0;
0103     }
0104 
0105     operator bool_type() const
0106     {
0107         return this->matched ? &dummy::i_ : 0;
0108     }
0109 
0110     bool operator !() const
0111     {
0112         return !this->matched;
0113     }
0114 
0115     /// \brief Performs a lexicographic string comparison
0116     /// \param str the string against which to compare
0117     /// \return the results of <tt>(*this).str().compare(str)</tt>
0118     int compare(string_type const &str) const
0119     {
0120         return this->str().compare(str);
0121     }
0122 
0123     /// \overload
0124     ///
0125     int compare(sub_match const &sub) const
0126     {
0127         return this->str().compare(sub.str());
0128     }
0129 
0130     /// \overload
0131     ///
0132     int compare(value_type const *ptr) const
0133     {
0134         return this->str().compare(ptr);
0135     }
0136 
0137     /// \brief true if this sub-match participated in the full match.
0138     bool matched;
0139 };
0140 
0141 ///////////////////////////////////////////////////////////////////////////////
0142 /// \brief \c range_begin() to make \c sub_match\<\> a valid range
0143 /// \param sub the \c sub_match\<\> object denoting the range
0144 /// \return \c sub.first
0145 /// \pre \c sub.first is not singular
0146 template<typename BidiIter>
0147 inline BidiIter range_begin(sub_match<BidiIter> &sub)
0148 {
0149     return sub.first;
0150 }
0151 
0152 /// \overload
0153 ///
0154 template<typename BidiIter>
0155 inline BidiIter range_begin(sub_match<BidiIter> const &sub)
0156 {
0157     return sub.first;
0158 }
0159 
0160 ///////////////////////////////////////////////////////////////////////////////
0161 /// \brief \c range_end() to make \c sub_match\<\> a valid range
0162 /// \param sub the \c sub_match\<\> object denoting the range
0163 /// \return \c sub.second
0164 /// \pre \c sub.second is not singular
0165 template<typename BidiIter>
0166 inline BidiIter range_end(sub_match<BidiIter> &sub)
0167 {
0168     return sub.second;
0169 }
0170 
0171 /// \overload
0172 ///
0173 template<typename BidiIter>
0174 inline BidiIter range_end(sub_match<BidiIter> const &sub)
0175 {
0176     return sub.second;
0177 }
0178 
0179 ///////////////////////////////////////////////////////////////////////////////
0180 /// \brief insertion operator for sending sub-matches to ostreams
0181 /// \param sout output stream.
0182 /// \param sub sub_match object to be written to the stream.
0183 /// \return sout \<\< sub.str()
0184 template<typename BidiIter, typename Char, typename Traits>
0185 inline std::basic_ostream<Char, Traits> &operator <<
0186 (
0187     std::basic_ostream<Char, Traits> &sout
0188   , sub_match<BidiIter> const &sub
0189 )
0190 {
0191     typedef typename iterator_value<BidiIter>::type char_type;
0192     BOOST_MPL_ASSERT_MSG(
0193         (boost::is_same<Char, char_type>::value)
0194       , CHARACTER_TYPES_OF_STREAM_AND_SUB_MATCH_MUST_MATCH
0195       , (Char, char_type)
0196     );
0197     if(sub.matched)
0198     {
0199         std::ostream_iterator<char_type, Char, Traits> iout(sout);
0200         std::copy(sub.first, sub.second, iout);
0201     }
0202     return sout;
0203 }
0204 
0205 
0206 // BUGBUG make these more efficient
0207 
0208 template<typename BidiIter>
0209 bool operator == (sub_match<BidiIter> const &lhs, sub_match<BidiIter> const &rhs)
0210 {
0211     return lhs.compare(rhs) == 0;
0212 }
0213 
0214 template<typename BidiIter>
0215 bool operator != (sub_match<BidiIter> const &lhs, sub_match<BidiIter> const &rhs)
0216 {
0217     return lhs.compare(rhs) != 0;
0218 }
0219 
0220 template<typename BidiIter>
0221 bool operator < (sub_match<BidiIter> const &lhs, sub_match<BidiIter> const &rhs)
0222 {
0223     return lhs.compare(rhs) < 0;
0224 }
0225 
0226 template<typename BidiIter>
0227 bool operator <= (sub_match<BidiIter> const &lhs, sub_match<BidiIter> const &rhs)
0228 {
0229     return lhs.compare(rhs) <= 0;
0230 }
0231 
0232 template<typename BidiIter>
0233 bool operator >= (sub_match<BidiIter> const &lhs, sub_match<BidiIter> const &rhs)
0234 {
0235     return lhs.compare(rhs) >= 0;
0236 }
0237 
0238 template<typename BidiIter>
0239 bool operator > (sub_match<BidiIter> const &lhs, sub_match<BidiIter> const &rhs)
0240 {
0241     return lhs.compare(rhs) > 0;
0242 }
0243 
0244 template<typename BidiIter>
0245 bool operator == (typename iterator_value<BidiIter>::type const *lhs, sub_match<BidiIter> const &rhs)
0246 {
0247     return lhs == rhs.str();
0248 }
0249 
0250 template<typename BidiIter>
0251 bool operator != (typename iterator_value<BidiIter>::type const *lhs, sub_match<BidiIter> const &rhs)
0252 {
0253     return lhs != rhs.str();
0254 }
0255 
0256 template<typename BidiIter>
0257 bool operator < (typename iterator_value<BidiIter>::type const *lhs, sub_match<BidiIter> const &rhs)
0258 {
0259     return lhs < rhs.str();
0260 }
0261 
0262 template<typename BidiIter>
0263 bool operator > (typename iterator_value<BidiIter>::type const *lhs, sub_match<BidiIter> const &rhs)
0264 {
0265     return lhs> rhs.str();
0266 }
0267 
0268 template<typename BidiIter>
0269 bool operator >= (typename iterator_value<BidiIter>::type const *lhs, sub_match<BidiIter> const &rhs)
0270 {
0271     return lhs >= rhs.str();
0272 }
0273 
0274 template<typename BidiIter>
0275 bool operator <= (typename iterator_value<BidiIter>::type const *lhs, sub_match<BidiIter> const &rhs)
0276 {
0277     return lhs <= rhs.str();
0278 }
0279 
0280 template<typename BidiIter>
0281 bool operator == (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const *rhs)
0282 {
0283     return lhs.str() == rhs;
0284 }
0285 
0286 template<typename BidiIter>
0287 bool operator != (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const *rhs)
0288 {
0289     return lhs.str() != rhs;
0290 }
0291 
0292 template<typename BidiIter>
0293 bool operator < (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const *rhs)
0294 {
0295     return lhs.str() < rhs;
0296 }
0297 
0298 template<typename BidiIter>
0299 bool operator > (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const *rhs)
0300 {
0301     return lhs.str() > rhs;
0302 }
0303 
0304 template<typename BidiIter>
0305 bool operator >= (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const *rhs)
0306 {
0307     return lhs.str() >= rhs;
0308 }
0309 
0310 template<typename BidiIter>
0311 bool operator <= (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const *rhs)
0312 {
0313     return lhs.str() <= rhs;
0314 }
0315 
0316 template<typename BidiIter>
0317 bool operator == (typename iterator_value<BidiIter>::type const &lhs, sub_match<BidiIter> const &rhs)
0318 {
0319     return lhs == rhs.str();
0320 }
0321 
0322 template<typename BidiIter>
0323 bool operator != (typename iterator_value<BidiIter>::type const &lhs, sub_match<BidiIter> const &rhs)
0324 {
0325     return lhs != rhs.str();
0326 }
0327 
0328 template<typename BidiIter>
0329 bool operator < (typename iterator_value<BidiIter>::type const &lhs, sub_match<BidiIter> const &rhs)
0330 {
0331     return lhs < rhs.str();
0332 }
0333 
0334 template<typename BidiIter>
0335 bool operator > (typename iterator_value<BidiIter>::type const &lhs, sub_match<BidiIter> const &rhs)
0336 {
0337     return lhs> rhs.str();
0338 }
0339 
0340 template<typename BidiIter>
0341 bool operator >= (typename iterator_value<BidiIter>::type const &lhs, sub_match<BidiIter> const &rhs)
0342 {
0343     return lhs >= rhs.str();
0344 }
0345 
0346 template<typename BidiIter>
0347 bool operator <= (typename iterator_value<BidiIter>::type const &lhs, sub_match<BidiIter> const &rhs)
0348 {
0349     return lhs <= rhs.str();
0350 }
0351 
0352 template<typename BidiIter>
0353 bool operator == (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const &rhs)
0354 {
0355     return lhs.str() == rhs;
0356 }
0357 
0358 template<typename BidiIter>
0359 bool operator != (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const &rhs)
0360 {
0361     return lhs.str() != rhs;
0362 }
0363 
0364 template<typename BidiIter>
0365 bool operator < (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const &rhs)
0366 {
0367     return lhs.str() < rhs;
0368 }
0369 
0370 template<typename BidiIter>
0371 bool operator > (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const &rhs)
0372 {
0373     return lhs.str() > rhs;
0374 }
0375 
0376 template<typename BidiIter>
0377 bool operator >= (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const &rhs)
0378 {
0379     return lhs.str() >= rhs;
0380 }
0381 
0382 template<typename BidiIter>
0383 bool operator <= (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const &rhs)
0384 {
0385     return lhs.str() <= rhs;
0386 }
0387 
0388 // Operator+ convenience function
0389 template<typename BidiIter>
0390 typename sub_match<BidiIter>::string_type
0391 operator + (sub_match<BidiIter> const &lhs, sub_match<BidiIter> const &rhs)
0392 {
0393     return lhs.str() + rhs.str();
0394 }
0395 
0396 template<typename BidiIter>
0397 typename sub_match<BidiIter>::string_type
0398 operator + (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const &rhs)
0399 {
0400     return lhs.str() + rhs;
0401 }
0402 
0403 template<typename BidiIter>
0404 typename sub_match<BidiIter>::string_type
0405 operator + (typename iterator_value<BidiIter>::type const &lhs, sub_match<BidiIter> const &rhs)
0406 {
0407     return lhs + rhs.str();
0408 }
0409 
0410 template<typename BidiIter>
0411 typename sub_match<BidiIter>::string_type
0412 operator + (sub_match<BidiIter> const &lhs, typename iterator_value<BidiIter>::type const *rhs)
0413 {
0414     return lhs.str() + rhs;
0415 }
0416 
0417 template<typename BidiIter>
0418 typename sub_match<BidiIter>::string_type
0419 operator + (typename iterator_value<BidiIter>::type const *lhs, sub_match<BidiIter> const &rhs)
0420 {
0421     return lhs + rhs.str();
0422 }
0423 
0424 template<typename BidiIter>
0425 typename sub_match<BidiIter>::string_type
0426 operator + (sub_match<BidiIter> const &lhs, typename sub_match<BidiIter>::string_type const &rhs)
0427 {
0428     return lhs.str() + rhs;
0429 }
0430 
0431 template<typename BidiIter>
0432 typename sub_match<BidiIter>::string_type
0433 operator + (typename sub_match<BidiIter>::string_type const &lhs, sub_match<BidiIter> const &rhs)
0434 {
0435     return lhs + rhs.str();
0436 }
0437 
0438 }} // namespace boost::xpressive
0439 
0440 // Hook the Boost.Range customization points to make sub_match a valid range.
0441 namespace boost
0442 {
0443     /// INTERNAL ONLY
0444     ///
0445     template<typename BidiIter>
0446     struct range_mutable_iterator<xpressive::sub_match<BidiIter> >
0447     {
0448         typedef BidiIter type;
0449     };
0450 
0451     /// INTERNAL ONLY
0452     ///
0453     template<typename BidiIter>
0454     struct range_const_iterator<xpressive::sub_match<BidiIter> >
0455     {
0456         typedef BidiIter type;
0457     };
0458 }
0459 
0460 #endif