00001
00002
00003
00004
00005
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