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