CppCMS
|
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