CppCMS
cppcms/string_key.h
00001 
00002 //                                                                             
00003 //  Copyright (C) 2008-2012  Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>     
00004 //                                                                             
00005 //  See accompanying file COPYING.TXT file for licensing details.
00006 //
00008 #ifndef CPPCMS_STRING_KEY_H
00009 #define CPPCMS_STRING_KEY_H
00010 
00011 #include <string>
00012 #include <string.h>
00013 #include <algorithm>
00014 #include <stdexcept>
00015 #include <ostream>
00016 
00017 namespace cppcms {
00018 
00030         class string_key {
00031         public:
00032 
00036                 typedef char const *const_iterator;
00037 
00041                 static const size_t npos = -1;
00042                 
00046                 string_key() : 
00047                         begin_(0),
00048                         end_(0)
00049                 {
00050                 }
00051 
00055                 string_key(char const *key) :
00056                         begin_(0),
00057                         end_(0),
00058                         key_(key)
00059                 {
00060                 }
00064                 string_key(std::string const &key) :
00065                         begin_(0),
00066                         end_(0),
00067                         key_(key)
00068                 {
00069                 }
00073                 size_t size() const
00074                 {
00075                         return end() - begin();
00076                 }
00080                 size_t length() const
00081                 {
00082                         return size();
00083                 }
00087                 void clear()
00088                 {
00089                         begin_ = end_ = 0;
00090                         key_.clear();
00091                 }
00095                 bool empty() const
00096                 {
00097                         return end() == begin();
00098                 }
00103                 size_t find(char c,size_t pos = 0) const
00104                 {
00105                         size_t s = size();
00106                         if(pos >= s)
00107                                 return npos;
00108                         char const *p=begin() + pos;
00109                         while(pos <= s && *p!=c) {
00110                                 pos++;
00111                                 p++;
00112                         }
00113                         if(pos >= s)
00114                                 return npos;
00115                         return pos;
00116                 }
00117 
00121                 string_key substr(size_t pos = 0,size_t n=npos) const
00122                 {
00123                         string_key tmp = unowned_substr(pos,n);
00124                         return string_key(std::string(tmp.begin(),tmp.end()));
00125                 }
00130                 string_key unowned_substr(size_t pos = 0,size_t n=npos) const
00131                 {
00132                         if(pos >= size()) {
00133                                 return string_key();
00134                         }
00135                         char const *p=begin() + pos;
00136                         char const *e=end();
00137                         if(n > size_t(e-p)) {
00138                                 return string_key(p,e);
00139                         }
00140                         else {
00141                                 return string_key(p,p+n);
00142                         }
00143                 }
00144                 
00148                 char const &operator[](size_t n) const
00149                 {
00150                         return *(begin() + n);
00151                 }
00155                 char const &at(size_t n) const
00156                 {
00157                         if(n > size())
00158                                 throw std::out_of_range("cppcms::string_key::at() range error");
00159                         return *(begin() + n);
00160                 }
00161 
00166                 static string_key unowned(std::string const &v) 
00167                 {
00168                         return string_key(v.c_str(),v.c_str()+v.size());
00169                 }
00174                 static string_key unowned(char const *str) 
00175                 {
00176                         char const *end = str;
00177                         while(*end)
00178                                 end++;
00179                         return string_key(str,end);
00180                 }
00185                 static string_key unowned(char const *begin,char const *end) 
00186                 {
00187                         return string_key(begin,end);
00188                 }
00189 
00193                 char const *begin() const
00194                 {
00195                         if(begin_)
00196                                 return begin_;
00197                         return key_.c_str();
00198                 }
00202                 char const *end() const
00203                 {
00204                         if(begin_)
00205                                 return end_;
00206                         return key_.c_str() + key_.size();
00207                 }
00211                 bool operator<(string_key const &other) const
00212                 {
00213                         return std::lexicographical_compare(    begin(),end(),
00214                                                                 other.begin(),other.end(),
00215                                                                 std::char_traits<char>::lt);
00216                 }
00220                 bool operator>(string_key const &other) const
00221                 {
00222                         return other < *this;
00223                 }
00227                 bool operator>=(string_key const &other) const
00228                 {
00229                         return !(*this < other);
00230                 }
00234                 bool operator<=(string_key const &other) const
00235                 {
00236                         return !(*this > other);
00237                 }
00241                 bool operator==(string_key const &other) const
00242                 {
00243                         return (end() - begin() == other.end() - other.begin())
00244                                 && memcmp(begin(),other.begin(),end()-begin()) == 0;
00245                 }
00249                 bool operator!=(string_key const &other) const
00250                 {
00251                         return !(*this!=other);
00252                 }
00253 
00257                 char const *data() const
00258                 {
00259                         return begin();
00260                 }
00261 
00265                 std::string str() const
00266                 {
00267                         if(begin_)
00268                                 return std::string(begin_,end_-begin_);
00269                         else
00270                                 return key_;
00271                 }
00275                 operator std::string() const
00276                 {
00277                         return str();
00278                 }
00279         private:
00280                 string_key(char const *b,char const *e) :
00281                         begin_(b),
00282                         end_(e)
00283                 {
00284                 }
00285 
00286                 char const *begin_;
00287                 char const *end_;
00288                 std::string key_;
00289         };
00290 
00294         inline std::ostream &operator<<(std::ostream &out,string_key const &s)
00295         {
00296                 out.write(s.data(),s.size());
00297                 return out;
00298         }
00299 
00303         inline bool operator==(string_key const &l,char const *r)
00304         {
00305                 return l==string_key::unowned(r);
00306         }
00307 
00311         inline bool operator==(char const *l,string_key const &r)
00312         {
00313                 return string_key::unowned(l) == r;
00314         }
00315 
00319         inline bool operator==(string_key const &l,std::string const &r)
00320         {
00321                 return l==string_key::unowned(r);
00322         }
00323 
00324 
00328         inline bool operator==(std::string const &l,string_key const &r)
00329         {
00330                 return string_key::unowned(l) == r;
00331         }
00332 
00336         inline bool operator!=(string_key const &l,char const *r)
00337         {
00338                 return l!=string_key::unowned(r);
00339         }
00340 
00344         inline bool operator!=(char const *l,string_key const &r)
00345         {
00346                 return string_key::unowned(l) != r;
00347         }
00348 
00352         inline bool operator!=(string_key const &l,std::string const &r)
00353         {
00354                 return l!=string_key::unowned(r);
00355         }
00356 
00360         inline bool operator!=(std::string const &l,string_key const &r)
00361         {
00362                 return string_key::unowned(l) != r;
00363         }
00367         inline bool operator<=(string_key const &l,char const *r)
00368         {
00369                 return l<=string_key::unowned(r);
00370         }
00371 
00375         inline bool operator<=(char const *l,string_key const &r)
00376         {
00377                 return string_key::unowned(l) <= r;
00378         }
00379 
00383         inline bool operator<=(string_key const &l,std::string const &r)
00384         {
00385                 return l<=string_key::unowned(r);
00386         }
00387 
00391         inline bool operator<=(std::string const &l,string_key const &r)
00392         {
00393                 return string_key::unowned(l) <= r;
00394         }
00398         inline bool operator>=(string_key const &l,char const *r)
00399         {
00400                 return l>=string_key::unowned(r);
00401         }
00402 
00406         inline bool operator>=(char const *l,string_key const &r)
00407         {
00408                 return string_key::unowned(l) >= r;
00409         }
00410 
00414         inline bool operator>=(string_key const &l,std::string const &r)
00415         {
00416                 return l>=string_key::unowned(r);
00417         }
00418 
00422         inline bool operator>=(std::string const &l,string_key const &r)
00423         {
00424                 return string_key::unowned(l) >= r;
00425         }
00426 
00427 
00431         inline bool operator<(string_key const &l,char const *r)
00432         {
00433                 return l<string_key::unowned(r);
00434         }
00435 
00439         inline bool operator<(char const *l,string_key const &r)
00440         {
00441                 return string_key::unowned(l) < r;
00442         }
00443 
00447         inline bool operator<(string_key const &l,std::string const &r)
00448         {
00449                 return l<string_key::unowned(r);
00450         }
00451 
00455         inline bool operator<(std::string const &l,string_key const &r)
00456         {
00457                 return string_key::unowned(l) < r;
00458         }
00462         inline bool operator>(string_key const &l,char const *r)
00463         {
00464                 return l>string_key::unowned(r);
00465         }
00466 
00470         inline bool operator>(char const *l,string_key const &r)
00471         {
00472                 return string_key::unowned(l) > r;
00473         }
00474 
00478         inline bool operator>(string_key const &l,std::string const &r)
00479         {
00480                 return l>string_key::unowned(r);
00481         }
00482 
00486         inline bool operator>(std::string const &l,string_key const &r)
00487         {
00488                 return string_key::unowned(l) > r;
00489         }
00490 
00491 }
00492 
00493 #endif