CppCMS
booster/regex_match.h
00001 //
00002 //  Copyright (C) 2009-2012 Artyom Beilis (Tonkikh)
00003 //
00004 //  Distributed under the Boost Software License, Version 1.0. (See
00005 //  accompanying file LICENSE_1_0.txt or copy at
00006 //  http://www.boost.org/LICENSE_1_0.txt)
00007 //
00008 #ifndef BOOSTER_REGEX_MATCH_H
00009 #define BOOSTER_REGEX_MATCH_H
00010 
00011 #include <algorithm>
00012 #include <iterator>
00013 #include <string>
00014 #include <vector>
00015 #include <string.h>
00016 
00017 namespace booster {
00018 
00024         template<typename Iterator>
00025         class sub_match : public std::pair<Iterator,Iterator> {
00026         public:
00027                 typedef Iterator iterator;
00028                 typedef typename std::iterator_traits<Iterator>::value_type value_type;
00029                 typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
00030 
00034                 typedef std::basic_string<value_type> string_type;
00035                 typedef std::pair<Iterator,Iterator> pair_type;
00036 
00041                 bool matched;
00042 
00046                 difference_type length() const
00047                 {
00048                         if(matched)
00049                                 return std::distance(pair_type::first,pair_type::second);
00050                         return 0;
00051                 }
00052 
00056                 operator string_type() const
00057                 {
00058                         return str();
00059                 }
00060 
00064                 string_type str() const
00065                 {
00066                         if(matched)
00067                                 return string_type(pair_type::first,pair_type::second);
00068                         else
00069                                 return string_type();
00070 
00071                 }
00075                 int compare(sub_match const &other) const
00076                 {
00077                         return str().compare(other.str());
00078                 }
00082                 int compare(string_type const &other) const
00083                 {
00084                         return str().compare(other);
00085                 }
00089                 int compare(value_type const *s) const
00090                 {
00091                         return str().compare(s);
00092                 }
00096                 sub_match() : matched(false)
00097                 {
00098                 }
00099         };
00100 
00101         typedef sub_match<char const *> csub_match;
00102         typedef sub_match<std::string::const_iterator> ssub_match;
00103 
00104 
00109         template<typename Iterator>
00110         class match_results {
00111         public:
00115                 match_results()
00116                 {
00117                         begin_ = Iterator();
00118                         end_ = Iterator();
00119                 }
00123                 typedef sub_match<Iterator> value_type;
00124 
00128                 value_type operator[](int n) const
00129                 {
00130                         value_type r;
00131                         if(n < 0 || n >= int(offsets_.size()))
00132                                 return r;
00133                         if(offsets_[n].first == -1)
00134                                 return r;
00135                         r.matched = true;
00136                         r.first = begin_;
00137                         r.second = begin_;
00138                         std::advance(r.first,offsets_[n].first);
00139                         std::advance(r.second,offsets_[n].second);
00140                         return r;
00141                 }
00142 
00146                 size_t size() const
00147                 {
00148                         return offsets_.size();
00149                 }
00150                 
00154                 value_type suffix()
00155                 {
00156                         value_type r;
00157                         if(offsets_.empty())
00158                                 return r;
00159                         r.first = begin_;
00160                         r.second = end_;
00161                         std::advance(r.first,offsets_.back().second);
00162                         r.matched = r.first != r.second;
00163                         return r;
00164                 }
00165 
00169                 value_type prefix()
00170                 {
00171                         value_type r;
00172                         if(offsets_.empty() || offsets_[0].first == 0)
00173                                 return r;
00174                         r.matched = true;
00175                         r.first = begin_;
00176                         r.second = begin_;
00177                         std::advance(r.second,offsets_[0].first);
00178                         return r;
00179                 }
00180 
00182 
00183                 void assign(Iterator begin,Iterator end,std::vector<std::pair<int,int> > &offsets)
00184                 {
00185                         begin_ = begin;
00186                         end_ = end;
00187                         offsets_.swap(offsets);
00188                 }
00189 
00191 
00192         private:
00193                 Iterator begin_,end_;
00194                 std::vector<std::pair<int,int> > offsets_;
00195         };
00196 
00197         typedef match_results<char const *> cmatch;
00198         typedef match_results<std::string::const_iterator> smatch;
00199 
00204         template<typename Regex>
00205         bool regex_match(char const *begin,char const *end,cmatch &m, Regex const &r,int flags = 0)
00206         {
00207                 std::vector<std::pair<int,int> > map;
00208                 bool res = r.match(begin,end,map,flags);
00209                 if(!res) return false;
00210                 m.assign(begin,end,map);
00211                 return true;
00212         }
00217 
00218         template<typename Regex>
00219         bool regex_match(std::string const &s,smatch &m, Regex const &r,int flags = 0)
00220         {
00221                 std::vector<std::pair<int,int> > map;
00222                 bool res = r.match(s.c_str(),s.c_str()+s.size(),map,flags);
00223                 if(!res) return false;
00224                 m.assign(s.begin(),s.end(),map);
00225                 return true;
00226         }
00231         
00232         template<typename Regex>
00233         bool regex_match(char const *s,cmatch &m, Regex const &r,int flags = 0)
00234         {
00235                 std::vector<std::pair<int,int> > map;
00236                 char const *begin=s;
00237                 char const *end = begin+strlen(begin);
00238                 bool res = r.match(begin,end,map,flags);
00239                 if(!res) return false;
00240                 m.assign(begin,end,map);
00241                 return true;
00242         }
00243 
00248         template<typename Regex>
00249         bool regex_search(char const *begin,char const *end,cmatch &m, Regex const &r,int flags = 0)
00250         {
00251                 std::vector<std::pair<int,int> > map;
00252                 bool res = r.search(begin,end,map,flags);
00253                 if(!res) return false;
00254                 m.assign(begin,end,map);
00255                 return true;
00256         }
00257 
00262         template<typename Regex>
00263         bool regex_search(std::string const &s,smatch &m, Regex const &r,int flags = 0)
00264         {
00265                 std::vector<std::pair<int,int> > map;
00266                 bool res = r.search(s.c_str(),s.c_str()+s.size(),map,flags);
00267                 if(!res) return false;
00268                 m.assign(s.begin(),s.end(),map);
00269                 return true;
00270         }
00271         
00276         
00277         template<typename Regex>
00278         bool regex_search(char const *s,cmatch &m, Regex const &r,int flags = 0)
00279         {
00280                 std::vector<std::pair<int,int> > map;
00281                 char const *begin=s;
00282                 char const *end = begin+strlen(begin);
00283                 bool res = r.search(begin,end,map,flags);
00284                 if(!res) return false;
00285                 m.assign(begin,end,map);
00286                 return true;
00287         }
00288 
00292         template<typename Regex>
00293         bool regex_match(char const *begin,char const *end, Regex const &r,int flags = 0)
00294         {
00295                 return r.match(begin,end,flags);
00296         }
00300 
00301         template<typename Regex>
00302         bool regex_match(std::string const &s, Regex const &r,int flags = 0)
00303         {
00304                 return r.match(s.c_str(),s.c_str()+s.size(),flags);
00305         }
00309         
00310         template<typename Regex>
00311         bool regex_match(char const *s, Regex const &r,int flags = 0)
00312         {
00313                 return r.match(s,s+strlen(s),flags);
00314         }
00315         
00319         template<typename Regex>
00320         bool regex_search(char const *begin,char const *end, Regex const &r,int flags = 0)
00321         {
00322                 return r.search(begin,end,flags);
00323         }
00324 
00328         template<typename Regex>
00329         bool regex_search(std::string const &s, Regex const &r,int flags = 0)
00330         {
00331                 return r.search(s.c_str(),s.c_str()+s.size(),flags);
00332         }
00333         
00337         template<typename Regex>
00338         bool regex_search(char const *s, Regex const &r,int flags = 0)
00339         {
00340                 return r.search(s,s+strlen(s),flags);
00341         }
00342 
00343         
00344         // sub -- sub   
00345         template<typename Iterator>
00346         bool operator==(sub_match<Iterator> const &l,sub_match<Iterator> const &r) { return l.compare(r) == 0; }
00347         template<typename Iterator>
00348         bool operator!=(sub_match<Iterator> const &l,sub_match<Iterator> const &r) { return l.compare(r) != 0; }
00349         template<typename Iterator>
00350         bool operator< (sub_match<Iterator> const &l,sub_match<Iterator> const &r) { return l.compare(r) <  0; }
00351         template<typename Iterator>
00352         bool operator> (sub_match<Iterator> const &l,sub_match<Iterator> const &r) { return l.compare(r) >  0; }
00353         template<typename Iterator>
00354         bool operator<=(sub_match<Iterator> const &l,sub_match<Iterator> const &r) { return l.compare(r) <= 0; }
00355         template<typename Iterator>
00356         bool operator>=(sub_match<Iterator> const &l,sub_match<Iterator> const &r) { return l.compare(r) >= 0; }
00357 
00358         // str -- sub
00359         template<typename Iterator>
00360         bool operator==(
00361                 typename sub_match<Iterator>::string_type const &l,
00362                 sub_match<Iterator> const &r) 
00363         { return l.compare(r) == 0; }
00364         template<typename Iterator>
00365         bool operator!=(
00366                 typename sub_match<Iterator>::string_type const &l,
00367                 sub_match<Iterator> const &r) 
00368         { return l.compare(r) != 0; }
00369         
00370         template<typename Iterator>
00371         bool operator<=(
00372                 typename sub_match<Iterator>::string_type const &l,
00373                 sub_match<Iterator> const &r) 
00374         { return l.compare(r) <= 0; }
00375         template<typename Iterator>
00376         bool operator>=(
00377                 typename sub_match<Iterator>::string_type const &l,
00378                 sub_match<Iterator> const &r) 
00379         { return l.compare(r) >= 0; }
00380         
00381         template<typename Iterator>
00382         bool operator<(
00383                 typename sub_match<Iterator>::string_type const &l,
00384                 sub_match<Iterator> const &r) 
00385         { return l.compare(r) <0; }
00386         template<typename Iterator>
00387         bool operator>(
00388                 typename sub_match<Iterator>::string_type const &l,
00389                 sub_match<Iterator> const &r) 
00390         { return l.compare(r) > 0; }
00391 
00392         // sub -- str
00393 
00394         template<typename Iterator>
00395         bool operator==(
00396                 sub_match<Iterator> const &l,
00397                 typename sub_match<Iterator>::string_type const &r
00398                 ) 
00399         { return l.compare(r) == 0; }
00400         template<typename Iterator>
00401         bool operator!=(
00402                 sub_match<Iterator> const &l,
00403                 typename sub_match<Iterator>::string_type const &r
00404                 ) 
00405         { return l.compare(r) != 0; }
00406         
00407         template<typename Iterator>
00408         bool operator<=(
00409                 sub_match<Iterator> const &l,
00410                 typename sub_match<Iterator>::string_type const &r
00411                 ) 
00412         { return l.compare(r) <= 0; }
00413 
00414         template<typename Iterator>
00415         bool operator>=(
00416                 sub_match<Iterator> const &l,
00417                 typename sub_match<Iterator>::string_type const &r
00418                 ) 
00419         { return l.compare(r) >= 0; }
00420         
00421         template<typename Iterator>
00422         bool operator<(
00423                 sub_match<Iterator> const &l,
00424                 typename sub_match<Iterator>::string_type const &r
00425                 ) 
00426         { return l.compare(r) <0; }
00427 
00428         template<typename Iterator>
00429         bool operator>(
00430                 sub_match<Iterator> const &l,
00431                 typename sub_match<Iterator>::string_type const &r
00432                 ) 
00433         { return l.compare(r) > 0; }
00434 
00435         // * -- sub
00436         template<typename Iterator>
00437         bool operator==(
00438                 typename std::iterator_traits<Iterator>::value_type const *l,
00439                 sub_match<Iterator> const &r) 
00440         { return r.compare(l) ==0; }
00441         template<typename Iterator>
00442         bool operator!=(
00443                 typename std::iterator_traits<Iterator>::value_type const *l,
00444                 sub_match<Iterator> const &r) 
00445         { return r.compare(l) !=0; }
00446 
00447 
00448         template<typename Iterator>
00449         bool operator<=(
00450                 typename std::iterator_traits<Iterator>::value_type const *l,
00451                 sub_match<Iterator> const &r) 
00452         { return r.compare(l) > 0; }
00453         template<typename Iterator>
00454         bool operator>=(
00455                 typename std::iterator_traits<Iterator>::value_type const *l,
00456                 sub_match<Iterator> const &r) 
00457         { return r.compare(l) < 0; }
00458         
00459         template<typename Iterator>
00460         bool operator<(
00461                 typename std::iterator_traits<Iterator>::value_type const *l,
00462                 sub_match<Iterator> const &r) 
00463         { return r.compare(l) >=0; }
00464         template<typename Iterator>
00465         bool operator>(
00466                 typename std::iterator_traits<Iterator>::value_type const *l,
00467                 sub_match<Iterator> const &r) 
00468         { return r.compare(l) <= 0; }
00469 
00470 
00471         // sub -- *
00472 
00473         template<typename Iterator>
00474         bool operator==(
00475                 sub_match<Iterator> const &l,
00476                 typename std::iterator_traits<Iterator>::value_type const *r
00477                 ) 
00478         { return l.compare(r) == 0; }
00479         template<typename Iterator>
00480         bool operator!=(
00481                 sub_match<Iterator> const &l,
00482                 typename std::iterator_traits<Iterator>::value_type const *r
00483                 ) 
00484         { return l.compare(r) != 0; }
00485         
00486         template<typename Iterator>
00487         bool operator<=(
00488                 sub_match<Iterator> const &l,
00489                 typename std::iterator_traits<Iterator>::value_type const *r
00490                 ) 
00491         { return l.compare(r) <= 0; }
00492 
00493         template<typename Iterator>
00494         bool operator>=(
00495                 sub_match<Iterator> const &l,
00496                 typename std::iterator_traits<Iterator>::value_type const *r
00497                 ) 
00498         { return l.compare(r) >= 0; }
00499         
00500         template<typename Iterator>
00501         bool operator<(
00502                 sub_match<Iterator> const &l,
00503                 typename std::iterator_traits<Iterator>::value_type const *r
00504                 ) 
00505         { return l.compare(r) <0; }
00506 
00507         template<typename Iterator>
00508         bool operator>(
00509                 sub_match<Iterator> const &l,
00510                 typename std::iterator_traits<Iterator>::value_type const *r
00511                 ) 
00512         { return l.compare(r) > 0; }
00513 
00514         // add + 
00515 
00516         template<typename Iterator>
00517         typename sub_match<Iterator>::string_type 
00518         operator+(sub_match<Iterator> const &l,sub_match<Iterator> const &r)
00519         { return l.str() + r.str(); }
00520         
00521         template<typename Iterator>
00522         typename sub_match<Iterator>::string_type 
00523         operator+(sub_match<Iterator> const &l,typename sub_match<Iterator>::string_type const &r)
00524         { return l.str() + r; }
00525         
00526         template<typename Iterator>
00527         typename sub_match<Iterator>::string_type 
00528         operator+(typename sub_match<Iterator>::string_type const &l,sub_match<Iterator> const &r)
00529         { return l + r.str(); }
00530         
00531         template<typename Iterator>
00532         typename sub_match<Iterator>::string_type 
00533         operator+(sub_match<Iterator> const &l,typename sub_match<Iterator>::value_type const *r)
00534         { return l.str() + r; }
00535         
00536         template<typename Iterator>
00537         typename sub_match<Iterator>::string_type 
00538         operator+(typename sub_match<Iterator>::value_type const *l,sub_match<Iterator> const &r)
00539         { return l + r.str(); }
00540 
00541 }
00542 
00543 
00544 
00545 #endif