HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ustring.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: Apache-2.0
3 // https://github.com/AcademySoftwareFoundation/OpenImageIO
4 
5 
6 #pragma once
7 #define OPENIMAGEIO_USTRING_H
8 
9 #if defined(_MSC_VER)
10 // Ignore warnings about DLL exported classes with member variables that are template classes.
11 // This happens with the std::string empty_std_string static member variable of ustring below.
12 // Also remove a warning about the strncpy function not being safe and deprecated in MSVC.
13 // There is no equivalent safe and portable function and trying to fix this is more trouble than
14 // its worth. (see http://stackoverflow.com/questions/858252/alternatives-to-ms-strncpy-s)
15 # pragma warning(disable : 4251 4996)
16 #endif
17 
18 #include <OpenImageIO/dassert.h>
19 #include <OpenImageIO/export.h>
22 #include <OpenImageIO/strutil.h>
23 #include <cstring>
24 #include <iostream>
25 #include <string>
26 
27 
29 
30 // Feature tests
31 #define OIIO_USTRING_HAS_USTRINGHASH 1
32 #define OIIO_USTRING_HAS_CTR_FROM_USTRINGHASH 1
33 #define OIIO_USTRING_HAS_STDHASH 1
34 #define OIIO_HAS_USTRINGHASH_FORMATTER 1
35 
36 
37 class ustringhash; // forward declaration
38 
39 
40 
41 /// A ustring is an alternative to char* or std::string for storing
42 /// strings, in which the character sequence is unique (allowing many
43 /// speed advantages for assignment, equality testing, and inequality
44 /// testing).
45 ///
46 /// The implementation is that behind the scenes there is a hash set of
47 /// allocated strings, so the characters of each string are unique. A
48 /// ustring itself is a pointer to the characters of one of these canonical
49 /// strings. Therefore, assignment and equality testing is just a single
50 /// 32- or 64-bit int operation, the only mutex is when a ustring is
51 /// created from raw characters, and the only malloc is the first time
52 /// each canonical ustring is created.
53 ///
54 /// The internal table also contains a std::string version and the length
55 /// of the string, so converting a ustring to a std::string (via
56 /// ustring::string()) or querying the number of characters (via
57 /// ustring::size() or ustring::length()) is extremely inexpensive, and does
58 /// not involve creation/allocation of a new std::string or a call to
59 /// strlen.
60 ///
61 /// We try very hard to completely mimic the API of std::string,
62 /// including all the constructors, comparisons, iterations, etc. Of
63 /// course, the characters of a ustring are non-modifiable, so we do not
64 /// replicate any of the non-const methods of std::string. But in most
65 /// other ways it looks and acts like a std::string and so most templated
66 /// algorithms that would work on a "const std::string &" will also work
67 /// on a ustring.
68 ///
69 /// Note that like a `char*`, but unlike a `std::string`, a ustring is not
70 /// allowed to contain any embedded NUL ('\0') characters. When constructing
71 /// ustrings from a std::string or a string_view, the contents will be
72 /// truncated at the point of any NUL character. This is done to ensure that
73 /// ustring::c_str() refers to the same C-style character sequence as the
74 /// ustring itself or ustring::string().
75 ///
76 /// Usage guidelines:
77 ///
78 /// Compared to standard strings, ustrings have several advantages:
79 ///
80 /// - Each individual ustring is very small -- in fact, we guarantee that
81 /// a ustring is the same size and memory layout as an ordinary char*.
82 /// - Storage is frugal, since there is only one allocated copy of each
83 /// unique character sequence, throughout the lifetime of the program.
84 /// - Assignment from one ustring to another is just copy of the pointer;
85 /// no allocation, no character copying, no reference counting.
86 /// - Equality testing (do the strings contain the same characters) is
87 /// a single operation, the comparison of the pointer.
88 /// - Memory allocation only occurs when a new ustring is constructed from
89 /// raw characters the FIRST time -- subsequent constructions of the
90 /// same string just finds it in the canonical string set, but doesn't
91 /// need to allocate new storage. Destruction of a ustring is trivial,
92 /// there is no de-allocation because the canonical version stays in
93 /// the set. Also, therefore, no user code mistake can lead to
94 /// memory leaks.
95 ///
96 /// But there are some problems, too. Canonical strings are never freed
97 /// from the table. So in some sense all the strings "leak", but they
98 /// only leak one copy for each unique string that the program ever comes
99 /// across. Also, creation of unique strings from raw characters is more
100 /// expensive than for standard strings, due to hashing, table queries,
101 /// and other overhead.
102 ///
103 /// On the whole, ustrings are a really great string representation
104 /// - if you tend to have (relatively) few unique strings, but many
105 /// copies of those strings;
106 /// - if the creation of strings from raw characters is relatively
107 /// rare compared to copying or comparing to existing strings;
108 /// - if you tend to make the same strings over and over again, and
109 /// if it's relatively rare that a single unique character sequence
110 /// is used only once in the entire lifetime of the program;
111 /// - if your most common string operations are assignment and equality
112 /// testing and you want them to be as fast as possible;
113 /// - if you are doing relatively little character-by-character assembly
114 /// of strings, string concatenation, or other "string manipulation"
115 /// (other than equality testing).
116 ///
117 /// ustrings are not so hot
118 /// - if your program tends to have very few copies of each character
119 /// sequence over the entire lifetime of the program;
120 /// - if your program tends to generate a huge variety of unique
121 /// strings over its lifetime, each of which is used only a short
122 /// time and then discarded, never to be needed again;
123 /// - if you don't need to do a lot of string assignment or equality
124 /// testing, but lots of more complex string manipulation.
125 ///
127 public:
128  using rep_t = const char*; ///< The underlying representation type
129  using value_type = char;
130  using hash_t = uint64_t; ///< The hash type
131  using pointer = value_type*;
133  using const_reference = const value_type&;
134  using size_type = size_t;
135  static const size_type npos = static_cast<size_type>(-1);
136  using const_iterator = std::string::const_iterator;
137  using const_reverse_iterator = std::string::const_reverse_iterator;
138 
139  /// Default ctr for ustring -- make an empty string.
140  constexpr ustring() noexcept
141  : m_chars(nullptr)
142  {
143  }
144 
145  /// Construct a ustring from a null-terminated C string (char *).
146  explicit ustring(const char* str)
147  {
148  m_chars = str ? make_unique(str) : nullptr;
149  }
150 
151  /// Construct a ustring from a string_view, which can be auto-converted
152  /// from either a null-terminated C string (char *) or a C++
153  /// std::string.
154  explicit ustring(string_view str)
155  {
156  m_chars = str.data() ? make_unique(str) : nullptr;
157  }
158 
159  /// Construct a ustring from at most n characters of str, starting at
160  /// position pos.
161  ustring(const char* str, size_type pos, size_type n)
162  : m_chars(make_unique(std::string(str, pos, n).c_str()))
163  {
164  }
165 
166  /// Construct a ustring from the first n characters of str.
167  ustring(const char* str, size_type n)
168  : m_chars(make_unique(string_view(str, n)))
169  {
170  }
171 
172  /// Construct a ustring from n copies of character c.
174  : m_chars(make_unique(std::string(n, c).c_str()))
175  {
176  }
177 
178  /// Construct a ustring from an indexed substring of a std::string.
179  ustring(const std::string& str, size_type pos, size_type n = npos)
180  {
181  string_view sref(str);
182  sref = sref.substr(pos, n);
183  m_chars = make_unique(sref);
184  }
185 
186  /// Copy construct a ustring from another ustring.
187  ustring(const ustring& str) noexcept
188  : m_chars(str.m_chars)
189  {
190  }
191 
192  /// Construct a ustring from an indexed substring of a ustring.
193  ustring(const ustring& str, size_type pos, size_type n = npos)
194  {
195  string_view sref(str);
196  sref = sref.substr(pos, n);
197  m_chars = make_unique(sref);
198  }
199 
200 #ifndef __CUDA_ARCH__
201  /// Construct from a known ustringhash
202  inline explicit ustring(ustringhash hash);
203 #endif
204 
205  /// ustring destructor.
206  ~ustring() noexcept {}
207 
208  /// Conversion to an OIIO::string_view.
209  operator string_view() const noexcept { return { c_str(), length() }; }
210 
211  /// Conversion to std::string (explicit only!).
212  explicit operator std::string() const noexcept { return string(); }
213 
214  /// Assign a ustring to *this.
215  const ustring& assign(const ustring& str)
216  {
217  m_chars = str.m_chars;
218  return *this;
219  }
220 
221  /// Assign a substring of a ustring to *this.
222  const ustring& assign(const ustring& str, size_type pos, size_type n = npos)
223  {
224  *this = ustring(str, pos, n);
225  return *this;
226  }
227 
228  /// Assign a std::string to *this.
229  const ustring& assign(const std::string& str)
230  {
231  assign(str.c_str());
232  return *this;
233  }
234 
235  /// Assign a substring of a std::string to *this.
236  const ustring& assign(const std::string& str, size_type pos,
237  size_type n = npos)
238  {
239  *this = ustring(str, pos, n);
240  return *this;
241  }
242 
243  /// Assign a null-terminated C string (char*) to *this.
244  const ustring& assign(const char* str)
245  {
246  m_chars = str ? make_unique(str) : nullptr;
247  return *this;
248  }
249 
250  /// Assign the first n characters of str to *this.
251  const ustring& assign(const char* str, size_type n)
252  {
253  *this = ustring(str, n);
254  return *this;
255  }
256 
257  /// Assign n copies of c to *this.
258  const ustring& assign(size_type n, char c)
259  {
260  *this = ustring(n, c);
261  return *this;
262  }
263 
264  /// Assign a string_view to *this.
266  {
267  m_chars = str.length() ? make_unique(str) : nullptr;
268  return *this;
269  }
270 
271  /// Assign a ustring to another ustring.
272  const ustring& operator=(const ustring& str) { return assign(str); }
273 
274  /// Assign a null-terminated C string (char *) to a ustring.
275  const ustring& operator=(const char* str) { return assign(str); }
276 
277  /// Assign a C++ std::string to a ustring.
278  const ustring& operator=(const std::string& str) { return assign(str); }
279 
280  /// Assign a string_view to a ustring.
281  const ustring& operator=(string_view str) { return assign(str); }
282 
283  /// Assign a single char to a ustring.
284  const ustring& operator=(char c)
285  {
286  return *this = ustring(string_view(&c, 1));
287  }
288 
289  /// Return a C string representation of a ustring.
290  const char* c_str() const noexcept { return m_chars; }
291 
292  /// Return a C string representation of a ustring.
293  const char* data() const noexcept { return c_str(); }
294 
295  /// Return a C++ std::string representation of a ustring.
296  const std::string& string() const noexcept
297  {
298  if (m_chars) {
299  const TableRep* rep = (const TableRep*)m_chars - 1;
300  return rep->str;
301  } else
302  return empty_std_string;
303  }
304 
305  /// Reset to an empty string.
306  void clear() noexcept { m_chars = nullptr; }
307 
308  /// Return the number of characters in the string.
309  size_t length() const noexcept
310  {
311  if (!m_chars)
312  return 0;
313  const TableRep* rep = ((const TableRep*)m_chars) - 1;
314  return rep->length;
315  }
316 
317  /// Return a hashed version of the string
318  hash_t hash() const noexcept
319  {
320  if (!m_chars)
321  return 0;
322  const TableRep* rep = ((const TableRep*)m_chars) - 1;
323  return rep->hashed;
324  }
325 
326  /// Return a hashed version of the string
327  ustringhash uhash() const noexcept;
328 
329  /// Return the number of characters in the string.
330  size_t size() const noexcept { return length(); }
331 
332  /// Is the string empty -- i.e., is it nullptr or does it point to an
333  /// empty string?
334  bool empty() const noexcept { return (size() == 0); }
335 
336  /// Return a const_iterator that references the first character of
337  /// the string.
338  const_iterator begin() const noexcept { return string().begin(); }
339 
340  /// Return a const_iterator that references the end of a traversal
341  /// of the characters of the string.
342  const_iterator end() const noexcept { return string().end(); }
343 
344  /// Return a const_reverse_iterator that references the last
345  /// character of the string.
346  const_reverse_iterator rbegin() const noexcept { return string().rbegin(); }
347 
348  /// Return a const_reverse_iterator that references the end of
349  /// a reverse traversal of the characters of the string.
350  const_reverse_iterator rend() const noexcept { return string().rend(); }
351 
352  /// Return a reference to the character at the given position.
353  /// Note that it's up to the caller to be sure pos is within the
354  /// size of the string.
356  {
357  return c_str()[pos];
358  }
359 
360  /// Dump into character array s the characters of this ustring,
361  /// beginning with position pos and copying at most n characters.
362  size_type copy(char* s, size_type n, size_type pos = 0) const
363  {
364  if (m_chars == nullptr) {
365  s[0] = 0;
366  return 0;
367  }
368  char* c = strncpy(s, c_str() + pos, n); // NOSONAR
369  return (size_type)(c - s);
370  }
371 
372  /// Returns a substring of the ustring object consisting of n
373  /// characters starting at position pos.
374  ustring substr(size_type pos = 0, size_type n = npos) const
375  {
376  return ustring(*this, pos, n);
377  }
378 
379  size_type find(const ustring& str, size_type pos = 0) const noexcept
380  {
381  return string().find(str.string(), pos);
382  }
383 
384  size_type find(const std::string& str, size_type pos = 0) const noexcept
385  {
386  return string().find(str, pos);
387  }
388 
389  size_type find(const char* s, size_type pos, size_type n) const
390  {
391  return string().find(s, pos, n);
392  }
393 
394  size_type find(const char* s, size_type pos = 0) const
395  {
396  return string().find(s, pos);
397  }
398 
399  size_type find(char c, size_type pos = 0) const noexcept
400  {
401  return string().find(c, pos);
402  }
403 
404  size_type rfind(const ustring& str, size_type pos = npos) const noexcept
405  {
406  return string().rfind(str.string(), pos);
407  }
408 
409  size_type rfind(const std::string& str, size_type pos = npos) const noexcept
410  {
411  return string().rfind(str, pos);
412  }
413 
414  size_type rfind(const char* s, size_type pos, size_type n) const
415  {
416  return string().rfind(s, pos, n);
417  }
418 
419  size_type rfind(const char* s, size_type pos = npos) const
420  {
421  return string().rfind(s, pos);
422  }
423 
424  size_type rfind(char c, size_type pos = npos) const noexcept
425  {
426  return string().rfind(c, pos);
427  }
428 
430  size_type pos = 0) const noexcept
431  {
432  return string().find_first_of(str.string(), pos);
433  }
434 
435  size_type find_first_of(const std::string& str,
436  size_type pos = 0) const noexcept
437  {
438  return string().find_first_of(str, pos);
439  }
440 
441  size_type find_first_of(const char* s, size_type pos, size_type n) const
442  {
443  return string().find_first_of(s, pos, n);
444  }
445 
446  size_type find_first_of(const char* s, size_type pos = 0) const
447  {
448  return string().find_first_of(s, pos);
449  }
450 
451  size_type find_first_of(char c, size_type pos = 0) const noexcept
452  {
453  return string().find_first_of(c, pos);
454  }
455 
457  size_type pos = npos) const noexcept
458  {
459  return string().find_last_of(str.string(), pos);
460  }
461 
462  size_type find_last_of(const std::string& str,
463  size_type pos = npos) const noexcept
464  {
465  return string().find_last_of(str, pos);
466  }
467 
468  size_type find_last_of(const char* s, size_type pos, size_type n) const
469  {
470  return string().find_last_of(s, pos, n);
471  }
472 
473  size_type find_last_of(const char* s, size_type pos = npos) const
474  {
475  return string().find_last_of(s, pos);
476  }
477 
478  size_type find_last_of(char c, size_type pos = npos) const noexcept
479  {
480  return string().find_last_of(c, pos);
481  }
482 
484  size_type pos = 0) const noexcept
485  {
486  return string().find_first_not_of(str.string(), pos);
487  }
488 
489  size_type find_first_not_of(const std::string& str,
490  size_type pos = 0) const noexcept
491  {
492  return string().find_first_not_of(str, pos);
493  }
494 
496  {
497  return string().find_first_not_of(s, pos, n);
498  }
499 
500  size_type find_first_not_of(const char* s, size_type pos = 0) const
501  {
502  return string().find_first_not_of(s, pos);
503  }
504 
505  size_type find_first_not_of(char c, size_type pos = 0) const noexcept
506  {
507  return string().find_first_not_of(c, pos);
508  }
509 
511  size_type pos = npos) const noexcept
512  {
513  return string().find_last_not_of(str.string(), pos);
514  }
515 
516  size_type find_last_not_of(const std::string& str,
517  size_type pos = npos) const noexcept
518  {
519  return string().find_last_not_of(str, pos);
520  }
521 
522  size_type find_last_not_of(const char* s, size_type pos, size_type n) const
523  {
524  return string().find_last_not_of(s, pos, n);
525  }
526 
527  size_type find_last_not_of(const char* s, size_type pos = npos) const
528  {
529  return string().find_last_not_of(s, pos);
530  }
531 
532  size_type find_last_not_of(char c, size_type pos = npos) const noexcept
533  {
534  return string().find_last_not_of(c, pos);
535  }
536 
537  /// Return 0 if *this is lexicographically equal to str, -1 if
538  /// *this is lexicographically earlier than str, 1 if *this is
539  /// lexicographically after str.
540  int compare(string_view str) const noexcept
541  {
542  return string_view(*this).compare(str);
543  }
544 
545  /// Return 0 if *this is lexicographically equal to str, -1 if
546  /// *this is lexicographically earlier than str, 1 if *this is
547  /// lexicographically after str.
548  int compare(const char* str) const noexcept
549  {
550  return strcmp(c_str() ? c_str() : "", str ? str : "");
551  }
552 
553  /// Return 0 if a is lexicographically equal to b, -1 if a is
554  /// lexicographically earlier than b, 1 if a is lexicographically
555  /// after b.
556  friend int compare(const std::string& a, const ustring& b) noexcept
557  {
558  return string_view(a).compare(b);
559  }
560 
561  /// Test two ustrings for equality -- are they comprised of the same
562  /// sequence of characters. Note that because ustrings are unique,
563  /// this is a trivial pointer comparison, not a char-by-char loop as
564  /// would be the case with a char* or a std::string.
565  bool operator==(const ustring& str) const noexcept
566  {
567  return c_str() == str.c_str();
568  }
569 
570  /// Test two ustrings for inequality -- are they comprised of different
571  /// sequences of characters. Note that because ustrings are unique,
572  /// this is a trivial pointer comparison, not a char-by-char loop as
573  /// would be the case with a char* or a std::string.
574  bool operator!=(const ustring& str) const noexcept
575  {
576  return c_str() != str.c_str();
577  }
578 
579  /// Test a ustring (*this) for lexicographic equality with std::string
580  /// x.
581  bool operator==(const std::string& x) const noexcept
582  {
583  return compare(x) == 0;
584  }
585 
586  /// Test a ustring (*this) for lexicographic equality with string_view
587  /// x.
588  bool operator==(string_view x) const noexcept { return compare(x) == 0; }
589 
590  /// Test a ustring (*this) for lexicographic equality with char* x.
591  bool operator==(const char* x) const noexcept { return compare(x) == 0; }
592 
593  /// Test for lexicographic equality between std::string a and ustring
594  /// b.
595  friend bool operator==(const std::string& a, const ustring& b) noexcept
596  {
597  return b.compare(a) == 0;
598  }
599 
600  /// Test for lexicographic equality between string_view a and ustring
601  /// b.
602  friend bool operator==(string_view a, const ustring& b) noexcept
603  {
604  return b.compare(a) == 0;
605  }
606 
607  /// Test for lexicographic equality between char* a and ustring
608  /// b.
609  friend bool operator==(const char* a, const ustring& b) noexcept
610  {
611  return b.compare(a) == 0;
612  }
613 
614  /// Test a ustring (*this) for lexicographic inequality with
615  /// std::string x.
616  bool operator!=(const std::string& x) const noexcept
617  {
618  return compare(x) != 0;
619  }
620 
621  /// Test a ustring (*this) for lexicographic inequality with
622  /// string_view x.
623  bool operator!=(string_view x) const noexcept { return compare(x) != 0; }
624 
625  /// Test a ustring (*this) for lexicographic inequality with
626  /// char* x.
627  bool operator!=(const char* x) const noexcept { return compare(x) != 0; }
628 
629  /// Test for lexicographic inequality between std::string a and
630  /// ustring b.
631  friend bool operator!=(const std::string& a, const ustring& b) noexcept
632  {
633  return b.compare(a) != 0;
634  }
635 
636  /// Test for lexicographic inequality between string_view a and
637  /// ustring b.
638  friend bool operator!=(string_view a, const ustring& b) noexcept
639  {
640  return b.compare(a) != 0;
641  }
642 
643  /// Test for lexicographic inequality between char* a and
644  /// ustring b.
645  friend bool operator!=(const char* a, const ustring& b) noexcept
646  {
647  return b.compare(a) != 0;
648  }
649 
650  /// Test for lexicographic 'less', comes in handy for lots of STL
651  /// containers and algorithms.
652  bool operator<(const ustring& x) const noexcept { return compare(x) < 0; }
653 
654  /// Construct a ustring in a printf-like fashion. In other words,
655  /// something like:
656  /// ustring s = ustring::sprintf("blah %d %g", (int)foo, (float)bar);
657  /// The argument list is fully typesafe.
658  /// The formatting of the string will always use the classic "C" locale
659  /// conventions (in particular, '.' as decimal separator for float values).
660  template<typename... Args>
661  OIIO_NODISCARD static ustring sprintf(const char* fmt, const Args&... args)
662  {
663  return ustring(Strutil::sprintf(fmt, args...));
664  }
665 
666  /// Construct a ustring in a fmt::format-like fashion. In other words,
667  /// something like:
668  /// ustring s = ustring::fmtformat("blah {} {}", (int)foo, (float)bar);
669  /// The argument list is fully typesafe.
670  /// The formatting of the string will always use the classic "C" locale
671  /// conventions (in particular, '.' as decimal separator for float values).
672  template<typename... Args>
673  OIIO_NODISCARD static ustring fmtformat(const char* fmt,
674  const Args&... args)
675  {
676  return ustring(Strutil::fmt::format(fmt, args...));
677  }
678 
679  /// NOTE: Semi-DEPRECATED! This will someday switch to behave like
680  /// fmt::format (or future std::format) but for now, it is back
681  /// compatible and equivalent to sprintf.
682  template<typename... Args>
683  OIIO_FORMAT_DEPRECATED static ustring format(const char* fmt,
684  const Args&... args)
685  {
686  return ustring(Strutil::format(fmt, args...));
687  }
688 
689  /// Concatenate two strings, returning a ustring, implemented carefully
690  /// to not perform any redundant copies or allocations.
692 
693  /// Generic stream output of a ustring.
694  friend std::ostream& operator<<(std::ostream& out, const ustring& str)
695  {
696  if (str.c_str() && out.good())
697  out.write(str.c_str(), str.size());
698  return out;
699  }
700 
701  /// Return the statistics output as a string.
702  static std::string getstats(bool verbose = true);
703 
704  /// Return the amount of memory consumed by the ustring table.
705  static size_t memory();
706 
707  /// Return the total number of ustrings in the internal table.
708  static size_t total_ustrings();
709 
710  /// Return the total number ustrings that have the exact hash as another
711  /// ustring. If `collisions` is passed, store all the colliding ustrings
712  /// in the vector.
713  static size_t hash_collisions(std::vector<ustring>* collisions = nullptr);
714 
715  /// Given a string_view, return a pointer to the unique
716  /// version kept in the internal table (creating a new table entry
717  /// if we haven't seen this sequence of characters before).
718  /// N.B.: this is equivalent to ustring(str).c_str(). It's also the
719  /// routine that is used directly by ustring's internals to generate
720  /// the canonical unique copy of the characters.
721  static const char* make_unique(string_view str);
722 
723  /// Is this character pointer a unique ustring representation of
724  /// those characters? Useful for diagnostics and debugging.
725  static bool is_unique(const char* str)
726  {
727  return str == nullptr || make_unique(str) == str;
728  }
729 
730  /// Create a ustring from characters guaranteed to already be
731  /// ustring-clean, without having to run through the hash yet
732  /// again. Use with extreme caution!!!
733  static ustring from_unique(const char* unique)
734  {
735  OIIO_DASSERT(is_unique(unique)); // DEBUG builds -- check it!
736  ustring u;
737  u.m_chars = unique;
738  return u;
739  }
740 
741  /// Return the ustring corresponding to the given hash, or the empty
742  /// ustring() if there is no registered ustring with that hash. Note that
743  /// if there are multiple ustrings with the same hash, this will return
744  /// the first one it finds in the table.
745  OIIO_NODISCARD static ustring from_hash(hash_t hash);
746 
747 private:
748  // Individual ustring internal representation -- the unique characters.
749  //
750  rep_t m_chars;
751 
752 public:
753  // Representation within the hidden string table -- DON'T EVER CREATE
754  // ONE OF THESE YOURSELF!
755  // The characters are found directly after the rep. So that means that
756  // if you know the rep, the chars are at (char *)(rep+1), and if you
757  // know the chars, the rep is at ((TableRep *)chars - 1).
758  struct TableRep {
759  hash_t hashed; // precomputed Hash value
760  std::string str; // String representation
761  size_t length; // Length of the string; must be right before cap
762  size_t dummy_capacity; // Dummy field! must be right before refcount
763  int dummy_refcount; // Dummy field! must be right before chars
764  TableRep(string_view strref, hash_t hash);
765  ~TableRep();
766  const char* c_str() const noexcept { return (const char*)(this + 1); }
767  };
768 
769 private:
770  static std::string empty_std_string;
771 };
772 
773 
774 
775 /// A ustringhash holds the hash of a ustring in a type-safe way.
776 ///
777 /// It has a nearly identical interface to a ustring, and still refers to a
778 /// string in the internal ustring table. But whereas the representation of a
779 /// ustring is the pointer to the characters, the representation of a
780 /// ustringhash is the hash of the string.
781 ///
782 /// For some uses where you don't need access to the characters in any
783 /// performance-critical paths, this may be a more convenient representation.
784 /// In particular, it's well suited to a GPU that doesn't have access to the
785 /// character memory. Another interesting difference is that from run to run,
786 /// a ustring may have a different literal value, since there's no reason to
787 /// expect that the pointer to a string like "foo" will refer to the same
788 /// memory location every time the program executes, but in contrast, the hash
789 /// is guaranteed to be identical from run to run.
790 ///
792 public:
793  using rep_t = ustring::hash_t; ///< The underlying representation type
794  using hash_t = ustring::hash_t; ///< The hash type
795 
796  // Default constructor
797  OIIO_HOSTDEVICE constexpr ustringhash() noexcept
798  : m_hash(0)
799  {
800  }
801 
802  /// ustringhash destructor.
803  ~ustringhash() noexcept = default;
804 
805  /// Copy construct a ustringhash from another ustringhash.
806  OIIO_HOSTDEVICE constexpr ustringhash(const ustringhash& str) noexcept
807  : m_hash(str.m_hash)
808  {
809  }
810 
811  /// Construct from a ustring
812  ustringhash(const ustring& str) noexcept
813  : m_hash(str.hash())
814  {
815  }
816 
817  /// Construct a ustringhash from a null-terminated C string (char *).
818  OIIO_DEVICE_CONSTEXPR explicit ustringhash(const char* str)
819 #ifdef __CUDA_ARCH__
820  // GPU: just compute the hash. This can be constexpr!
821  : m_hash(Strutil::strhash(str))
822 #else
823  // CPU: make ustring, get its hash. Note that ustring ctr can't be
824  // constexpr because it has to modify the internal ustring table.
825  : m_hash(ustring(str).hash())
826 #endif
827  {
828  }
829 
830  OIIO_DEVICE_CONSTEXPR explicit ustringhash(const char* str, size_t len)
831 #ifdef __CUDA_ARCH__
832  // GPU: just compute the hash. This can be constexpr!
833  : m_hash(Strutil::strhash(len, str))
834 #else
835  // CPU: make ustring, get its hash. Note that ustring ctr can't be
836  // constexpr because it has to modify the internal ustring table.
837  : m_hash(ustring(str, len).hash())
838 #endif
839  {
840  }
841 
842  /// Construct a ustringhash from a string_view, which can be
843  /// auto-converted from either a std::string.
845 #ifdef __CUDA_ARCH__
846  // GPU: just compute the hash. This can be constexpr!
847  : m_hash(Strutil::strhash(str))
848 #else
849  // CPU: make ustring, get its hash. Note that ustring ctr can't be
850  // constexpr because it has to modify the internal ustring table.
851  : m_hash(ustring(str).hash())
852 #endif
853  {
854  }
855 
856  /// Construct from a raw hash value. Beware: results are undefined if it's
857  /// not the valid hash of a ustring.
858  OIIO_HOSTDEVICE explicit constexpr ustringhash(hash_t hash) noexcept
859  : m_hash(hash)
860  {
861  }
862 
863  /// Conversion to an OIIO::string_view.
864  operator string_view() const noexcept { return ustring::from_hash(m_hash); }
865 
866  /// Conversion to std::string (explicit only!).
867  explicit operator std::string() const noexcept
868  {
869  return ustring::from_hash(m_hash).string();
870  }
871 
872  /// Assign from a ustringhash
873  OIIO_HOSTDEVICE constexpr const ustringhash&
874  operator=(const ustringhash& str)
875  {
876  m_hash = str.m_hash;
877  return *this;
878  }
879 
880  /// Assign from a ustring
881  const ustringhash& operator=(const ustring& str)
882  {
883  m_hash = str.hash();
884  return *this;
885  }
886 
887  /// Reset to an empty string.
888  OIIO_HOSTDEVICE void clear() noexcept { m_hash = 0; }
889 
890 #ifndef __CUDA_ARCH__
891  /// Return a pointer to the characters.
892  const char* c_str() const noexcept
893  {
894  return ustring::from_hash(m_hash).c_str();
895  }
896 
897  /// Return a C string representation of a ustring.
898  const char* data() const noexcept { return c_str(); }
899 
900  /// Return a C++ std::string representation of a ustring.
901  const std::string& string() const noexcept
902  {
903  return ustring::from_hash(m_hash).string();
904  }
905 
906  /// Return the number of characters in the string.
907  size_t length() const noexcept
908  {
909  return ustring::from_hash(m_hash).length();
910  }
911 #endif
912 
913  /// Return a hashed version of the string
914  OIIO_HOSTDEVICE constexpr hash_t hash() const noexcept { return m_hash; }
915 
916 #ifndef __CUDA_ARCH__
917  /// Return the number of characters in the string.
918  size_t size() const noexcept { return length(); }
919 #endif
920 
921  /// Is the string empty -- i.e., is it nullptr or does it point to an
922  /// empty string? (Empty strings always have a hash of 0.)
923  OIIO_HOSTDEVICE constexpr bool empty() const noexcept
924  {
925  return m_hash == 0;
926  }
927 
928  /// Test for equality with another ustringhash.
929  OIIO_HOSTDEVICE constexpr bool
930  operator==(const ustringhash& str) const noexcept
931  {
932  return m_hash == str.m_hash;
933  }
934 
935  /// Test for inequality with another ustringhash.
936  OIIO_HOSTDEVICE constexpr bool
937  operator!=(const ustringhash& str) const noexcept
938  {
939  return m_hash != str.m_hash;
940  }
941 
942  /// Test for equality with a char*.
943  OIIO_CONSTEXPR17 bool operator==(const char* str) const noexcept
944  {
945  return m_hash == Strutil::strhash(str);
946  }
947 
948  /// Test for inequality with a char*.
949  OIIO_CONSTEXPR17 bool operator!=(const char* str) const noexcept
950  {
951  return m_hash != Strutil::strhash(str);
952  }
953 
954 #ifndef __CUDA_ARCH__
955  /// Test for equality with a ustring.
956  bool operator==(const ustring& str) const noexcept
957  {
958  return m_hash == str.hash();
959  }
960 
961  friend bool operator==(const ustring& a, const ustringhash& b) noexcept
962  {
963  return b == a;
964  }
965 
966  /// Test for inequality with a ustring.
967  bool operator!=(const ustring& str) const noexcept
968  {
969  return m_hash != str.hash();
970  }
971 
972  friend bool operator!=(const ustring& a, const ustringhash& b) noexcept
973  {
974  return b != a;
975  }
976 
977  OIIO_HOSTDEVICE constexpr bool operator<(const ustringhash& x) const noexcept
978  {
979  return hash() < x.hash();
980  }
981 
982  /// Generic stream output of a ustringhash outputs the string it refers
983  /// to.
984  friend std::ostream& operator<<(std::ostream& out, const ustringhash& str)
985  {
986  return (out << ustring(str));
987  }
988 #endif
989 
990  /// Return the ustringhash corresponding to the given hash. Caveat emptor:
991  /// results are undefined if it's not the valid hash of a ustring.
993  {
994  ustringhash u;
995  u.m_hash = hash;
996  return u;
997  }
998 
999 private:
1000  // Individual ustringhash internal representation -- the hash value.
1001  rep_t m_hash;
1002 
1003  friend class ustring;
1004 };
1005 
1006 
1007 
1008 static_assert(sizeof(ustringhash) == sizeof(uint64_t),
1009  "ustringhash should be the same size as a uint64_t");
1010 static_assert(sizeof(ustring) == sizeof(const char*),
1011  "ustring should be the same size as a const char*");
1012 
1013 
1014 
1015 inline ustringhash
1016 ustring::uhash() const noexcept
1017 {
1018  return ustringhash(hash());
1019 }
1020 
1021 
1022 
1023 #ifndef __CUDA_ARCH__
1025 {
1026  // The ustring constructor from a ustringhash is just a pretty
1027  // wrapper around an awkward construct.
1028  m_chars = ustring::from_hash(hash.hash()).c_str();
1029 }
1030 #endif
1031 
1032 
1033 
1034 /// ustring string literal operator
1035 inline ustring
1036 operator""_us(const char* str, std::size_t len)
1037 {
1038  return ustring(str, len);
1039 }
1040 
1041 
1042 /// ustringhash string literal operator
1044 operator""_ush(const char* str, std::size_t len)
1045 {
1046  return ustringhash(str, len);
1047 }
1048 
1049 
1050 
1051 #if OIIO_VERSION_LESS(3, 0, 0)
1052 /// Deprecated -- This is too easy to confuse with the ustringhash class. And
1053 /// also it is unnecessary if you use std::hash<ustring>. This will be removed
1054 /// in OIIO 3.0.
1055 using ustringHash = std::hash<ustring>;
1056 #endif
1057 
1058 
1059 
1060 /// Functor class to use for comparisons when sorting ustrings, if you
1061 /// want the strings sorted lexicographically.
1063 public:
1064  size_t operator()(ustring a, ustring b) const noexcept { return a < b; }
1065 };
1066 
1067 
1068 /// Functor class to use for comparisons when sorting ustrings, if you
1069 /// don't care if the sort order is lexicographic. This sorts based on
1070 /// the pointers themselves, which is safe because once allocated, a
1071 /// ustring's characters will never be moved. But beware, the resulting
1072 /// sorting order may vary from run to run!
1074 public:
1075  size_t operator()(ustring a, ustring b) const noexcept
1076  {
1077  return size_t(a.data()) < size_t(b.data());
1078  }
1079 };
1080 
1081 
1082 
1083 /// Case-insensitive comparison of ustrings. For speed, this always
1084 /// uses a static locale that doesn't require a mutex lock.
1085 inline bool
1087 {
1088  return a == b || Strutil::iequals(a.string(), b.string());
1089 }
1090 
1091 inline bool
1092 iequals(ustring a, const std::string& b)
1093 {
1094  return Strutil::iequals(a.string(), b);
1095 }
1096 
1097 inline bool
1098 iequals(const std::string& a, ustring b)
1099 {
1100  return Strutil::iequals(a, b.string());
1101 }
1102 
1103 
1104 
1105 // ustring variant stof from OpenImageIO/strutil.h
1106 namespace Strutil {
1107 
1108 #ifndef __CUDA_ARCH__
1109 
1110 inline float
1112 {
1113  return Strutil::stof(s.string());
1114 }
1115 
1116 template<>
1117 inline std::string
1119 {
1120  return value.string();
1121 }
1122 
1123 template<>
1124 inline std::string
1126 {
1127  return ustring(value).string();
1128 }
1129 
1130 #endif
1131 
1132 } // end namespace Strutil
1133 
1135 
1136 
1137 namespace std { // not necessary in C++17, then we can just say std::hash
1138 // std::hash specialization for ustring
1139 template<> struct hash<OIIO::ustring> {
1140  std::size_t operator()(OIIO::ustring u) const noexcept
1141  {
1142  return static_cast<std::size_t>(u.hash());
1143  }
1144 };
1145 
1146 
1147 // std::hash specialization for ustringhash
1148 template<> struct hash<OIIO::ustringhash> {
1149  OIIO_HOSTDEVICE constexpr std::size_t
1150  operator()(OIIO::ustringhash u) const noexcept
1151  {
1152  return static_cast<std::size_t>(u.hash());
1153  }
1154 };
1155 } // namespace std
1156 
1157 
1158 
1159 // Supply a fmtlib compatible custom formatter for ustring and ustringhash.
1161 
1162 template<> struct formatter<OIIO::ustring> : formatter<fmt::string_view, char> {
1163  template<typename FormatContext>
1164  auto format(const OIIO::ustring& u,
1165  FormatContext& ctx) OIIO_FMT_CUSTOM_FORMATTER_CONST
1166  {
1167  return formatter<fmt::string_view, char>::format({ u.data(), u.size() },
1168  ctx);
1169  }
1170 };
1171 
1172 template<>
1173 struct formatter<OIIO::ustringhash> : formatter<fmt::string_view, char> {
1174  template<typename FormatContext>
1175  auto format(const OIIO::ustringhash& h,
1176  FormatContext& ctx) OIIO_FMT_CUSTOM_FORMATTER_CONST
1177  {
1178  OIIO::ustring u(h);
1179  return formatter<fmt::string_view, char>::format({ u.data(), u.size() },
1180  ctx);
1181  }
1182 };
1183 
GLsizei GLenum GLsizei GLsizei GLuint memory
Definition: RE_OGL.h:202
const ustring & assign(const char *str)
Assign a null-terminated C string (char*) to *this.
Definition: ustring.h:244
bool operator==(const ustring &str) const noexcept
Definition: ustring.h:565
static OIIO_FORMAT_DEPRECATED ustring format(const char *fmt, const Args &...args)
Definition: ustring.h:683
char value_type
Definition: ustring.h:129
OIIO_HOSTDEVICE constexpr bool operator==(const ustringhash &str) const noexcept
Test for equality with another ustringhash.
Definition: ustring.h:930
size_type find_last_of(const char *s, size_type pos, size_type n) const
Definition: ustring.h:468
bool OIIO_UTIL_API iequals(string_view a, string_view b)
size_type find_last_of(const std::string &str, size_type pos=npos) const noexcept
Definition: ustring.h:462
bool operator==(const char *x) const noexcept
Test a ustring (this) for lexicographic equality with char x.
Definition: ustring.h:591
ustringhash(const ustring &str) noexcept
Construct from a ustring.
Definition: ustring.h:812
bool operator==(const ustring &str) const noexcept
Test for equality with a ustring.
Definition: ustring.h:956
size_type find(const char *s, size_type pos=0) const
Definition: ustring.h:394
OIIO_CONSTEXPR17 bool operator!=(const char *str) const noexcept
Test for inequality with a char*.
Definition: ustring.h:949
size_type copy(char *s, size_type n, size_type pos=0) const
Definition: ustring.h:362
size_type find_first_not_of(char c, size_type pos=0) const noexcept
Definition: ustring.h:505
friend bool operator!=(string_view a, const ustring &b) noexcept
Definition: ustring.h:638
OIIO_HOSTDEVICE constexpr hash_t hash() const noexcept
Return a hashed version of the string.
Definition: ustring.h:914
const ustring & assign(string_view str)
Assign a string_view to *this.
Definition: ustring.h:265
OIIO_HOSTDEVICE constexpr bool operator!=(const ustringhash &str) const noexcept
Test for inequality with another ustringhash.
Definition: ustring.h:937
size_type find_first_of(const char *s, size_type pos, size_type n) const
Definition: ustring.h:441
size_type rfind(char c, size_type pos=npos) const noexcept
Definition: ustring.h:424
size_type find_last_not_of(char c, size_type pos=npos) const noexcept
Definition: ustring.h:532
OIIO_CONSTEXPR14 basic_string_view substr(size_type pos, size_type n=npos) const noexcept
Definition: string_view.h:241
const ustringhash & operator=(const ustring &str)
Assign from a ustring.
Definition: ustring.h:881
size_t length() const noexcept
Return the number of characters in the string.
Definition: ustring.h:907
size_type rfind(const char *s, size_type pos=npos) const
Definition: ustring.h:419
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
GLsizei const GLfloat * value
Definition: glcorearb.h:824
static bool is_unique(const char *str)
Definition: ustring.h:725
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, float failrelative, float warnrelative, ROI roi={}, int nthreads=0)
bool operator!=(const char *x) const noexcept
Definition: ustring.h:627
static OIIO_NODISCARD ustring fmtformat(const char *fmt, const Args &...args)
Definition: ustring.h:673
const ustring & operator=(const char *str)
Assign a null-terminated C string (char *) to a ustring.
Definition: ustring.h:275
std::string to_string(const T &value)
Definition: strutil.h:706
OIIO_NODISCARD std::string format(const Str &fmt, Args &&...args)
Definition: strutil.h:128
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
ustring::hash_t rep_t
The underlying representation type.
Definition: ustring.h:793
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
size_type find_last_of(char c, size_type pos=npos) const noexcept
Definition: ustring.h:478
ustring(size_type n, char c)
Construct a ustring from n copies of character c.
Definition: ustring.h:173
const ustring & operator=(char c)
Assign a single char to a ustring.
Definition: ustring.h:284
friend std::ostream & operator<<(std::ostream &out, const ustringhash &str)
Definition: ustring.h:984
bool operator!=(const std::string &x) const noexcept
Definition: ustring.h:616
bool operator!=(string_view x) const noexcept
Definition: ustring.h:623
ustring substr(size_type pos=0, size_type n=npos) const
Definition: ustring.h:374
const ustring & assign(const std::string &str, size_type pos, size_type n=npos)
Assign a substring of a std::string to *this.
Definition: ustring.h:236
String-related utilities, all in namespace Strutil.
#define OIIO_UTIL_API
Definition: export.h:71
bool operator==(const std::string &x) const noexcept
Definition: ustring.h:581
friend bool operator!=(const std::string &a, const ustring &b) noexcept
Definition: ustring.h:631
const ustring & operator=(string_view str)
Assign a string_view to a ustring.
Definition: ustring.h:281
ustring(const std::string &str, size_type pos, size_type n=npos)
Construct a ustring from an indexed substring of a std::string.
Definition: ustring.h:179
hash_t hash() const noexcept
Return a hashed version of the string.
Definition: ustring.h:318
#define FMT_END_NAMESPACE
Definition: core.h:179
OIIO_DEVICE_CONSTEXPR ustringhash(const char *str)
Construct a ustringhash from a null-terminated C string (char *).
Definition: ustring.h:818
OIIO_UTIL_API float stof(string_view s, size_t *pos=0)
basic_string_view< char > string_view
Definition: core.h:501
static OIIO_NODISCARD constexpr ustringhash from_hash(hash_t hash)
Definition: ustring.h:992
auto format(const OIIO::ustringhash &h, FormatContext &ctx) OIIO_FMT_CUSTOM_FORMATTER_CONST
Definition: ustring.h:1175
size_t operator()(ustring a, ustring b) const noexcept
Definition: ustring.h:1064
const_iterator begin() const noexcept
Definition: ustring.h:338
friend bool operator!=(const ustring &a, const ustringhash &b) noexcept
Definition: ustring.h:972
OIIO_CONSTEXPR17 bool operator==(const char *str) const noexcept
Test for equality with a char*.
Definition: ustring.h:943
constexpr size_t strhash(size_t len, const char *s)
Definition: strutil.h:373
size_type find_last_not_of(const char *s, size_type pos, size_type n) const
Definition: ustring.h:522
const_reverse_iterator rend() const noexcept
Definition: ustring.h:350
GLdouble n
Definition: glcorearb.h:2008
size_type find_last_not_of(const ustring &str, size_type pos=npos) const noexcept
Definition: ustring.h:510
size_type find(const ustring &str, size_type pos=0) const noexcept
Definition: ustring.h:379
FMT_CONSTEXPR_CHAR_TRAITS auto compare(basic_string_view other) const -> int
Definition: core.h:470
const_reverse_iterator rbegin() const noexcept
Definition: ustring.h:346
ustring(const char *str, size_type pos, size_type n)
Definition: ustring.h:161
size_type find_first_of(const char *s, size_type pos=0) const
Definition: ustring.h:446
const_reference operator[](size_type pos) const noexcept
Definition: ustring.h:355
friend std::ostream & operator<<(std::ostream &out, const ustring &str)
Generic stream output of a ustring.
Definition: ustring.h:694
size_type find_first_not_of(const ustring &str, size_type pos=0) const noexcept
Definition: ustring.h:483
size_t operator()(ustring a, ustring b) const noexcept
Definition: ustring.h:1075
std::string str
Definition: ustring.h:760
size_type find_first_not_of(const char *s, size_type pos, size_type n) const
Definition: ustring.h:495
#define OIIO_DASSERT
Definition: dassert.h:55
~ustring() noexcept
ustring destructor.
Definition: ustring.h:206
static OIIO_NODISCARD ustring sprintf(const char *fmt, const Args &...args)
Definition: ustring.h:661
size_type rfind(const char *s, size_type pos, size_type n) const
Definition: ustring.h:414
const ustring & assign(const char *str, size_type n)
Assign the first n characters of str to *this.
Definition: ustring.h:251
size_type find(const char *s, size_type pos, size_type n) const
Definition: ustring.h:389
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:108
uint64_t hash_t
The hash type.
Definition: ustring.h:130
const ustring & assign(size_type n, char c)
Assign n copies of c to *this.
Definition: ustring.h:258
static OIIO_NODISCARD ustring from_hash(hash_t hash)
int compare(string_view str) const noexcept
Definition: ustring.h:540
size_t size_type
Definition: ustring.h:134
const std::string & string() const noexcept
Return a C++ std::string representation of a ustring.
Definition: ustring.h:901
ustring(const ustring &str, size_type pos, size_type n=npos)
Construct a ustring from an indexed substring of a ustring.
Definition: ustring.h:193
#define OIIO_HOSTDEVICE
Definition: platform.h:529
size_t length() const noexcept
Return the number of characters in the string.
Definition: ustring.h:309
std::string::const_reverse_iterator const_reverse_iterator
Definition: ustring.h:137
ustring(const char *str)
Construct a ustring from a null-terminated C string (char *).
Definition: ustring.h:146
std::size_t operator()(OIIO::ustring u) const noexcept
Definition: ustring.h:1140
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
const ustring & assign(const ustring &str)
Assign a ustring to *this.
Definition: ustring.h:215
GLint GLenum GLint x
Definition: glcorearb.h:409
bool operator<(const ustring &x) const noexcept
Definition: ustring.h:652
ustringhash uhash() const noexcept
Return a hashed version of the string.
Definition: ustring.h:1016
const ustring & assign(const std::string &str)
Assign a std::string to *this.
Definition: ustring.h:229
friend bool operator==(const std::string &a, const ustring &b) noexcept
Definition: ustring.h:595
OIIO_HOSTDEVICE constexpr ustringhash(hash_t hash) noexcept
Definition: ustring.h:858
GLdouble t
Definition: glad.h:2397
const_iterator end() const noexcept
Definition: ustring.h:342
const char * c_str() const noexcept
Return a pointer to the characters.
Definition: ustring.h:892
bool operator!=(const ustring &str) const noexcept
Definition: ustring.h:574
constexpr ustring() noexcept
Default ctr for ustring – make an empty string.
Definition: ustring.h:140
#define OIIO_NODISCARD
Definition: platform.h:485
const char * data() const noexcept
Return a C string representation of a ustring.
Definition: ustring.h:898
friend bool operator==(const ustring &a, const ustringhash &b) noexcept
Definition: ustring.h:961
size_type rfind(const std::string &str, size_type pos=npos) const noexcept
Definition: ustring.h:409
OIIO_DEVICE_CONSTEXPR ustringhash(string_view str)
Definition: ustring.h:844
size_type find(const std::string &str, size_type pos=0) const noexcept
Definition: ustring.h:384
GLsizeiptr size
Definition: glcorearb.h:664
ustring(const char *str, size_type n)
Construct a ustring from the first n characters of str.
Definition: ustring.h:167
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
size_type find_first_not_of(const std::string &str, size_type pos=0) const noexcept
Definition: ustring.h:489
std::string::const_iterator const_iterator
Definition: ustring.h:136
void clear() noexcept
Reset to an empty string.
Definition: ustring.h:306
const ustring & assign(const ustring &str, size_type pos, size_type n=npos)
Assign a substring of a ustring to *this.
Definition: ustring.h:222
size_type find_last_of(const char *s, size_type pos=npos) const
Definition: ustring.h:473
OIIO_HOSTDEVICE constexpr ustringhash() noexcept
Definition: ustring.h:797
size_type find_last_not_of(const std::string &str, size_type pos=npos) const noexcept
Definition: ustring.h:516
#define OIIO_FMT_CUSTOM_FORMATTER_CONST
Definition: fmt.h:76
OIIO_HOSTDEVICE constexpr const ustringhash & operator=(const ustringhash &str)
Assign from a ustringhash.
Definition: ustring.h:874
bool operator==(string_view x) const noexcept
Definition: ustring.h:588
value_type * pointer
Definition: ustring.h:131
size_type find_first_of(char c, size_type pos=0) const noexcept
Definition: ustring.h:451
size_t size() const noexcept
Return the number of characters in the string.
Definition: ustring.h:330
size_t size() const noexcept
Return the number of characters in the string.
Definition: ustring.h:918
size_t dummy_capacity
Definition: ustring.h:762
size_type find_first_of(const ustring &str, size_type pos=0) const noexcept
Definition: ustring.h:429
operator std::string() const noexcept
Conversion to std::string (explicit only!).
Definition: ustring.h:212
size_type rfind(const ustring &str, size_type pos=npos) const noexcept
Definition: ustring.h:404
auto format(const OIIO::ustring &u, FormatContext &ctx) OIIO_FMT_CUSTOM_FORMATTER_CONST
Definition: ustring.h:1164
OIIO_HOSTDEVICE constexpr std::size_t operator()(OIIO::ustringhash u) const noexcept
Definition: ustring.h:1150
ustring(const ustring &str) noexcept
Copy construct a ustring from another ustring.
Definition: ustring.h:187
bool iequals(ustring a, ustring b)
Definition: ustring.h:1086
ustring::hash_t hash_t
The hash type.
Definition: ustring.h:794
const value_type & const_reference
Definition: ustring.h:133
**If you just want to fire and args
Definition: thread.h:618
constexpr auto data() const noexcept-> const Char *
Definition: core.h:440
friend bool operator==(const char *a, const ustring &b) noexcept
Definition: ustring.h:609
size_type find_last_of(const ustring &str, size_type pos=npos) const noexcept
Definition: ustring.h:456
size_type find(char c, size_type pos=0) const noexcept
Definition: ustring.h:399
int compare(const char *str) const noexcept
Definition: ustring.h:548
OIIO_UTIL_API const char * c_str(string_view str)
bool operator!=(const ustring &str) const noexcept
Test for inequality with a ustring.
Definition: ustring.h:967
friend bool operator!=(const char *a, const ustring &b) noexcept
Definition: ustring.h:645
#define OIIO_FORMAT_DEPRECATED
Definition: strutil.h:50
static ustring from_unique(const char *unique)
Definition: ustring.h:733
#define FMT_BEGIN_NAMESPACE
Definition: core.h:176
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:127
auto sprintf(const S &fmt, const T &...args) -> std::basic_string< Char >
Definition: printf.h:617
PUGI__FN I unique(I begin, I end)
Definition: pugixml.cpp:7464
size_type find_first_not_of(const char *s, size_type pos=0) const
Definition: ustring.h:500
OIIO_HOSTDEVICE constexpr bool empty() const noexcept
Definition: ustring.h:923
OIIO_HOSTDEVICE constexpr bool operator<(const ustringhash &x) const noexcept
Definition: ustring.h:977
size_type find_last_not_of(const char *s, size_type pos=npos) const
Definition: ustring.h:527
const char * data() const noexcept
Return a C string representation of a ustring.
Definition: ustring.h:293
const char * c_str() const noexcept
Definition: ustring.h:766
const std::string & string() const noexcept
Return a C++ std::string representation of a ustring.
Definition: ustring.h:296
bool empty() const noexcept
Definition: ustring.h:334
OIIO_HOSTDEVICE void clear() noexcept
Reset to an empty string.
Definition: ustring.h:888
std::string OIIO_UTIL_API concat(string_view s, string_view t)
value_type & reference
Definition: ustring.h:132
const char * c_str() const noexcept
Return a C string representation of a ustring.
Definition: ustring.h:290
OIIO_DEVICE_CONSTEXPR ustringhash(const char *str, size_t len)
Definition: ustring.h:830
ustring(string_view str)
Definition: ustring.h:154
#define OIIO_DEVICE_CONSTEXPR
Definition: platform.h:539
constexpr size_type length() const noexcept
Definition: string_view.h:204
const ustring & operator=(const ustring &str)
Assign a ustring to another ustring.
Definition: ustring.h:272
friend bool operator==(string_view a, const ustring &b) noexcept
Definition: ustring.h:602
const char * rep_t
The underlying representation type.
Definition: ustring.h:128
const ustring & operator=(const std::string &str)
Assign a C++ std::string to a ustring.
Definition: ustring.h:278
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:126
size_type find_first_of(const std::string &str, size_type pos=0) const noexcept
Definition: ustring.h:435
friend int compare(const std::string &a, const ustring &b) noexcept
Definition: ustring.h:556