HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ustring.h
Go to the documentation of this file.
1 /*
2  Copyright 2008 Larry Gritz and the other authors and contributors.
3  All Rights Reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are
7  met:
8  * Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13  * Neither the name of the software's owners nor the names of its
14  contributors may be used to endorse or promote products derived from
15  this software without specific prior written permission.
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28  (This is the Modified BSD License)
29 */
30 
31 
32 /// \file
33 /// Define the ustring class, unique strings with efficient storage and
34 /// very fast copy and comparison.
35 
36 
37 /////////////////////////////////////////////////////////////////////////////
38 /// \class ustring
39 ///
40 /// A ustring is an alternative to char* or std::string for storing
41 /// strings, in which the character sequence is unique (allowing many
42 /// speed advantages for assignment, equality testing, and inequality
43 /// testing).
44 ///
45 /// The implementation is that behind the scenes there is a hash set of
46 /// allocated strings, so the characters of each string are unique. A
47 /// ustring itself is a pointer to the characters of one of these canonical
48 /// strings. Therefore, assignment and equality testing is just a single
49 /// 32- or 64-bit int operation, the only mutex is when a ustring is
50 /// created from raw characters, and the only malloc is the first time
51 /// each canonical ustring is created.
52 ///
53 /// The internal table also contains a std::string version and the length
54 /// of the string, so converting a ustring to a std::string (via
55 /// ustring::string()) or querying the number of characters (via
56 /// ustring::size() or ustring::length()) is extremely inexpensive, and does
57 /// not involve creation/allocation of a new std::string or a call to
58 /// strlen.
59 ///
60 /// We try very hard to completely mimic the API of std::string,
61 /// including all the constructors, comparisons, iterations, etc. Of
62 /// course, the charaters of a ustring are non-modifiable, so we do not
63 /// replicate any of the non-const methods of std::string. But in most
64 /// other ways it looks and acts like a std::string and so most templated
65 /// algorthms that would work on a "const std::string &" will also work
66 /// on a ustring.
67 ///
68 /// Usage guidelines:
69 ///
70 /// Compared to standard strings, ustrings have several advantages:
71 ///
72 /// - Each individual ustring is very small -- in fact, we guarantee that
73 /// a ustring is the same size and memory layout as an ordinary char*.
74 /// - Storage is frugal, since there is only one allocated copy of each
75 /// unique character sequence, throughout the lifetime of the program.
76 /// - Assignment from one ustring to another is just copy of the pointer;
77 /// no allocation, no character copying, no reference counting.
78 /// - Equality testing (do the strings contain the same characters) is
79 /// a single operation, the comparison of the pointer.
80 /// - Memory allocation only occurs when a new ustring is construted from
81 /// raw characters the FIRST time -- subsequent constructions of the
82 /// same string just finds it in the canonial string set, but doesn't
83 /// need to allocate new storage. Destruction of a ustring is trivial,
84 /// there is no de-allocation because the canonical version stays in
85 /// the set. Also, therefore, no user code mistake can lead to
86 /// memory leaks.
87 ///
88 /// But there are some problems, too. Canonical strings are never freed
89 /// from the table. So in some sense all the strings "leak", but they
90 /// only leak one copy for each unique string that the program ever comes
91 /// across. Also, creation of unique strings from raw characters is more
92 /// expensive than for standard strings, due to hashing, table queries,
93 /// and other overhead.
94 ///
95 /// On the whole, ustrings are a really great string representation
96 /// - if you tend to have (relatively) few unique strings, but many
97 /// copies of those strings;
98 /// - if the creation of strings from raw characters is relatively
99 /// rare compared to copying or comparing to existing strings;
100 /// - if you tend to make the same strings over and over again, and
101 /// if it's relatively rare that a single unique character sequence
102 /// is used only once in the entire lifetime of the program;
103 /// - if your most common string operations are assignment and equality
104 /// testing and you want them to be as fast as possible;
105 /// - if you are doing relatively little character-by-character assembly
106 /// of strings, string concatenation, or other "string manipulation"
107 /// (other than equality testing).
108 ///
109 /// ustrings are not so hot
110 /// - if your program tends to have very few copies of each character
111 /// sequence over the entire lifetime of the program;
112 /// - if your program tends to generate a huge variety of unique
113 /// strings over its lifetime, each of which is used only a short
114 /// time and then discarded, never to be needed again;
115 /// - if you don't need to do a lot of string assignment or equality
116 /// testing, but lots of more complex string manipulation.
117 ///
118 /////////////////////////////////////////////////////////////////////////////
119 
120 
121 #pragma once
122 #define OPENIMAGEIO_USTRING_H
123 
124 #if defined(_MSC_VER)
125 // Ignore warnings about DLL exported classes with member variables that are template classes.
126 // This happens with the std::string empty_std_string static member variable of ustring below.
127 // Also remove a warning about the strncpy function not being safe and deprecated in MSVC.
128 // There is no equivalent safe and portable function and trying to fix this is more trouble than
129 // its worth. (see http://stackoverflow.com/questions/858252/alternatives-to-ms-strncpy-s)
130 # pragma warning(disable : 4251 4996)
131 #endif
132 
133 #include <OpenImageIO/dassert.h>
134 #include <OpenImageIO/export.h>
135 #include <OpenImageIO/oiioversion.h>
136 #include <OpenImageIO/string_view.h>
137 #include <OpenImageIO/strutil.h>
138 #include <cstring>
139 #include <iostream>
140 #include <string>
141 
142 
144 
146 public:
147  typedef char value_type;
148  typedef value_type* pointer;
150  typedef const value_type& const_reference;
151  typedef size_t size_type;
152  static const size_type npos = static_cast<size_type>(-1);
153  typedef std::string::const_iterator const_iterator;
154  typedef std::string::const_reverse_iterator const_reverse_iterator;
155 
156  /// Default ctr for ustring -- make an empty string.
157  ///
158  ustring(void)
159  : m_chars(nullptr)
160  {
161  }
162 
163  /// Construct a ustring from a null-terminated C string (char *).
164  ///
165  explicit ustring(const char* str)
166  {
167  m_chars = str ? make_unique(str) : nullptr;
168  }
169 
170  /// Construct a ustring from a string_view, which can be auto-converted
171  /// from either a null-terminated C string (char *) or a C++
172  /// std::string.
173  explicit ustring(string_view str)
174  {
175  m_chars = str.data() ? make_unique(str) : nullptr;
176  }
177 
178  /// Construct a ustring from at most n characters of str, starting at
179  /// position pos.
180  ustring(const char* str, size_type pos, size_type n)
181  : m_chars(make_unique(std::string(str, pos, n).c_str()))
182  {
183  }
184 
185  /// Construct a ustring from the first n characters of str.
186  ///
187  ustring(const char* str, size_type n)
188  : m_chars(make_unique(string_view(str, n)))
189  {
190  }
191 
192  /// Construct a ustring from n copies of character c.
193  ///
195  : m_chars(make_unique(std::string(n, c).c_str()))
196  {
197  }
198 
199  /// Construct a ustring from an indexed substring of a std::string.
200  ///
201  ustring(const std::string& str, size_type pos, size_type n = npos)
202  {
203  string_view sref(str);
204  sref = sref.substr(pos, n);
205  m_chars = make_unique(sref);
206  }
207 
208  /// Copy construct a ustring from another ustring.
209  ///
210  ustring(const ustring& str)
211  : m_chars(str.m_chars)
212  {
213  }
214 
215  /// Construct a ustring from an indexed substring of a ustring.
216  ///
217  ustring(const ustring& str, size_type pos, size_type n = npos)
218  {
219  string_view sref(str);
220  sref = sref.substr(pos, n);
221  m_chars = make_unique(sref);
222  }
223 
224  /// ustring destructor.
225  ///
226  ~ustring() {}
227 
228  /// Conversion to string_view
229  operator string_view() const { return string_view(c_str(), length()); }
230 
231  /// Assign a ustring to *this.
232  ///
233  const ustring& assign(const ustring& str)
234  {
235  m_chars = str.m_chars;
236  return *this;
237  }
238 
239  /// Assign a substring of a ustring to *this.
240  ///
241  const ustring& assign(const ustring& str, size_type pos, size_type n = npos)
242  {
243  *this = ustring(str, pos, n);
244  return *this;
245  }
246 
247  /// Assign a std::string to *this.
248  ///
249  const ustring& assign(const std::string& str)
250  {
251  assign(str.c_str());
252  return *this;
253  }
254 
255  /// Assign a substring of a std::string to *this.
256  ///
257  const ustring& assign(const std::string& str, size_type pos,
258  size_type n = npos)
259  {
260  *this = ustring(str, pos, n);
261  return *this;
262  }
263 
264  /// Assign a null-terminated C string (char*) to *this.
265  ///
266  const ustring& assign(const char* str)
267  {
268  m_chars = str ? make_unique(str) : nullptr;
269  return *this;
270  }
271 
272  /// Assign the first n characters of str to *this.
273  ///
274  const ustring& assign(const char* str, size_type n)
275  {
276  *this = ustring(str, n);
277  return *this;
278  }
279 
280  /// Assign n copies of c to *this.
281  ///
282  const ustring& assign(size_type n, char c)
283  {
284  *this = ustring(n, c);
285  return *this;
286  }
287 
288  /// Assign a string_view to *this.
290  {
291  m_chars = str.length() ? make_unique(str) : nullptr;
292  return *this;
293  }
294 
295  /// Assign a ustring to another ustring.
296  ///
297  const ustring& operator=(const ustring& str) { return assign(str); }
298 
299  /// Assign a null-terminated C string (char *) to a ustring.
300  ///
301  const ustring& operator=(const char* str) { return assign(str); }
302 
303  /// Assign a C++ std::string to a ustring.
304  ///
305  const ustring& operator=(const std::string& str) { return assign(str); }
306 
307  /// Assign a string_view to a ustring.
308  ///
309  const ustring& operator=(string_view str) { return assign(str); }
310 
311  /// Assign a single char to a ustring.
312  ///
313  const ustring& operator=(char c)
314  {
315  char s[2];
316  s[0] = c;
317  s[1] = 0;
318  *this = ustring(s);
319  return *this;
320  }
321 
322  /// Return a C string representation of a ustring.
323  ///
324  const char* c_str() const { return m_chars; }
325 
326  /// Return a C string representation of a ustring.
327  ///
328  const char* data() const { return c_str(); }
329 
330  /// Return a C++ std::string representation of a ustring.
331  ///
332  const std::string& string() const
333  {
334  if (m_chars) {
335  const TableRep* rep = (const TableRep*)m_chars - 1;
336  return rep->str;
337  } else
338  return empty_std_string;
339  }
340 
341  /// Reset to an empty string.
342  ///
343  void clear(void) { m_chars = nullptr; }
344 
345  /// Return the number of characters in the string.
346  ///
347  size_t length(void) const
348  {
349  if (!m_chars)
350  return 0;
351  const TableRep* rep = ((const TableRep*)m_chars) - 1;
352  return rep->length;
353  }
354 
355  /// Return a hashed version of the string
356  ///
357  size_t hash(void) const
358  {
359  if (!m_chars)
360  return 0;
361  const TableRep* rep = ((const TableRep*)m_chars) - 1;
362  return rep->hashed;
363  }
364 
365  /// Return the number of characters in the string.
366  ///
367  size_t size(void) const { return length(); }
368 
369  /// Is the string empty -- i.e., is it nullptr or does it point to an
370  /// empty string?
371  bool empty(void) const { return (size() == 0); }
372 
373  /// Return a const_iterator that references the first character of
374  /// the string.
375  const_iterator begin() const { return string().begin(); }
376 
377  /// Return a const_iterator that references the end of a traversal
378  /// of the characters of the string.
379  const_iterator end() const { return string().end(); }
380 
381  /// Return a const_reverse_iterator that references the last
382  /// character of the string.
383  const_reverse_iterator rbegin() const { return string().rbegin(); }
384 
385  /// Return a const_reverse_iterator that references the end of
386  /// a reverse traversal of the characters of the string.
387  const_reverse_iterator rend() const { return string().rend(); }
388 
389  /// Return a reference to the character at the given position.
390  /// Note that it's up to the caller to be sure pos is within the
391  /// size of the string.
392  const_reference operator[](size_type pos) const { return c_str()[pos]; }
393 
394  /// Dump into character array s the characters of this ustring,
395  /// beginning with position pos and copying at most n characters.
396  size_type copy(char* s, size_type n, size_type pos = 0) const
397  {
398  if (m_chars == nullptr) {
399  s[0] = 0;
400  return 0;
401  }
402  char* c = strncpy(s, c_str() + pos, n);
403  return (size_type)(c - s);
404  }
405 
406  /// Returns a substring of the ustring object consisting of n
407  /// characters starting at position pos.
408  ustring substr(size_type pos = 0, size_type n = npos) const
409  {
410  return ustring(*this, pos, n);
411  }
412 
413  // FIXME: implement compare.
414 
415  size_type find(const ustring& str, size_type pos = 0) const
416  {
417  return string().find(str.string(), pos);
418  }
419 
420  size_type find(const std::string& str, size_type pos = 0) const
421  {
422  return string().find(str, pos);
423  }
424 
425  size_type find(const char* s, size_type pos, size_type n) const
426  {
427  return string().find(s, pos, n);
428  }
429 
430  size_type find(const char* s, size_type pos = 0) const
431  {
432  return string().find(s, pos);
433  }
434 
435  size_type find(char c, size_type pos = 0) const
436  {
437  return string().find(c, pos);
438  }
439 
440  size_type rfind(const ustring& str, size_type pos = npos) const
441  {
442  return string().rfind(str.string(), pos);
443  }
444 
445  size_type rfind(const std::string& str, size_type pos = npos) const
446  {
447  return string().rfind(str, pos);
448  }
449 
450  size_type rfind(const char* s, size_type pos, size_type n) const
451  {
452  return string().rfind(s, pos, n);
453  }
454 
455  size_type rfind(const char* s, size_type pos = npos) const
456  {
457  return string().rfind(s, pos);
458  }
459 
460  size_type rfind(char c, size_type pos = npos) const
461  {
462  return string().rfind(c, pos);
463  }
464 
465  size_type find_first_of(const ustring& str, size_type pos = 0) const
466  {
467  return string().find_first_of(str.string(), pos);
468  }
469 
470  size_type find_first_of(const std::string& str, size_type pos = 0) const
471  {
472  return string().find_first_of(str, pos);
473  }
474 
475  size_type find_first_of(const char* s, size_type pos, size_type n) const
476  {
477  return string().find_first_of(s, pos, n);
478  }
479 
480  size_type find_first_of(const char* s, size_type pos = 0) const
481  {
482  return string().find_first_of(s, pos);
483  }
484 
485  size_type find_first_of(char c, size_type pos = 0) const
486  {
487  return string().find_first_of(c, pos);
488  }
489 
490  size_type find_last_of(const ustring& str, size_type pos = npos) const
491  {
492  return string().find_last_of(str.string(), pos);
493  }
494 
495  size_type find_last_of(const std::string& str, size_type pos = npos) const
496  {
497  return string().find_last_of(str, pos);
498  }
499 
500  size_type find_last_of(const char* s, size_type pos, size_type n) const
501  {
502  return string().find_last_of(s, pos, n);
503  }
504 
505  size_type find_last_of(const char* s, size_type pos = npos) const
506  {
507  return string().find_last_of(s, pos);
508  }
509 
510  size_type find_last_of(char c, size_type pos = npos) const
511  {
512  return string().find_last_of(c, pos);
513  }
514 
515  size_type find_first_not_of(const ustring& str, size_type pos = 0) const
516  {
517  return string().find_first_not_of(str.string(), pos);
518  }
519 
521  {
522  return string().find_first_not_of(str, pos);
523  }
524 
526  {
527  return string().find_first_not_of(s, pos, n);
528  }
529 
530  size_type find_first_not_of(const char* s, size_type pos = 0) const
531  {
532  return string().find_first_not_of(s, pos);
533  }
534 
535  size_type find_first_not_of(char c, size_type pos = 0) const
536  {
537  return string().find_first_not_of(c, pos);
538  }
539 
540  size_type find_last_not_of(const ustring& str, size_type pos = npos) const
541  {
542  return string().find_last_not_of(str.string(), pos);
543  }
544 
546  size_type pos = npos) const
547  {
548  return string().find_last_not_of(str, pos);
549  }
550 
551  size_type find_last_not_of(const char* s, size_type pos, size_type n) const
552  {
553  return string().find_last_not_of(s, pos, n);
554  }
555 
556  size_type find_last_not_of(const char* s, size_type pos = npos) const
557  {
558  return string().find_last_not_of(s, pos);
559  }
560 
561  size_type find_last_not_of(char c, size_type pos = npos) const
562  {
563  return string().find_last_not_of(c, pos);
564  }
565 
566  /// Return 0 if *this is lexicographically equal to str, -1 if
567  /// *this is lexicographically earlier than str, 1 if *this is
568  /// lexicographically after str.
569 
570  int compare(const ustring& str) const
571  {
572  return (c_str() == str.c_str())
573  ? 0
574  : strcmp(c_str() ? c_str() : "",
575  str.c_str() ? str.c_str() : "");
576  }
577 
578  /// Return 0 if *this is lexicographically equal to str, -1 if
579  /// *this is lexicographically earlier than str, 1 if *this is
580  /// lexicographically after str.
581  int compare(const std::string& str) const
582  {
583  return strcmp(c_str() ? c_str() : "", str.c_str());
584  }
585 
586  /// Return 0 if *this is lexicographically equal to str, -1 if
587  /// *this is lexicographically earlier than str, 1 if *this is
588  /// lexicographically after str.
589  int compare(string_view str) const
590  {
591  return string_view(*this).compare(str);
592  }
593 
594  /// Return 0 if *this is lexicographically equal to str, -1 if
595  /// *this is lexicographically earlier than str, 1 if *this is
596  /// lexicographically after str.
597  int compare(const char* str) const
598  {
599  return strcmp(c_str() ? c_str() : "", str ? str : "");
600  }
601 
602  /// Return 0 if a is lexicographically equal to b, -1 if a is
603  /// lexicographically earlier than b, 1 if a is lexicographically
604  /// after b.
605  friend int compare(const std::string& a, const ustring& b)
606  {
607  return string_view(a).compare(b);
608  }
609 
610  /// Test two ustrings for equality -- are they comprised of the same
611  /// sequence of characters. Note that because ustrings are unique,
612  /// this is a trivial pointer comparison, not a char-by-char loop as
613  /// would be the case with a char* or a std::string.
614  bool operator==(const ustring& str) const { return c_str() == str.c_str(); }
615 
616  /// Test two ustrings for inequality -- are they comprised of different
617  /// sequences of characters. Note that because ustrings are unique,
618  /// this is a trivial pointer comparison, not a char-by-char loop as
619  /// would be the case with a char* or a std::string.
620  bool operator!=(const ustring& str) const { return c_str() != str.c_str(); }
621 
622  /// Test a ustring (*this) for lexicographic equality with std::string
623  /// x.
624  bool operator==(const std::string& x) const { return compare(x) == 0; }
625 
626  /// Test a ustring (*this) for lexicographic equality with string_view
627  /// x.
628  bool operator==(string_view x) const { return compare(x) == 0; }
629 
630  /// Test a ustring (*this) for lexicographic equality with char* x.
631  bool operator==(const char* x) const { return compare(x) == 0; }
632 
633  /// Test for lexicographic equality between std::string a and ustring
634  /// b.
635  friend bool operator==(const std::string& a, const ustring& b)
636  {
637  return b.compare(a) == 0;
638  }
639 
640  /// Test for lexicographic equality between string_view a and ustring
641  /// b.
642  friend bool operator==(string_view a, const ustring& b)
643  {
644  return b.compare(a) == 0;
645  }
646 
647  /// Test for lexicographic equality between char* a and ustring
648  /// b.
649  friend bool operator==(const char* a, const ustring& b)
650  {
651  return b.compare(a) == 0;
652  }
653 
654  /// Test a ustring (*this) for lexicographic inequality with
655  /// std::string x.
656  bool operator!=(const std::string& x) const { return compare(x) != 0; }
657 
658  /// Test a ustring (*this) for lexicographic inequality with
659  /// string_view x.
660  bool operator!=(string_view x) const { return compare(x) != 0; }
661 
662  /// Test a ustring (*this) for lexicographic inequality with
663  /// char* x.
664  bool operator!=(const char* x) const { return compare(x) != 0; }
665 
666  /// Test for lexicographic inequality between std::string a and
667  /// ustring b.
668  friend bool operator!=(const std::string& a, const ustring& b)
669  {
670  return b.compare(a) != 0;
671  }
672 
673  /// Test for lexicographic inequality between string_view a and
674  /// ustring b.
675  friend bool operator!=(string_view a, const ustring& b)
676  {
677  return b.compare(a) != 0;
678  }
679 
680  /// Test for lexicographic inequality between char* a and
681  /// ustring b.
682  friend bool operator!=(const char* a, const ustring& b)
683  {
684  return b.compare(a) != 0;
685  }
686 
687  /// Test for lexicographic 'less', comes in handy for lots of STL
688  /// containers and algorithms.
689  bool operator<(const ustring& x) const { return compare(x) < 0; }
690 
691  /// Construct a ustring in a printf-like fashion. In other words,
692  /// something like:
693  /// ustring s = ustring::sprintf("blah %d %g", (int)foo, (float)bar);
694  /// The argument list is fully typesafe.
695  /// The formatting of the string will always use the classic "C" locale
696  /// conventions (in particular, '.' as decimal separator for float values).
697  template<typename... Args>
698  static ustring sprintf(const char* fmt, const Args&... args)
699  {
700  return ustring(Strutil::sprintf(fmt, args...));
701  }
702 
703  /// Construct a ustring in a fmt::format-like fashion. In other words,
704  /// something like:
705  /// ustring s = ustring::fmtformat("blah {} {}", (int)foo, (float)bar);
706  /// The argument list is fully typesafe.
707  /// The formatting of the string will always use the classic "C" locale
708  /// conventions (in particular, '.' as decimal separator for float values).
709  template<typename... Args>
710  static ustring fmtformat(const char* fmt, const Args&... args)
711  {
712  return ustring(Strutil::fmt::format(fmt, args...));
713  }
714 
715  /// NOTE: Semi-DEPRECATED! This will someday switch to behave like
716  /// fmt::format (or future std::format) but for now, it is back
717  /// compatible and equivalent to sprintf.
718  template<typename... Args>
719  static ustring format(const char* fmt, const Args&... args)
720  {
721  return ustring(Strutil::format(fmt, args...));
722  }
723 
724  /// Generic stream output of a ustring.
725  ///
726  friend std::ostream& operator<<(std::ostream& out, const ustring& str)
727  {
728  if (str.c_str() && out.good())
729  out.write(str.c_str(), str.size());
730  return out;
731  }
732 
733  /// Return the statistics output as a string.
734  ///
735  static std::string getstats(bool verbose = true);
736 
737  /// Return the amount of memory consumed by the ustring table.
738  ///
739  static size_t memory();
740 
741  /// Given a string_view, return a pointer to the unique
742  /// version kept in the internal table (creating a new table entry
743  /// if we haven't seen this sequence of characters before).
744  /// N.B.: this is equivalent to ustring(str).c_str(). It's also the
745  /// routine that is used directly by ustring's internals to generate
746  /// the canonical unique copy of the characters.
747  static const char* make_unique(string_view str);
748 
749  /// Is this character pointer a unique ustring representation of
750  /// those characters? Useful for diagnostics and debugging.
751  static bool is_unique(const char* str)
752  {
753  return str == nullptr || make_unique(str) == str;
754  }
755 
756  /// Create a ustring from characters guaranteed to already be
757  /// ustring-clean, without having to run through the hash yet
758  /// again. Use with extreme caution!!!
759  static ustring from_unique(const char* unique)
760  {
761  DASSERT(is_unique(unique)); // DEBUG builds -- check it!
762  ustring u;
763  u.m_chars = unique;
764  return u;
765  }
766 
767 private:
768  // Individual ustring internal representation -- the unique characters.
769  //
770  const char* m_chars;
771 
772 public:
773  // Representation within the hidden string table -- DON'T EVER CREATE
774  // ONE OF THESE YOURSELF!
775  // The characters are found directly after the rep. So that means that
776  // if you know the rep, the chars are at (char *)(rep+1), and if you
777  // know the chars, the rep is at ((TableRep *)chars - 1).
778  struct TableRep {
779  size_t hashed; // precomputed Hash value
780  std::string str; // String representation
781  size_t length; // Length of the string; must be right before cap
782  size_t dummy_capacity; // Dummy field! must be right before refcount
783  int dummy_refcount; // Dummy field! must be right before chars
784  TableRep(string_view strref, size_t hash);
785  ~TableRep();
786  const char* c_str() const { return (const char*)(this + 1); }
787  };
788 
789 private:
790  static std::string empty_std_string;
791 };
792 
793 
794 
795 /// Functor class to use as a hasher when you want to make a hash_map or
796 /// hash_set using ustring as a key.
797 class ustringHash {
798 public:
799  size_t operator()(const ustring& s) const { return s.hash(); }
800 };
801 
802 
803 
804 /// Functor class to use for comparisons when sorting ustrings, if you
805 /// want the strings sorted lexicographically.
806 class ustringLess {
807 public:
808  size_t operator()(ustring a, ustring b) const { return a < b; }
809 };
810 
811 
812 /// Functor class to use for comparisons when sorting ustrings, if you
813 /// don't care if the sort order is lexicographic. This sorts based on
814 /// the pointers themselves, which is safe because once allocated, a
815 /// ustring's characters will never be moved. But beware, the resulting
816 /// sorting order may vary from run to run!
818 public:
819  size_t operator()(ustring a, ustring b) const
820  {
821  return size_t(a.data()) < size_t(b.data());
822  }
823 };
824 
825 
826 
827 /// Case-insensitive comparison of ustrings. For speed, this always
828 /// uses a static locale that doesn't require a mutex lock.
829 inline bool
831 {
832  return a == b || Strutil::iequals(a.string(), b.string());
833 }
834 
835 inline bool
837 {
838  return Strutil::iequals(a.string(), b);
839 }
840 
841 inline bool
843 {
844  return Strutil::iequals(a, b.string());
845 }
846 
847 
848 
849 // ustring variant stof from OpenImageIO/strutil.h
850 namespace Strutil {
851 
852 inline float
854 {
855  return Strutil::stof(s.string());
856 }
857 
858 template<>
859 inline std::string
861 {
862  return value.string();
863 }
864 
865 } // end namespace Strutil
866 
const ustring & assign(const char *str)
Definition: ustring.h:266
GLdouble s
Definition: glew.h:1390
std::string::const_iterator const_iterator
Definition: ustring.h:153
friend bool operator!=(const char *a, const ustring &b)
Definition: ustring.h:682
const char * c_str() const
Definition: ustring.h:786
std::string sprintf(const char *fmt, const Args &...args)
Definition: strutil.h:136
value_type * pointer
Definition: ustring.h:148
size_type find_last_of(const char *s, size_type pos, size_type n) const
Definition: ustring.h:500
size_type find_first_of(const std::string &str, size_type pos=0) const
Definition: ustring.h:470
~ustring()
Definition: ustring.h:226
char value_type
Definition: ustring.h:147
GLsizeiptr size
Definition: glew.h:1681
size_type find(const char *s, size_type pos=0) const
Definition: ustring.h:430
friend bool operator==(const char *a, const ustring &b)
Definition: ustring.h:649
size_type copy(char *s, size_type n, size_type pos=0) const
Definition: ustring.h:396
const_reference operator[](size_type pos) const
Definition: ustring.h:392
const ustring & assign(string_view str)
Assign a string_view to *this.
Definition: ustring.h:289
bool operator!=(string_view x) const
Definition: ustring.h:660
const value_type & const_reference
Definition: ustring.h:150
size_type find_first_of(const char *s, size_type pos, size_type n) const
Definition: ustring.h:475
ustring(void)
Definition: ustring.h:158
int compare(const std::string &str) const
Definition: ustring.h:581
const Args & args
Definition: printf.h:628
const_reverse_iterator rend() const
Definition: ustring.h:387
friend bool operator==(const std::string &a, const ustring &b)
Definition: ustring.h:635
size_type rfind(const char *s, size_type pos=npos) const
Definition: ustring.h:455
static bool is_unique(const char *str)
Definition: ustring.h:751
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:9477
std::string format(const char *fmt, const Args &...args)
Definition: strutil.h:182
value_type & reference
Definition: ustring.h:149
const ustring & operator=(const char *str)
Definition: ustring.h:301
std::string to_string(const T &value)
Definition: strutil.h:512
size_type find_first_not_of(const std::string &str, size_type pos=0) const
Definition: ustring.h:520
void clear(void)
Definition: ustring.h:343
const std::string & string() const
Definition: ustring.h:332
ustring(size_type n, char c)
Definition: ustring.h:194
const ustring & operator=(char c)
Definition: ustring.h:313
ustring substr(size_type pos=0, size_type n=npos) const
Definition: ustring.h:408
friend bool operator==(string_view a, const ustring &b)
Definition: ustring.h:642
const ustring & assign(const std::string &str, size_type pos, size_type n=npos)
Definition: ustring.h:257
String-related utilities, all in namespace Strutil.
const ustring & operator=(string_view str)
Definition: ustring.h:309
int compare(const char *str) const
Definition: ustring.h:597
ustring(const std::string &str, size_type pos, size_type n=npos)
Definition: ustring.h:201
int compare(string_view str) const
Definition: ustring.h:589
const charT * data() const
Definition: string_view.h:176
int compare(const ustring &str) const
Definition: ustring.h:570
size_type find_last_of(const std::string &str, size_type pos=npos) const
Definition: ustring.h:495
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, ROI roi={}, int nthreads=0)
size_type find_last_not_of(const char *s, size_type pos, size_type n) const
Definition: ustring.h:551
friend bool operator!=(string_view a, const ustring &b)
Definition: ustring.h:675
static ustring fmtformat(const char *fmt, const Args &...args)
Definition: ustring.h:710
#define DASSERT(x)
Definition: dassert.h:99
size_type rfind(char c, size_type pos=npos) const
Definition: ustring.h:460
GLint GLint GLint GLint GLint x
Definition: glew.h:1252
ustring(const char *str, size_type pos, size_type n)
Definition: ustring.h:180
size_type find_first_of(const char *s, size_type pos=0) const
Definition: ustring.h:480
friend std::ostream & operator<<(std::ostream &out, const ustring &str)
Definition: ustring.h:726
std::string str
Definition: ustring.h:780
size_type find_first_not_of(const char *s, size_type pos, size_type n) const
Definition: ustring.h:525
size_type find_first_of(const ustring &str, size_type pos=0) const
Definition: ustring.h:465
size_type rfind(const char *s, size_type pos, size_type n) const
Definition: ustring.h:450
const ustring & assign(const char *str, size_type n)
Definition: ustring.h:274
size_type find(const char *s, size_type pos, size_type n) const
Definition: ustring.h:425
static ustring sprintf(const char *fmt, const Args &...args)
Definition: ustring.h:698
size_t hash(void) const
Definition: ustring.h:357
basic_string_view< char > string_view
Definition: core.h:426
const_iterator begin() const
Definition: ustring.h:375
const ustring & assign(size_type n, char c)
Definition: ustring.h:282
GLsizei n
Definition: glew.h:4040
const GLfloat * c
Definition: glew.h:16296
GLuint GLsizei GLsizei * length
Definition: glew.h:1825
size_type rfind(const ustring &str, size_type pos=npos) const
Definition: ustring.h:440
size_type find_last_not_of(char c, size_type pos=npos) const
Definition: ustring.h:561
size_t length(void) const
Definition: ustring.h:347
friend int compare(const std::string &a, const ustring &b)
Definition: ustring.h:605
size_type find_last_of(char c, size_type pos=npos) const
Definition: ustring.h:510
ustring(const ustring &str, size_type pos, size_type n=npos)
Definition: ustring.h:217
bool OIIO_API iequals(string_view a, string_view b)
bool operator==(const char *x) const
Test a ustring (this) for lexicographic equality with char x.
Definition: ustring.h:631
ustring(const char *str)
Definition: ustring.h:165
size_type rfind(const std::string &str, size_type pos=npos) const
Definition: ustring.h:445
const ustring & assign(const ustring &str)
Definition: ustring.h:233
size_t size_type
Definition: ustring.h:151
const_iterator end() const
Definition: ustring.h:379
const ustring & assign(const std::string &str)
Definition: ustring.h:249
size_type find_first_not_of(const ustring &str, size_type pos=0) const
Definition: ustring.h:515
size_type find_last_of(const ustring &str, size_type pos=npos) const
Definition: ustring.h:490
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
I unique(I begin, I end)
Definition: pugixml.cpp:7195
ustring(const char *str, size_type n)
Definition: ustring.h:187
GLsizei const GLchar *const * string
Definition: glew.h:1844
const ustring & assign(const ustring &str, size_type pos, size_type n=npos)
Definition: ustring.h:241
bool operator<(const ustring &x) const
Definition: ustring.h:689
size_type find_last_of(const char *s, size_type pos=npos) const
Definition: ustring.h:505
size_t operator()(ustring a, ustring b) const
Definition: ustring.h:819
size_t operator()(const ustring &s) const
Definition: ustring.h:799
friend bool operator!=(const std::string &a, const ustring &b)
Definition: ustring.h:668
size_type find(const std::string &str, size_type pos=0) const
Definition: ustring.h:420
size_t dummy_capacity
Definition: ustring.h:782
static ustring format(const char *fmt, const Args &...args)
Definition: ustring.h:719
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: glew.h:1254
size_type length() const
Definition: string_view.h:162
const char * data() const
Definition: ustring.h:328
ustring(const ustring &str)
Definition: ustring.h:210
bool iequals(ustring a, ustring b)
Definition: ustring.h:830
bool operator==(const ustring &str) const
Definition: ustring.h:614
size_type find_last_not_of(const ustring &str, size_type pos=npos) const
Definition: ustring.h:540
size_t operator()(ustring a, ustring b) const
Definition: ustring.h:808
string_view substr(size_type pos, size_type n=npos) const
Definition: string_view.h:194
bool operator!=(const ustring &str) const
Definition: ustring.h:620
int compare(basic_string_view other) const
Definition: core.h:398
size_type find_first_of(char c, size_type pos=0) const
Definition: ustring.h:485
bool empty(void) const
Definition: ustring.h:371
bool operator!=(const std::string &x) const
Definition: ustring.h:656
static ustring from_unique(const char *unique)
Definition: ustring.h:759
size_type find_first_not_of(char c, size_type pos=0) const
Definition: ustring.h:535
bool operator!=(const char *x) const
Definition: ustring.h:664
const_reverse_iterator rbegin() const
Definition: ustring.h:383
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:66
size_type find(const ustring &str, size_type pos=0) const
Definition: ustring.h:415
size_type find_first_not_of(const char *s, size_type pos=0) const
Definition: ustring.h:530
size_type find_last_not_of(const char *s, size_type pos=npos) const
Definition: ustring.h:556
std::string::const_reverse_iterator const_reverse_iterator
Definition: ustring.h:154
bool operator==(string_view x) const
Definition: ustring.h:628
OIIO_API float stof(string_view s, size_t *pos=0)
GLsizei const GLfloat * value
Definition: glew.h:1849
size_type find(char c, size_type pos=0) const
Definition: ustring.h:435
const char * c_str() const
Definition: ustring.h:324
ustring(string_view str)
Definition: ustring.h:173
size_type find_last_not_of(const std::string &str, size_type pos=npos) const
Definition: ustring.h:545
bool operator==(const std::string &x) const
Definition: ustring.h:624
const ustring & operator=(const ustring &str)
Definition: ustring.h:297
size_t size(void) const
Definition: ustring.h:367
const ustring & operator=(const std::string &str)
Definition: ustring.h:305
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:65
#define OIIO_API
Definition: export.h:91