00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00035
00036
00119
00120
00121 #ifndef OPENIMAGEIO_USTRING_H
00122 #define OPENIMAGEIO_USTRING_H
00123
00124 #include <string>
00125 #include <iostream>
00126 #include <cstring>
00127 #include "export.h"
00128 #include "strutil.h"
00129
00130 #ifdef _WIN32
00131 #include "hash.h"
00132 #endif
00133
00134 #ifndef NULL
00135 #define NULL 0
00136 #endif
00137
00138
00139 #ifdef OPENIMAGEIO_NAMESPACE
00140 namespace OPENIMAGEIO_NAMESPACE {
00141 #endif
00142
00143
00144
00145
00146
00147 class DLLPUBLIC ustring {
00148 public:
00149 typedef char value_type;
00150 typedef value_type * pointer;
00151 typedef value_type & reference;
00152 typedef const value_type & const_reference;
00153 typedef size_t size_type;
00154 static const size_type npos = static_cast<size_type>(-1);
00155 typedef std::string::const_iterator const_iterator;
00156 typedef std::string::const_reverse_iterator const_reverse_iterator;
00157
00160 ustring (void) : m_chars(NULL) { }
00161
00164 explicit ustring (const char *str) {
00165 m_chars = str ? _make_unique(str)->c_str() : NULL;
00166 }
00167
00170 ustring (const char *str, size_type pos, size_type n)
00171 : m_chars (_make_unique(std::string(str,pos,n).c_str())->c_str()) { }
00172
00175 ustring (const char *str, size_type n)
00176 : m_chars (_make_unique(std::string(str,n).c_str())->c_str()) { }
00177
00180 ustring (size_type n, char c)
00181 : m_chars (_make_unique(std::string(n,c).c_str())->c_str()) { }
00182
00185 explicit ustring (const std::string &str) { *this = ustring(str.c_str()); }
00186
00189 ustring (const std::string &str, size_type pos, size_type n=npos)
00190 : m_chars (_make_unique(std::string(str, pos, n).c_str())->c_str()) { }
00191
00194 ustring (const ustring &str) : m_chars(str.m_chars) { }
00195
00198 ustring (const ustring &str, size_type pos, size_type n=npos)
00199 : m_chars (_make_unique(std::string(str.c_str(),pos,n).c_str())->c_str()) { }
00200
00203 ~ustring () { }
00204
00207 const ustring & assign (const ustring &str) {
00208 m_chars = str.m_chars;
00209 return *this;
00210 }
00211
00214 const ustring & assign (const ustring &str, size_type pos, size_type n=npos)
00215 { *this = ustring(str,pos,n); return *this; }
00216
00219 const ustring & assign (const std::string &str) {
00220 assign (str.c_str());
00221 return *this;
00222 }
00223
00226 const ustring & assign (const std::string &str, size_type pos,
00227 size_type n=npos)
00228 { *this = ustring(str,pos,n); return *this; }
00229
00232 const ustring & assign (const char *str) {
00233 m_chars = str ? _make_unique(str)->c_str() : NULL;
00234 return *this;
00235 }
00236
00239 const ustring & assign (const char *str, size_type n)
00240 { *this = ustring(str,n); return *this; }
00241
00244 const ustring & assign (size_type n, char c)
00245 { *this = ustring(n,c); return *this; }
00246
00249 const ustring & operator= (const ustring &str) { return assign(str); }
00250
00253 const ustring & operator= (const char *str) { return assign(str); }
00254
00257 const ustring & operator= (const std::string &str) { return assign(str); }
00258
00261 const ustring & operator= (char c) {
00262 char s[2];
00263 s[0] = c; s[1] = 0;
00264 *this = ustring (s);
00265 return *this;
00266 }
00267
00270 const char *c_str () const {
00271 return m_chars;
00272 }
00273
00276 const char *data () const { return c_str(); }
00277
00280 const std::string & string () const {
00281 if (m_chars) {
00282 const TableRep *rep = (const TableRep *)(m_chars - chars_offset);
00283 return rep->str;
00284 }
00285 else return empty_std_string;
00286 }
00287
00290 void clear (void) {
00291 m_chars = NULL;
00292 }
00293
00296 size_t length (void) const {
00297 if (! m_chars)
00298 return 0;
00299 const TableRep *rep = (const TableRep *)(m_chars - chars_offset);
00300 return rep->length;
00301 }
00302
00305 size_t hash (void) const {
00306 if (! m_chars)
00307 return 0;
00308 const TableRep *rep = (const TableRep *)(m_chars - chars_offset);
00309 return rep->hashed;
00310 }
00311
00314 size_t size (void) const { return length(); }
00315
00318 bool empty (void) const { return (size() == 0); }
00319
00323 operator int (void) { return !empty(); }
00324
00327 const_iterator begin () const { return string().begin(); }
00328
00331 const_iterator end () const { return string().end(); }
00332
00335 const_reverse_iterator rbegin () const { return string().rbegin(); }
00336
00339 const_reverse_iterator rend () const { return string().rend(); }
00340
00344 const_reference operator[] (size_type pos) const { return c_str()[pos]; }
00345
00348 size_type copy (char* s, size_type n, size_type pos = 0) const {
00349 char *c = strncpy (s, c_str()+pos, n);
00350 return (size_type)(c-s);
00351 }
00352
00353
00354
00355
00359
00360 int compare (const ustring& str) const {
00361 return c_str() == str.c_str() ? 0 : strcmp (c_str(), str.c_str());
00362 }
00363
00367 int compare (const std::string& str) const {
00368 return strcmp (c_str(), str.c_str());
00369 }
00370
00374 friend int compare (const std::string& a, const ustring &b) {
00375 return strcmp (a.c_str(), b.c_str());
00376 }
00377
00382 bool operator== (const ustring &str) const {
00383 return c_str() == str.c_str();
00384 }
00385
00390 bool operator!= (const ustring &str) const {
00391 return c_str() != str.c_str();
00392 }
00393
00396 bool operator== (const std::string &x) const { return compare(x) == 0; }
00397
00400 friend bool operator== (const std::string &a, const ustring &b) {
00401 return b.compare(a) == 0;
00402 }
00403
00406 bool operator!= (const std::string &x) const { return compare(x) != 0; }
00407
00410 friend bool operator!= (const std::string &a, const ustring &b) {
00411 return b.compare(a) != 0;
00412 }
00413
00416 bool operator< (const ustring &x) const { return compare(x) < 0; }
00417
00422 static ustring format (const char *fmt, ...) OPENIMAGEIO_PRINTF_ARGS(1,2);
00423
00426 friend std::ostream & operator<< (std::ostream &out, const ustring &str) {
00427 if (str.c_str())
00428 out << str.c_str();
00429 return out;
00430 }
00431
00432 private:
00433
00436 const char *m_chars;
00437
00438 public:
00441 struct TableRep {
00442 std::string str;
00443 unsigned int length;
00444 unsigned int hashed;
00445 char chars[1];
00446 TableRep (const char *s) : str(s), length(str.size()), hashed(Strutil::strhash(s)) {
00447 strcpy (chars, s);
00448 }
00449 const char *c_str () const { return chars; }
00450 };
00453 static const off_t chars_offset = sizeof(std::string)+2*sizeof(unsigned int);
00454
00455
00456
00457 private:
00462 static const TableRep * _make_unique (const char *str);
00463 static std::string empty_std_string;
00464 };
00465
00466
00467
00470 class ustringHash
00471 #ifdef _WIN32
00472 : public hash_compare<ustring>
00473 #endif
00474 {
00475 public:
00476 size_t operator() (const ustring &s) const { return s.hash(); }
00477 #ifdef _WIN32
00478 bool operator() (const ustring &a, const ustring &b) {
00479 return strcmp (a.c_str(), b.c_str()) < 0;
00480 }
00481 #endif
00482 };
00483
00484
00485
00486
00487
00488
00489 #ifdef OPENIMAGEIO_NAMESPACE
00490 };
00491 using namespace OPENIMAGEIO_NAMESPACE;
00492 #endif
00493
00494 #endif // OPENIMAGEIO_USTRING_H