HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
strutil.h
Go to the documentation of this file.
1 // Copyright 2008-present Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // https://github.com/OpenImageIO/oiio/blob/master/LICENSE.md
4 
5 // clang-format off
6 
7 /////////////////////////////////////////////////////////////////////////
8 /// @file strutil.h
9 ///
10 /// @brief String-related utilities, all in namespace Strutil.
11 /////////////////////////////////////////////////////////////////////////
12 
13 
14 
15 #pragma once
16 
17 #include <cstdio>
18 #include <map>
19 #include <sstream>
20 #include <string>
21 #include <vector>
22 
23 #include <OpenImageIO/export.h>
24 #include <OpenImageIO/hash.h>
26 #include <OpenImageIO/platform.h>
28 
30 
31 #if OIIO_GNUC_VERSION >= 70000
32 # pragma GCC diagnostic push
33 # pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
34 #endif
35 #ifndef FMT_HEADER_ONLY
36 # define FMT_HEADER_ONLY
37 #endif
38 #ifndef FMT_EXCEPTIONS
39 # define FMT_EXCEPTIONS 0
40 #endif
41 #ifndef FMT_USE_GRISU
42 # define FMT_USE_GRISU 1
43 #endif
44 #include "detail/fmt/ostream.h"
45 #include "detail/fmt/format.h"
46 #include "detail/fmt/printf.h"
47 #if OIIO_GNUC_VERSION >= 70000
48 # pragma GCC diagnostic pop
49 #endif
50 
51 // Allow client software to know if this version of OIIO as Strutil::sprintf
52 #define OIIO_HAS_SPRINTF 1
53 
54 // Allow client software to know if this version of OIIO has Strutil::format
55 // behave like sprintf (OIIO_FORMAT_IS_FMT==0) or like python / {fmt} /
56 // C++20ish std::format (OIIO_FORMAT_IS_FMT==1).
57 #define OIIO_FORMAT_IS_FMT 0
58 
59 // Allow client software to know that at this moment, the fmt-based string
60 // formatting is locale-independent. This was 0 in older versions when fmt
61 // was locale dependent.
62 #define OIIO_FMT_LOCALE_INDEPENDENT 1
63 
64 
65 
67 /// @namespace Strutil
68 ///
69 /// @brief String-related utilities.
70 namespace Strutil {
71 
72 /// Output the string to the file/stream in a synchronized fashion, so that
73 /// buffers are flushed and internal mutex is used to prevent threads from
74 /// clobbering each other -- output strings coming from concurrent threads
75 /// may be interleaved, but each string is "atomic" and will never splice
76 /// each other character-by-character.
77 void OIIO_API sync_output (FILE *file, string_view str);
78 void OIIO_API sync_output (std::ostream &file, string_view str);
79 
80 
81 /// Construct a std::string in a printf-like fashion. For example:
82 ///
83 /// std::string s = Strutil::sprintf ("blah %d %g", (int)foo, (float)bar);
84 ///
85 /// Uses the fmt library underneath, so it's fully type-safe, and
86 /// works with any types that understand stream output via '<<'.
87 /// The formatting of the string will always use the classic "C" locale
88 /// conventions (in particular, '.' as decimal separator for float values).
89 template<typename... Args>
90 inline std::string sprintf (const char* fmt, const Args&... args)
91 {
92  return ::fmt::sprintf (fmt, args...);
93 }
94 
95 
96 
97 /// format() constructs formatted strings. Note that this is in transition!
98 ///
99 /// Strutil::old::format() uses printf conventions and matches format() used
100 /// in OIIO 1.x. It is equivalent to Strutil::sprintf().
101 ///
102 /// std::string s = Strutil::old::sprintf ("blah %d %g", (int)foo, (float)bar);
103 ///
104 /// Strutil::fmt::format() uses "Python" conventions, in the style of string
105 /// formatting used by C++20 std::format and implemented today in the {fmt}
106 /// package (https://github.com/fmtlib/fmt). For example:
107 ///
108 /// std::string s = Strutil::format ("blah {} {}", (int)foo, (float)bar);
109 ///
110 /// Straight-up Strutil::format is today aliased to old::format for the sake
111 /// of back-compatibility, but will someday be switched to fmt::format.
112 ///
113 /// Recommended strategy for users:
114 /// * If you want printf conventions, switch to Strutil::sprintf().
115 /// * If you want to use the python conventions prior to the big switch,
116 /// use Strutil::fmt::format() explicitly (but see the caveat below).
117 /// * Use of unspecified Strutil::format() is, for back compatibility,
118 /// currently equivalent to sprintf, but beware that some point it will
119 /// switch to the future-standard formatting rules.
120 ///
121 
122 namespace fmt {
123 template<typename... Args>
124 inline std::string format (const char* fmt, const Args&... args)
125 {
126  return ::fmt::format (fmt, args...);
127 }
128 } // namespace fmt
129 
130 namespace old {
131 template<typename... Args>
132 inline std::string format (const char* fmt, const Args&... args)
133 {
134  return Strutil::sprintf (fmt, args...);
135 }
136 
137 // DEPRECATED(2.0) string_view version. Phasing this out because
138 // std::string_view won't have a c_str() method.
139 template<typename... Args>
140 inline std::string format (string_view fmt, const Args&... args)
141 {
142  return format (fmt.c_str(), args...);
143 }
144 } // namespace old
145 
146 
147 
148 using old::format;
149 
150 
151 
152 /// Strutil::print (fmt, ...)
153 /// Strutil::fprint (FILE*, fmt, ...)
154 /// Strutil::fprint (ostream& fmt, ...)
155 ///
156 /// Output formatted strings to stdout, a FILE*, or a stream, respectively.
157 /// All use printf-like formatting rules, are type-safe, are thread-safe
158 /// (the outputs are "atomic", at least versus other calls to
159 /// Strutil::*printf), and automatically flush their outputs. They are all
160 /// locale-independent (forcing classic "C" locale).
161 
162 template<typename... Args>
163 inline void printf (const char* fmt, const Args&... args)
164 {
165  sync_output (stdout, Strutil::sprintf(fmt, args...));
166 }
167 
168 template<typename... Args>
169 inline void fprintf (FILE *file, const char* fmt, const Args&... args)
170 {
171  sync_output (file, Strutil::sprintf(fmt, args...));
172 }
173 
174 template<typename... Args>
175 inline void fprintf (std::ostream &file, const char* fmt, const Args&... args)
176 {
177  sync_output (file, Strutil::sprintf(fmt, args...));
178 }
179 
180 
181 
182 /// Strutil::print (fmt, ...)
183 /// Strutil::print (FILE*, fmt, ...)
184 /// Strutil::print (ostream& fmt, ...)
185 ///
186 /// Output formatted strings to stdout, a FILE*, or a stream, respectively.
187 /// All use "Python-like" formatting description (as {fmt} does, and some
188 /// day, std::format), are type-safe, are thread-safe (the outputs are
189 /// "atomic", at least versus other calls to Strutil::*printf), and
190 /// automatically flush their outputs. They are all locale-independent by
191 /// default (use {:n} for locale-aware formatting).
192 
193 template<typename... Args>
194 inline void print (const char* fmt, const Args&... args)
195 {
196  sync_output (stdout, Strutil::fmt::format(fmt, args...));
197 }
198 
199 template<typename... Args>
200 inline void print (FILE *file, const char* fmt, const Args&... args)
201 {
202  sync_output (file, Strutil::fmt::format(fmt, args...));
203 }
204 
205 template<typename... Args>
206 inline void print (std::ostream &file, const char* fmt, const Args&... args)
207 {
208  sync_output (file, Strutil::fmt::format(fmt, args...));
209 }
210 
211 
212 
213 
214 /// Return a std::string formatted from printf-like arguments -- passed
215 /// already as a va_list. This is not guaranteed type-safe and is not
216 /// extensible like format(). Use with caution!
217 std::string OIIO_API vsprintf (const char *fmt, va_list ap)
218 #if defined(__GNUC__) && !defined(__CUDACC__)
219  __attribute__ ((format (printf, 1, 0) ))
220 #endif
221  ;
222 
223 /// Return a std::string formatted like Strutil::format, but passed
224 /// already as a va_list. This is not guaranteed type-safe and is not
225 /// extensible like format(). Use with caution!
226 OIIO_DEPRECATED("use `vsprintf` instead")
227 std::string OIIO_API vformat (const char *fmt, va_list ap)
228 #if defined(__GNUC__) && !defined(__CUDACC__)
229  __attribute__ ((format (printf, 1, 0) ))
230 #endif
231  ;
232 
233 /// Return a string expressing a number of bytes, in human readable form.
234 /// - memformat(153) -> "153 B"
235 /// - memformat(15300) -> "14.9 KB"
236 /// - memformat(15300000) -> "14.6 MB"
237 /// - memformat(15300000000LL) -> "14.2 GB"
238 std::string OIIO_API memformat (long long bytes, int digits=1);
239 
240 /// Return a string expressing an elapsed time, in human readable form.
241 /// e.g. "0:35.2"
242 std::string OIIO_API timeintervalformat (double secs, int digits=1);
243 
244 
245 /// Get a map with RESTful arguments extracted from the given string 'str'.
246 /// Add it into the 'result' argument (Warning: the 'result' argument may
247 /// be changed even if 'get_rest_arguments ()' return an error!).
248 /// Return true on success, false on error.
249 /// Acceptable forms:
250 /// - text?arg1=val1&arg2=val2...
251 /// - ?arg1=val1&arg2=val2...
252 /// Everything before question mark will be saved into the 'base' argument.
253 bool OIIO_API get_rest_arguments (const std::string &str, std::string &base,
254  std::map<std::string, std::string> &result);
255 
256 /// Take a string that may have embedded newlines, tabs, etc., and turn
257 /// those characters into escape sequences like `\n`, `\t`, `\v`, `\b`,
258 /// `\r`, `\f`, `\a`, `\\`, `\"`.
260 
261 /// Take a string that has embedded escape sequences (`\\`, `\"`, `\n`,
262 /// etc.) and collapse them into the 'real' characters.
264 
265 /// Word-wrap string `src` to no more than `columns` width, starting with an
266 /// assumed position of `prefix` on the first line and intending by `prefix`
267 /// blanks before all lines other than the first.
268 ///
269 /// Words may be split AT any characters in `sep` or immediately AFTER any
270 /// characters in `presep`. After the break, any extra `sep` characters will
271 /// be deleted.
272 ///
273 /// By illustration,
274 /// wordwrap("0 1 2 3 4 5 6 7 8", 10, 4)
275 /// should return:
276 /// "0 1 2\n 3 4 5\n 6 7 8"
277 std::string OIIO_API wordwrap (string_view src, int columns = 80,
278  int prefix = 0, string_view sep = " ",
279  string_view presep = "");
280 
281 
282 /// Our favorite "string" hash of a length of bytes. Currently, it is just
283 /// a wrapper for an inlined, constexpr (if C++ >= 14), Cuda-safe farmhash.
284 inline OIIO_CONSTEXPR14 size_t
285 strhash (size_t len, const char *s)
286 {
287  return OIIO::farmhash::inlined::Hash(s, len);
288 }
289 
290 
291 /// Hash a string_view. This is OIIO's default favorite string hasher.
292 /// Currently, it uses farmhash, is constexpr (for C++14), and works in
293 /// Cuda. This is rigged, though, so that empty strings hash always hash to
294 /// 0 (that isn't would a raw farmhash would give you, but it's a useful
295 /// property, especially for trivial initialization).
296 inline OIIO_CONSTEXPR14 size_t
298 {
299  return s.length() ? strhash(s.length(), s.data()) : 0;
300 }
301 
302 
303 
304 /// Case-insensitive comparison of strings. For speed, this always uses
305 /// a static locale that doesn't require a mutex.
307 
308 /// Case-insensitive ordered comparison of strings. For speed, this always
309 /// uses a static locale that doesn't require a mutex.
311 
312 /// Does 'a' start with the string 'b', with a case-sensitive comparison?
314 
315 /// Does 'a' start with the string 'b', with a case-insensitive comparison?
316 /// For speed, this always uses a static locale that doesn't require a mutex.
318 
319 /// Does 'a' end with the string 'b', with a case-sensitive comparison?
321 
322 /// Does 'a' end with the string 'b', with a case-insensitive comparison?
323 /// For speed, this always uses a static locale that doesn't require a mutex.
325 
326 /// Does 'a' contain the string 'b' within it?
328 
329 /// Does 'a' contain the string 'b' within it, using a case-insensitive
330 /// comparison?
332 
333 /// Convert to upper case in place, faster than std::toupper because we use
334 /// a static locale that doesn't require a mutex lock.
336 
337 /// Convert to upper case in place, faster than std::toupper because we use
338 /// a static locale that doesn't require a mutex lock.
340 
341 /// Return an all-upper case version of `a` (locale-independent).
343  std::string result(a);
344  to_lower(result);
345  return result;
346 }
347 
348 /// Return an all-upper case version of `a` (locale-independent).
350  std::string result(a);
351  to_upper(result);
352  return result;
353 }
354 
355 
356 
357 /// Return a reference to the section of str that has all consecutive
358 /// characters in chars removed from the beginning and ending. If chars is
359 /// empty, it will be interpreted as " \t\n\r\f\v" (whitespace).
361 
362 /// Return a reference to the section of str that has all consecutive
363 /// characters in chars removed from the beginning (left side). If chars is
364 /// empty, it will be interpreted as " \t\n\r\f\v" (whitespace).
366 
367 /// Return a reference to the section of str that has all consecutive
368 /// characters in chars removed from the ending (right side). If chars is
369 /// empty, it will be interpreted as " \t\n\r\f\v" (whitespace).
371 
372 
373 /// Fills the "result" list with the words in the string, using sep as
374 /// the delimiter string. If maxsplit is > -1, at most maxsplit splits
375 /// are done. If sep is "", any whitespace string is a separator. If the
376 /// source `str` is empty, there will be zero pieces.
377 void OIIO_API split (string_view str, std::vector<string_view> &result,
378  string_view sep = string_view(), int maxsplit = -1);
379 void OIIO_API split (string_view str, std::vector<std::string> &result,
380  string_view sep = string_view(), int maxsplit = -1);
381 
382 /// Split the contents of `str` using `sep` as the delimiter string. If
383 /// `sep` is "", any whitespace string is a separator. If `maxsplit > -1`,
384 /// at most `maxsplit` split fragments will be produced (for example,
385 /// maxsplit=2 will split at only the first separator, yielding at most two
386 /// fragments). The result is returned as a vector of std::string (for
387 /// `splits()`) or a vector of string_view (for `splitsv()`). If the source
388 /// `str` is empty, there will be zero pieces.
389 OIIO_API std::vector<std::string>
390 splits (string_view str, string_view sep = "", int maxsplit = -1);
391 OIIO_API std::vector<string_view>
392 splitsv (string_view str, string_view sep = "", int maxsplit = -1);
393 
394 /// Join all the strings in 'seq' into one big string, separated by the
395 /// 'sep' string. The Sequence can be any iterable collection of items that
396 /// are able to convert to string via stream output. Examples include:
397 /// std::vector<string_view>, std::vector<std::string>, std::set<ustring>,
398 /// std::vector<int>, etc.
399 template<class Sequence>
400 std::string join (const Sequence& seq, string_view sep="")
401 {
402  std::ostringstream out;
403  out.imbue(std::locale::classic()); // Force "C" locale
404  bool first = true;
405  for (auto&& s : seq) {
406  if (! first && sep.size())
407  out << sep;
408  out << s;
409  first = false;
410  }
411  return out.str();
412 }
413 
414 /// Join all the strings in 'seq' into one big string, separated by the
415 /// 'sep' string. The Sequence can be any iterable collection of items that
416 /// are able to convert to string via stream output. Examples include:
417 /// std::vector<string_view>, std::vector<std::string>, std::set<ustring>,
418 /// std::vector<int>, etc. Values will be rendered into the string in a
419 /// locale-independent manner (i.e., '.' for decimal in floats). If the
420 /// optional `len` is nonzero, exactly that number of elements will be
421 /// output (truncating or default-value-padding the sequence).
422 template<class Sequence>
423 std::string join (const Sequence& seq, string_view sep /*= ""*/, size_t len)
424 {
426  std::ostringstream out;
427  out.imbue(std::locale::classic()); // Force "C" locale
428  bool first = true;
429  for (auto&& s : seq) {
430  if (! first)
431  out << sep;
432  out << s;
433  first = false;
434  if (len && (--len == 0))
435  break;
436  }
437  while (len--) {
438  if (! first)
439  out << sep;
440  out << E();
441  first = false;
442  }
443  return out.str();
444 }
445 
446 /// Concatenate two strings, returning a std::string, implemented carefully
447 /// to not perform any redundant copies or allocations. This is
448 /// semantically equivalent to `Strutil::sprintf("%s%s", s, t)`, but is
449 /// more efficient.
451 
452 /// Repeat a string formed by concatenating str n times.
454 
455 /// Replace a pattern inside a string and return the result. If global is
456 /// true, replace all instances of the pattern, otherwise just the first.
458  string_view replacement, bool global=false);
459 
460 
461 /// strtod/strtof equivalents that are "locale-independent", always using
462 /// '.' as the decimal separator. This should be preferred for I/O and other
463 /// situations where you want the same standard formatting regardless of
464 /// locale.
465 float OIIO_API strtof (const char *nptr, char **endptr = nullptr) noexcept;
466 double OIIO_API strtod (const char *nptr, char **endptr = nullptr) noexcept;
467 
468 
469 // stoi() returns the int conversion of text from a string.
470 // No exceptions or errors -- parsing errors just return 0, over/underflow
471 // gets clamped to int range. No locale consideration.
472 OIIO_API int stoi (string_view s, size_t* pos=0, int base=10);
473 
474 // stoui() returns the unsigned int conversion of text from a string.
475 // No exceptions or errors -- parsing errors just return 0. Negative
476 // values are cast, overflow is clamped. No locale considerations.
477 inline unsigned int stoui (string_view s, size_t* pos=0, int base=10) {
478  return static_cast<unsigned int>(stoi (s, pos, base));
479 }
480 
481 /// stof() returns the float conversion of text from several string types.
482 /// No exceptions or errors -- parsing errors just return 0.0. These always
483 /// use '.' for the decimal mark (versus atof and std::strtof, which are
484 /// locale-dependent).
485 OIIO_API float stof (string_view s, size_t* pos=0);
486 #define OIIO_STRUTIL_HAS_STOF 1 /* be able to test this */
487 
488 // Temporary fix: allow separate std::string and char* versions, to avoid
489 // string_view allocation on some platforms. This will be deprecated once
490 // we can count on all supported compilers using short string optimization.
491 OIIO_API float stof (const std::string& s, size_t* pos=0);
492 OIIO_API float stof (const char* s, size_t* pos=0);
493 // N.B. For users of ustring, there's a stof(ustring) defined in ustring.h.
494 
495 OIIO_API double stod (string_view s, size_t* pos=0);
496 OIIO_API double stod (const std::string& s, size_t* pos=0);
497 OIIO_API double stod (const char* s, size_t* pos=0);
498 
499 
500 
501 /// Return true if the string is exactly (other than leading and trailing
502 /// whitespace) a valid int.
504 
505 /// Return true if the string is exactly (other than leading or trailing
506 /// whitespace) a valid float. This operations in a locale-independent
507 /// manner, i.e., it assumes '.' as the decimal mark.
509 
510 
511 
512 // Helper template to convert from generic type to string. Used when you
513 // want stoX but you're in a template. Rigged to use "C" locale.
514 template<typename T>
516  return T(s); // Generic: assume there is an explicit converter
517 }
518 // Special case for int
519 template<> inline int from_string<int> (string_view s) {
520  return Strutil::stoi(s);
521 }
522 // Special case for uint
523 template<> inline unsigned int from_string<unsigned int> (string_view s) {
524  return Strutil::stoui(s);
525 }
526 // Special case for float -- note that by using Strutil::strtof, this
527 // always treats '.' as the decimal mark.
528 template<> inline float from_string<float> (string_view s) {
529  return Strutil::stof(s);
530 }
531 
532 
533 
534 /// Template function to convert any type to a string. The default
535 /// implementation is just to use sprintf or fmt::to_string. The template
536 /// can be overloaded if there is a better method for particular types.
537 template<typename T>
538 inline std::string to_string (const T& value) {
540 }
541 
542 // Some special pass-through cases
543 inline std::string to_string (const std::string& value) { return value; }
545 inline std::string to_string (const char* value) { return value; }
546 
547 
548 
549 // Helper template to test if a string is a generic type. Used instead of
550 // string_is_X, but when you're inside templated code.
551 template<typename T>
552 inline bool string_is (string_view /*s*/) {
553  return false; // Generic: assume there is an explicit specialization
554 }
555 // Special case for int
556 template <> inline bool string_is<int> (string_view s) {
557  return string_is_int (s);
558 }
559 // Special case for float. Note that by using Strutil::stof, this always
560 // treats '.' as the decimal character.
561 template <> inline bool string_is<float> (string_view s) {
562  return string_is_float (s);
563 }
564 
565 
566 
567 
568 /// Given a string containing values separated by a comma (or optionally
569 /// another separator), extract the individual values, placing them into
570 /// vals[] which is presumed to already contain defaults. If only a single
571 /// value was in the list, replace all elements of vals[] with the value.
572 /// Otherwise, replace them in the same order. A missing value will simply
573 /// not be replaced. Return the number of values found in the list
574 /// (including blank or malformed ones). If the vals vector was empty
575 /// initially, grow it as necessary.
576 ///
577 /// For example, if T=float, suppose initially, vals[] = {0, 1, 2}, then
578 /// "3.14" results in vals[] = {3.14, 3.14, 3.14}
579 /// "3.14,,-2.0" results in vals[] = {3.14, 1, -2.0}
580 ///
581 /// This can work for type T = int, float, or any type for that has
582 /// an explicit constructor from a std::string.
583 template<class T, class Allocator>
584 int extract_from_list_string (std::vector<T, Allocator> &vals,
585  string_view list,
586  string_view sep = ",")
587 {
588  size_t nvals = vals.size();
589  std::vector<string_view> valuestrings;
590  Strutil::split (list, valuestrings, sep);
591  for (size_t i = 0, e = valuestrings.size(); i < e; ++i) {
592  T v = from_string<T> (valuestrings[i]);
593  if (nvals == 0)
594  vals.push_back (v);
595  else if (valuestrings[i].size()) {
596  if (vals.size() > i) // don't replace non-existant entries
597  vals[i] = from_string<T> (valuestrings[i]);
598  }
599  /* Otherwise, empty space between commas, so leave default alone */
600  }
601  if (valuestrings.size() == 1 && nvals > 0) {
602  vals.resize (1);
603  vals.resize (nvals, vals[0]);
604  }
605  return list.size() ? (int) valuestrings.size() : 0;
606 }
607 
608 
609 /// Given a string containing values separated by a comma (or optionally
610 /// another separator), extract the individual values, returning them as a
611 /// std::vector<T>. The vector will be initialized with `nvals` elements
612 /// with default value `val`. If only a single value was in the list,
613 /// replace all elements of vals[] with the value. Otherwise, replace them
614 /// in the same order. A missing value will simply not be replaced and
615 /// will retain the initialized default value. If the string contains more
616 /// then `nvals` values, they will append to grow the vector.
617 ///
618 /// For example, if T=float,
619 /// extract_from_list_string ("", 3, 42.0f)
620 /// --> {42.0, 42.0, 42.0}
621 /// extract_from_list_string ("3.14", 3, 42.0f)
622 /// --> {3.14, 3.14, 3.14}
623 /// extract_from_list_string ("3.14,,-2.0", 3, 42.0f)
624 /// --> {3.14, 42.0, -2.0}
625 /// extract_from_list_string ("1,2,3,4", 3, 42.0f)
626 /// --> {1.0, 2.0, 3.0, 4.0}
627 ///
628 /// This can work for type T = int, float, or any type for that has
629 /// an explicit constructor from a std::string.
630 template<class T>
631 std::vector<T>
632 extract_from_list_string (string_view list, size_t nvals=0, T val=T(),
633  string_view sep = ",")
634 {
635  std::vector<T> vals (nvals, val);
636  extract_from_list_string (vals, list, sep);
637  return vals;
638 }
639 
640 
641 
642 
643 /// C++ functor wrapper class for using strhash for unordered_map or
644 /// unordered_set. The way this is used, in conjunction with
645 /// StringEqual, to build an efficient hash map for char*'s or
646 /// std::string's is as follows:
647 /// \code
648 /// unordered_map <const char *, Key, Strutil::StringHash, Strutil::StringEqual>
649 /// \endcode
650 class StringHash {
651 public:
652  size_t operator() (string_view s) const {
653  return (size_t)Strutil::strhash(s);
654  }
655 };
656 
657 
658 
659 /// C++ functor for comparing two strings for equality of their characters.
661  bool operator() (const char *a, const char *b) const noexcept { return strcmp (a, b) == 0; }
662  bool operator() (string_view a, string_view b) const noexcept { return a == b; }
663 };
664 
665 
666 /// C++ functor for comparing two strings for equality of their characters
667 /// in a case-insensitive and locale-insensitive way.
669  bool operator() (const char *a, const char *b) const noexcept;
670  bool operator() (string_view a, string_view b) const noexcept { return iequals (a, b); }
671 };
672 
673 
674 /// C++ functor for comparing the ordering of two strings.
676  bool operator() (const char *a, const char *b) const noexcept { return strcmp (a, b) < 0; }
677  bool operator() (string_view a, string_view b) const noexcept { return a < b; }
678 };
679 
680 
681 /// C++ functor for comparing the ordering of two strings in a
682 /// case-insensitive and locale-insensitive way.
684  bool operator() (const char *a, const char *b) const noexcept;
685  bool operator() (string_view a, string_view b) const noexcept { return a < b; }
686 };
687 
688 
689 
690 #ifdef _WIN32
691 /// Conversion functions between UTF-8 and UTF-16 for windows.
692 ///
693 /// For historical reasons, the standard encoding for strings on windows is
694 /// UTF-16, whereas the unix world seems to have settled on UTF-8. These two
695 /// encodings can be stored in std::string and std::wstring respectively, with
696 /// the caveat that they're both variable-width encodings, so not all the
697 /// standard string methods will make sense (for example std::string::size()
698 /// won't return the number of glyphs in a UTF-8 string, unless it happens to
699 /// be made up of only the 7-bit ASCII subset).
700 ///
701 /// The standard windows API functions usually have two versions, a UTF-16
702 /// version with a 'W' suffix (using wchar_t* strings), and an ANSI version
703 /// with a 'A' suffix (using char* strings) which uses the current windows
704 /// code page to define the encoding. (To make matters more confusing there is
705 /// also a further "TCHAR" version which is #defined to the UTF-16 or ANSI
706 /// version, depending on whether UNICODE is defined during compilation.
707 /// This is meant to make it possible to support compiling libraries in
708 /// either unicode or ansi mode from the same codebase.)
709 ///
710 /// Using std::string as the string container (as in OIIO) implies that we
711 /// can't use UTF-16. It also means we need a variable-width encoding to
712 /// represent characters in non-Latin alphabets in an unambiguous way; the
713 /// obvious candidate is UTF-8. File paths in OIIO are considered to be
714 /// represented in UTF-8, and must be converted to UTF-16 before passing to
715 /// windows API file opening functions.
716 
717 /// On the other hand, the encoding used for the ANSI versions of the windows
718 /// API is the current windows code page. This is more compatible with the
719 /// default setup of the standard windows command prompt, and may be more
720 /// appropriate for error messages.
721 
722 // Conversion to wide char
723 //
724 std::wstring OIIO_API utf8_to_utf16 (string_view utf8str) noexcept;
725 
726 // Conversion from wide char
727 //
728 std::string OIIO_API utf16_to_utf8(const std::wstring& utf16str) noexcept;
729 #endif
730 
731 
732 /// Copy at most size characters (including terminating 0 character) from
733 /// src into dst[], filling any remaining characters with 0 values. Returns
734 /// dst. Note that this behavior is identical to strncpy, except that it
735 /// guarantees that there will be a termining 0 character.
736 OIIO_API char * safe_strcpy (char *dst, string_view src, size_t size) noexcept;
737 
738 
739 /// Modify str to trim any leading whitespace (space, tab, linefeed, cr)
740 /// from the front.
741 void OIIO_API skip_whitespace (string_view &str) noexcept;
742 
743 /// Modify str to trim any trailing whitespace (space, tab, linefeed, cr)
744 /// from the back.
745 void OIIO_API remove_trailing_whitespace (string_view &str) noexcept;
746 
747 /// Modify str to trim any whitespace (space, tab, linefeed, cr) from both
748 /// the front and back.
749 inline void trim_whitespace (string_view &str) noexcept {
750  skip_whitespace(str);
752 }
753 
754 /// If str's first character is c (or first non-whitespace char is c, if
755 /// skip_whitespace is true), return true and additionally modify str to
756 /// skip over that first character if eat is also true. Otherwise, if str
757 /// does not begin with character c, return false and don't modify str.
758 bool OIIO_API parse_char (string_view &str, char c,
759  bool skip_whitespace = true, bool eat=true) noexcept;
760 
761 /// Modify str to trim all characters up to (but not including) the first
762 /// occurrence of c, and return true if c was found or false if the whole
763 /// string was trimmed without ever finding c. But if eat is false, then
764 /// don't modify str, just return true if any c is found, false if no c
765 /// is found.
766 bool OIIO_API parse_until_char (string_view &str, char c, bool eat=true) noexcept;
767 
768 /// If str's first non-whitespace characters are the prefix, return true and
769 /// additionally modify str to skip over that prefix if eat is also true.
770 /// Otherwise, if str doesn't start with optional whitespace and the prefix,
771 /// return false and don't modify str.
772 bool OIIO_API parse_prefix (string_view &str, string_view prefix, bool eat=true) noexcept;
773 
774 /// If str's first non-whitespace characters form a valid integer, return
775 /// true, place the integer's value in val, and additionally modify str to
776 /// skip over the parsed integer if eat is also true. Otherwise, if no
777 /// integer is found at the beginning of str, return false and don't modify
778 /// val or str.
779 bool OIIO_API parse_int (string_view &str, int &val, bool eat=true) noexcept;
780 
781 /// If str's first non-whitespace characters form a valid float, return
782 /// true, place the float's value in val, and additionally modify str to
783 /// skip over the parsed float if eat is also true. Otherwise, if no float
784 /// is found at the beginning of str, return false and don't modify val or
785 /// str.
786 bool OIIO_API parse_float (string_view &str, float &val, bool eat=true) noexcept;
787 
789 /// If str's first non-whitespace characters form a valid string (either a
790 /// single word separated by whitespace or anything inside a double-quoted
791 /// ("") or single-quoted ('') string, return true, place the string's value
792 /// (not including surrounding double quotes) in val, and additionally
793 /// modify str to skip over the parsed string if eat is also true.
794 /// Otherwise, if no string is found at the beginning of str, return false
795 /// and don't modify val or str. If keep_quotes is true, the surrounding
796 /// double quotes (if present) will be kept in val.
797 bool OIIO_API parse_string (string_view &str, string_view &val, bool eat=true,
798  QuoteBehavior keep_quotes=DeleteQuotes) noexcept;
799 
800 /// Return the first "word" (set of contiguous alphabetical characters) in
801 /// str, and additionally modify str to skip over the parsed word if eat is
802 /// also true. Otherwise, if no word is found at the beginning of str,
803 /// return an empty string_view and don't modify str.
804 string_view OIIO_API parse_word (string_view &str, bool eat=true) noexcept;
805 
806 /// If str's first non-whitespace characters form a valid C-like identifier,
807 /// return the identifier, and additionally modify str to skip over the
808 /// parsed identifier if eat is also true. Otherwise, if no identifier is
809 /// found at the beginning of str, return an empty string_view and don't
810 /// modify str.
811 string_view OIIO_API parse_identifier (string_view &str, bool eat=true) noexcept;
812 
813 /// If str's first non-whitespace characters form a valid C-like identifier,
814 /// return the identifier, and additionally modify str to skip over the
815 /// parsed identifier if eat is also true. Otherwise, if no identifier is
816 /// found at the beginning of str, return an empty string_view and don't
817 /// modify str. The 'allowed' parameter may specify a additional characters
818 /// accepted that would not ordinarily be allowed in C identifiers, for
819 /// example, parse_identifier (blah, "$:") would allow "identifiers"
820 /// containing dollar signs and colons as well as the usual alphanumeric and
821 /// underscore characters.
823  string_view allowed, bool eat = true) noexcept;
824 
825 /// If the C-like identifier at the head of str exactly matches id,
826 /// return true, and also advance str if eat is true. If it is not a match
827 /// for id, return false and do not alter str.
829  bool eat=true) noexcept;
830 
831 /// Return the characters until any character in sep is found, storing it in
832 /// str, and additionally modify str to skip over the parsed section if eat
833 /// is also true. Otherwise, if no word is found at the beginning of str,
834 /// return an empty string_view and don't modify str.
836  string_view sep=" \t\r\n", bool eat=true) noexcept;
837 
838 /// Return the characters at the head of the string that match any in set,
839 /// and additionally modify str to skip over the parsed section if eat is
840 /// also true. Otherwise, if no `set` characters are found at the beginning
841 /// of str, return an empty string_view and don't modify str.
843  string_view set, bool eat=true) noexcept;
844 
845 /// Assuming the string str starts with either '(', '[', or '{', return the
846 /// head, up to and including the corresponding closing character (')', ']',
847 /// or '}', respectively), recognizing nesting structures. For example,
848 /// parse_nested("(a(b)c)d") should return "(a(b)c)", NOT "(a(b)". Return an
849 /// empty string if str doesn't start with one of those characters, or
850 /// doesn't contain a correctly matching nested pair. If eat==true, str will
851 /// be modified to trim off the part of the string that is returned as the
852 /// match.
853 string_view OIIO_API parse_nested (string_view &str, bool eat=true) noexcept;
854 
855 
856 /// Look within `str` for the pattern:
857 /// head nonwhitespace_chars whitespace
858 /// Remove that full pattern from `str` and return the nonwhitespace
859 /// part that followed the head (or return the empty string and leave `str`
860 /// unmodified, if the head was never found).
861 OIIO_API std::string
862 excise_string_after_head (std::string& str, string_view head);
863 
864 
865 /// Converts utf-8 string to vector of unicode codepoints. This function
866 /// will not stop on invalid sequences. It will let through some invalid
867 /// utf-8 sequences like: 0xfdd0-0xfdef, 0x??fffe/0x??ffff. It does not
868 /// support 5-6 bytes long utf-8 sequences. Will skip trailing character if
869 /// there are not enough bytes for decoding a codepoint.
870 ///
871 /// N.B. Following should probably return u32string instead of taking
872 /// vector, but C++11 support is not yet stabilized across compilers.
873 /// We will eventually add that and deprecate this one, after everybody
874 /// is caught up to C++11.
875 void OIIO_API utf8_to_unicode (string_view str, std::vector<uint32_t> &uvec);
876 
877 /// Encode the string in base64.
878 /// https://en.wikipedia.org/wiki/Base64
879 std::string OIIO_API base64_encode (string_view str);
880 
881 } // namespace Strutil
882 
type
Definition: core.h:977
void print(const char *fmt, const Args &...args)
Definition: strutil.h:194
string_view OIIO_API parse_word(string_view &str, bool eat=true) noexcept
std::string sprintf(const char *fmt, const Args &...args)
Definition: strutil.h:90
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
void printf(const char *fmt, const Args &...args)
Definition: strutil.h:163
std::string upper(string_view a)
Return an all-upper case version of a (locale-independent).
Definition: strutil.h:349
OIIO_API std::vector< std::string > splits(string_view str, string_view sep="", int maxsplit=-1)
size_t operator()(string_view s) const
Definition: strutil.h:652
string_view OIIO_API strip(string_view str, string_view chars=string_view())
unsigned int from_string< unsigned int >(string_view s)
Definition: strutil.h:523
GLint first
Definition: glcorearb.h:404
std::string OIIO_API escape_chars(string_view unescaped)
STATIC_INLINE size_t Hash(const char *s, size_t len)
Definition: farmhash.h:2038
void OIIO_API remove_trailing_whitespace(string_view &str) noexcept
OIIO_API int stoi(string_view s, size_t *pos=0, int base=10)
bool OIIO_API iends_with(string_view a, string_view b)
void fprintf(FILE *file, const char *fmt, const Args &...args)
Definition: strutil.h:169
OIIO_API std::vector< string_view > splitsv(string_view str, string_view sep="", int maxsplit=-1)
const GLfloat * c
Definition: glew.h:16631
string_view OIIO_API lstrip(string_view str, string_view chars=string_view())
std::string format(const char *fmt, const Args &...args)
Definition: strutil.h:124
string_view OIIO_API parse_identifier(string_view &str, bool eat=true) noexcept
bool OIIO_API ends_with(string_view a, string_view b)
Does 'a' end with the string 'b', with a case-sensitive comparison?
std::string to_string(const T &value)
Definition: strutil.h:538
std::string format(string_view fmt, const Args &...args)
Definition: strutil.h:140
bool OIIO_API parse_string(string_view &str, string_view &val, bool eat=true, QuoteBehavior keep_quotes=DeleteQuotes) noexcept
#define OIIO_DEPRECATED(msg)
Definition: platform.h:421
GLenum src
Definition: glcorearb.h:1792
bool OIIO_API istarts_with(string_view a, string_view b)
GLdouble GLdouble t
Definition: glew.h:1403
void OIIO_API utf8_to_unicode(string_view str, std::vector< uint32_t > &uvec)
std::string OIIO_API concat(string_view s, string_view t)
OIIO_API bool string_is_float(string_view s)
std::string OIIO_API base64_encode(string_view str)
basic_string_view< char > string_view
Definition: core.h:440
void OIIO_API to_lower(std::string &a)
GLsizeiptr size
Definition: glcorearb.h:663
constexpr size_type size() const noexcept
Definition: string_view.h:140
std::string OIIO_API wordwrap(string_view src, int columns=80, int prefix=0, string_view sep=" ", string_view presep="")
float OIIO_API strtof(const char *nptr, char **endptr=nullptr) noexcept
void OIIO_API sync_output(FILE *file, string_view str)
void OIIO_API split(string_view str, std::vector< string_view > &result, string_view sep=string_view(), int maxsplit=-1)
GLuint64EXT * result
Definition: glew.h:14311
string_view OIIO_API parse_until(string_view &str, string_view sep=" \t\r\n", bool eat=true) noexcept
std::string to_string(const char *value)
Definition: strutil.h:545
std::string OIIO_API replace(string_view str, string_view pattern, string_view replacement, bool global=false)
float from_string< float >(string_view s)
Definition: strutil.h:528
GLenum GLsizei len
Definition: glew.h:7782
const GLdouble * v
Definition: glcorearb.h:836
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
string_view OIIO_API parse_nested(string_view &str, bool eat=true) noexcept
OIIO_API double stod(string_view s, size_t *pos=0)
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
void OIIO_API to_upper(std::string &a)
OIIO_CONSTEXPR14 size_t strhash(size_t len, const char *s)
Definition: strutil.h:285
unsigned int stoui(string_view s, size_t *pos=0, int base=10)
Definition: strutil.h:477
QuoteBehavior
Definition: strutil.h:788
OIIO_API char * safe_strcpy(char *dst, string_view src, size_t size) noexcept
bool OIIO_API iequals(string_view a, string_view b)
std::string OIIO_API timeintervalformat(double secs, int digits=1)
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
std::string format(const char *fmt, const Args &...args)
Definition: strutil.h:132
OIIO_API bool string_is_int(string_view s)
std::string OIIO_API vsprintf(const char *fmt, va_list ap)
string_view OIIO_API rstrip(string_view str, string_view chars=string_view())
double OIIO_API strtod(const char *nptr, char **endptr=nullptr) noexcept
bool OIIO_API parse_identifier_if(string_view &str, string_view id, bool eat=true) noexcept
T from_string(string_view s)
Definition: strutil.h:515
bool OIIO_API get_rest_arguments(const std::string &str, std::string &base, std::map< std::string, std::string > &result)
void trim_whitespace(string_view &str) noexcept
Definition: strutil.h:749
bool OIIO_API parse_float(string_view &str, float &val, bool eat=true) noexcept
void OIIO_API skip_whitespace(string_view &str) noexcept
bool OIIO_API parse_until_char(string_view &str, char c, bool eat=true) noexcept
GLdouble n
Definition: glcorearb.h:2007
bool OIIO_API contains(string_view a, string_view b)
Does 'a' contain the string 'b' within it?
bool string_is(string_view)
Definition: strutil.h:552
GLubyte * pattern
Definition: glew.h:5741
std::string OIIO_API unescape_chars(string_view escaped)
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:107
GLuint GLfloat * val
Definition: glcorearb.h:1607
std::string OIIO_API repeat(string_view str, int n)
Repeat a string formed by concatenating str n times.
std::string join(const Sequence &seq, string_view sep="")
Definition: strutil.h:400
bool OIIO_API parse_int(string_view &str, int &val, bool eat=true) noexcept
std::string lower(string_view a)
Return an all-upper case version of a (locale-independent).
Definition: strutil.h:342
int extract_from_list_string(std::vector< T, Allocator > &vals, string_view list, string_view sep=",")
Definition: strutil.h:584
constexpr size_type length() const noexcept
Definition: string_view.h:141
bool string_is< int >(string_view s)
Definition: strutil.h:556
GLsizei const GLfloat * value
Definition: glcorearb.h:823
bool string_is< float >(string_view s)
Definition: strutil.h:561
**If you just want to fire and args
Definition: thread.h:615
int from_string< int >(string_view s)
Definition: strutil.h:519
std::string OIIO_API memformat(long long bytes, int digits=1)
int16_t cl_short __attribute__((aligned(2)))
Definition: cl_platform.h:274
bool OIIO_API parse_char(string_view &str, char c, bool skip_whitespace=true, bool eat=true) noexcept
bool OIIO_API starts_with(string_view a, string_view b)
Does 'a' start with the string 'b', with a case-sensitive comparison?
bool OIIO_API icontains(string_view a, string_view b)
#define const
Definition: zconf.h:214
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:94
std::string OIIO_API vformat(const char *fmt, va_list ap)
const char * c_str() const
C++ functor for comparing two strings for equality of their characters.
Definition: strutil.h:660
OIIO_API std::string excise_string_after_head(std::string &str, string_view head)
GLenum GLenum dst
Definition: glcorearb.h:1792
GLboolean r
Definition: glcorearb.h:1221
bool OIIO_API iless(string_view a, string_view b)
bool OIIO_API parse_prefix(string_view &str, string_view prefix, bool eat=true) noexcept
OIIO_API float stof(string_view s, size_t *pos=0)
GLdouble s
Definition: glew.h:1395
C++ functor for comparing the ordering of two strings.
Definition: strutil.h:675
const charT * data() const noexcept
Definition: string_view.h:160
Definition: format.h:3611
string_view OIIO_API parse_while(string_view &str, string_view set, bool eat=true) noexcept
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:93
#define OIIO_API
Definition: export.h:65
std::basic_string< Char > sprintf(const S &format, const Args &...args)
Definition: printf.h:653