39 #ifndef __UT_StringHolder_h__
40 #define __UT_StringHolder_h__
65 template <
typename T>
class UT_Array;
68 class ut_PatternRecord;
76 namespace UT {
inline namespace Literal {
101 , myHash(SYSstring_hash(str, myLength, true))
108 return myData ? myData :
"";
123 if (myLength != other.myLength || myHash != other.myHash)
126 if (myData ==
nullptr || other.myData ==
nullptr)
128 return !SYSmemcmp(myData, other.myData, myLength);
132 return !(*
this == other);
139 if (other ==
nullptr)
140 return (str.myLength == 0);
141 if (str.myData ==
nullptr)
144 if (__builtin_is_constant_evaluated())
147 for (
int32 i = 0; i < str.myLength + 1; ++i)
149 if (str.myData[i] != other[i])
154 return !strcmp(str.myData, other);
156 return !__builtin_strcmp(str.myData, other);
162 return (str == other);
167 return !(str == other);
172 return !(str == other);
211 if (myStorageMode == STORE_INLINE)
212 return myDataIfInline;
229 if (myRefCount.add(-1) == 0)
233 int64 getMemoryUsage(
bool inclusive)
const;
237 return myRefCount.relaxedLoad() == 1 && myStorageMode != STORE_EXTERNAL;
242 return myDataIfInline;
247 if (myStorageMode == STORE_MALLOC && myRefCount.relaxedLoad() == 1)
249 myStorageMode = STORE_EXTERNAL;
250 return (
char*)myData;
265 char myDataIfInline[
sizeof(
const char *)];
283 _reference(str, strlen(str));
292 _reference(data, length);
323 , myLength(
s.myLength)
333 , myLength(
s.myLength)
355 , myHash(SENTINEL_HASH)
364 , myHash(str ? 0 : SENTINEL_HASH)
367 _reference(str, strlen(str));
373 return myHash == SENTINEL_HASH && !myLength;
382 myHash = SENTINEL_HASH;
389 return !myLength && myDataIfHolder && myDataIfHolder->isUnique();
398 myLength = s.myLength;
422 return myHash == s.myHash;
430 if (myHash && s.myHash && myHash != s.myHash)
433 return tl == s.
length() && SYSmemcmp(c_str(), s.
c_str(), tl) == 0;
439 return (!s || !*s) && !myHash;
446 if (myDataIfChars == s)
451 return ::strcmp(c_str(), s) == 0;
454 {
return operator==(s.
buffer()); }
457 {
return !operator==(s); }
459 {
return !operator==(s); }
461 {
return operator!=(s.
buffer()); }
472 int r = SYSmemcmp(c_str(), k.
c_str(), minlen);
475 else if (kl > minlen)
484 {
return spaceship(k) < 0; }
486 {
return spaceship(k) <= 0; }
488 {
return spaceship(k) > 0; }
490 {
return spaceship(k) >= 0; }
525 char separator)
const
528 pattern, case_sensitive, separator);
531 const char *separators =
", ",
532 bool *explicitly_excluded = 0,
533 int *match_index = 0,
534 ut_PatternRecord *pattern_record=
nullptr)
const
537 pattern, case_sensitive, separators, explicitly_excluded,
538 match_index, pattern_record);
541 bool *explicitly_excluded = 0,
542 int *match_index = 0,
543 ut_PatternRecord *pattern_record=
nullptr)
const
546 pattern, explicitly_excluded, match_index, pattern_record);
551 bool matchRegex(
const char *expr)
const;
559 bool isFloat(
bool skip_spaces =
false,
bool loose =
false)
const
566 operator const char *()
const
597 UTswap(myLength, other.myLength);
598 UTswap(myHash, other.myHash);
608 {
return myData !=
nullptr; }
612 {
return myData ==
nullptr; }
616 {
return myData ==
nullptr; }
622 const char *
ptr = c_str();
624 if (!SYSisspace(ptr[i]))
634 const char *str = c_str();
635 const void *
ptr = ::memchr(str, c,
length());
636 return ptr ? (
const char *)ptr - str : -1;
646 const char *
ptr = c_str();
647 const char *found_char = strpbrk(ptr, str);
649 return found_char -
ptr;
659 if (start_offset <
length())
661 const char *str = c_str();
662 const void *
ptr = ::memchr(str+start_offset, c,
665 return (
const char *)ptr - str;
677 const char *
ptr = c_str();
678 const char *found_char = strpbrk(ptr+start_offset, str);
680 return found_char -
ptr;
689 const char *str = c_str();
691 const void *
start = SYSmemrchr(str, c, n);
694 n = (
const char *)start - str;
696 if (occurrence_number <= 0)
698 start = (n == 0) ?
nullptr : SYSmemrchr(str, c, n-1);
727 return myDataIfChars;
729 else if (myDataIfHolder)
730 return myDataIfHolder->c_str();
733 #if SYS_IS_GCC_GE(6, 0) && !SYS_IS_GCC_GE(8, 0)
736 const char *
volatile empty =
"";
753 else if (myDataIfHolder)
754 return myDataIfHolder->length();
761 if (!myHash && myData)
787 int64 mem = inclusive ?
sizeof(*this) : 0;
788 if (!myLength && myDataIfHolder)
789 mem += myDataIfHolder->getMemoryUsage(
true);
798 return SYSstring_hash(str, len,
true);
811 UT_StringRef forceValidVariableName(
const char *safechars =
nullptr)
const;
826 setHolder(Holder::buildInline(src, src ? strlen(src) : 0));
831 void adoptFromMalloc(
const char *str,
exint length);
845 adoptFromMalloc(str.myData, strlen(str.myData));
849 str.myIsReference =
true;
859 char *stealAsMalloc();
862 static bool verifyStringLit();
888 if (!myLength && myDataIfHolder)
889 myDataIfHolder->incref();
895 if (!myLength && myDataIfHolder)
896 myDataIfHolder->decref();
900 void setHolder(Holder* holder)
903 myDataIfHolder = holder;
915 myDataIfHolder = Holder::buildInline(myDataIfChars, myLength);
940 static constexpr
uint32 SENTINEL_HASH = 0xdeadbeef;
953 return ref.operator==(lit.
asRef());
958 return ref.operator==(lit.
asRef());
963 return ref.operator!=(lit.
asRef());
968 return ref.operator!=(lit.
asRef());
977 return str.operator==(lit.
asRef());
982 return str.operator==(lit.
asRef());
987 return str.operator!=(lit.
asRef());
992 return str.operator!=(lit.
asRef());
1050 : UT_StringHolder(data,
exint(length)) { }
1053 : UT_StringHolder(data,
exint(length)) { }
1201 template<
typename... Args>
1204 return format(fmt, {args...});
1206 size_t format(
const char *fmt, std::initializer_list<UT::Format::ArgValue>
args);
1209 template<
typename... Args>
1213 return sprintf(fmt, {args...});
1215 size_t sprintf(
const char *fmt, std::initializer_list<UT::Format::ArgValue>
args);
1231 int substitute(const
char *
find, const
char *replacement,
bool all)
1233 return substitute(find, replacement, !all ? 1 : -1);
1239 int strip(
const char *chars);
1262 bool trimBoundingSpace();
1268 bool trimSpace(
bool leave_single_space_between_words =
false);
1272 const char *
s, std::size_t
const length);
1274 const char *
s, std::size_t
const length);
1288 myDataIfChars = str;
1298 myHash = SYSstring_hash_literal(str);
1345 namespace UT {
inline namespace Literal {
1383 template <
typename T>
1384 struct DefaultClearer;
1395 static const bool clearNeedsDestruction =
false;
1399 #endif // __UT_StringHolder_h__
SYS_FORCE_INLINE UT_StringHolder(UT_StringReferenceType, const UT_String &str)
This will make a shallow reference to the contents of the string.
bool match(const char *pattern, bool case_sensitive=true) const
std::string toStdString() const
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
void adoptFromString(UT_String &str)
SYS_FORCE_INLINE UT_StringHolder(const UT_StringHolder &str)
Makes a copy of the provided string.
std::string ignore_case(std::string item)
Helper function to allow ignore_case to be passed to IsMember or Transform.
SYS_FORCE_INLINE const_iterator begin() const
GLenum GLuint GLenum GLsizei const GLchar * buf
SYS_FORCE_INLINE const char * nonNullBuffer() const
#define SYS_STATIC_ASSERT(expr)
const char * fcontain(const char *pattern, bool case_sensitive=true) const
SYS_FORCE_INLINE exint findCharIndex(char c, exint start_offset) const
Find the location of the character (or -1 if not found)
size_t operator()(const UT_StringRef &s) const
friend void swap(UT_StringRef &a, UT_StringRef &b)
Friend specialization of std::swap() to use UT_StringRef::swap()
SYS_FORCE_INLINE UT_StringRef(const char *data, exint length)
SYS_FORCE_INLINE constexpr exint length() const
bool multiMatch(const char *pattern, bool case_sensitive, char separator) const
SYS_FORCE_INLINE UT_StringHolder(UT_StringLiteralType, const char *str, size_t length)
void harden(const char *src)
getFileOption("OpenEXR:storage") storage
int substitute(const char *find, const char *replacement, int count=-1)
SYS_FORCE_INLINE UT_StringHolder(const char *data, exint length)
Will make a copy of the provided string.
SYS_FORCE_INLINE UT_StringHolder()
SYS_NO_DISCARD_RESULT bool UTstringEndsWith(const T &str, const char *suffix, bool case_sensitive=true, exint len=-1)
UT_StringLiteralType
A marker enum to use this constructor.
SYS_FORCE_INLINE void clear()
GLsizei const GLchar *const * string
bool contains(const char *pattern, bool case_sensitive=true) const
#define SYS_DEPRECATED_HDK_REPLACE(__V__, __R__)
bool isEmpty() const
Same as !isstring()
static void clear(UT_StringHolder &v)
bool isFloat(bool skip_spaces=false, bool loose=false) const
Determine if string can be seen as a single floating point number.
bool multiMatch(const char *pattern, bool case_sensitive=true, const char *separators=", ", bool *explicitly_excluded=0, int *match_index=0, ut_PatternRecord *pattern_record=nullptr) const
SYS_FORCE_INLINE void swap(UT_StringHolder &other)
GLboolean GLboolean GLboolean GLboolean a
void swap(T &lhs, T &rhs)
GLuint GLsizei GLsizei * length
static void clearConstruct(UT_StringHolder *p)
SYS_FORCE_INLINE UT_StringRef & operator=(UT_StringRef &&s)
bool endsWith(const UT_StringView &suffix, bool case_sense=true) const
bool equal(const UT_StringRef &str, bool ignore_case=false) const
SYS_FORCE_INLINE UT_StringHolder(const char *data, uint64 length)
SYS_FORCE_INLINE UT_StringRef(UT_StringRef &&s) noexcept
Move constructor. Steals the working data from the original.
SYS_FORCE_INLINE constexpr bool operator==(const UT_StringLit &other) const
bool operator!=(const char *s) const
SYS_FORCE_INLINE bool hasNonSpace() const
unsigned long long uint64
bool match(const char *pattern, bool case_sensitive=true) const
SYS_FORCE_INLINE exint findCharIndex(const char *str) const
Find the first location of any of the characters in the str passed in.
SYS_FORCE_INLINE size_t tbb_hasher(const UT_StringRef &s)
SIM_API const UT_StringHolder all
constexpr SYS_FORCE_INLINE UT_StringLit()
SYS_FORCE_INLINE const char * data() const
SYS_FORCE_INLINE constexpr uint32 hash() const
SYS_FORCE_INLINE UT_StringRef(const UT_StringLit &lit)
Construct from string literal.
int substitute(const char *find, const char *replacement, int count=-1)
PUGI__FN unsigned int hash_string(const char_t *str)
SYS_FORCE_INLINE const UT_StringHolder & UTmakeUnsafeRefHash(const UT_StringRef &ref)
bool load(UT_IStream &is)
Load string from stream. Use is.eof() to check eof status.
bool contains(const char *pattern, bool case_sensitive=true) const
#define SYS_DEPRECATED_REPLACE(__V__, __R__)
constexpr SYS_FORCE_INLINE UT_StringLit(const char(&str)[N])
std::ostream & operator<<(std::ostream &ostr, const DataType &a)
SYS_FORCE_INLINE const_iterator end() const
SYS_NO_DISCARD_RESULT SYS_FORCE_INLINE const char * data() const noexcept
Returns a pointer to the first character of a view.
void saveAscii(std::ostream &os) const
UT_StringRef & operator=(const UT_StringRef &s)
Shares a reference with the source.
SYS_FORCE_INLINE UT_StringHolder(const UT_String &str)
Will make a copy of the provided string.
bool isInteger(bool skip_spaces=false) const
Determine if string can be seen as a single integer number.
const char * buffer() const
SYS_FORCE_INLINE UT_StringRef(UT_StringSentinelType)
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, ROI roi={}, int nthreads=0)
A utility class to do read-only operations on a subset of an existing string.
SYS_FORCE_INLINE size_t hash_value(const UT_StringRef &str)
UT_StringHolder(UT_String &&str)
Attempts to steal the string's buffer.
SYS_NO_DISCARD_RESULT SYS_FORCE_INLINE exint length() const
Returns the length of the string in bytes.
SYS_FORCE_INLINE UT_StringHolder(const std::string &str)
Will make a copy of the provided string.
bool operator==(const UT_StringRef &s) const
int compare(const UT_StringRef &str, bool ignore_case=false) const
OIIO_FORCEINLINE const vint4 & operator+=(vint4 &a, const vint4 &b)
int64 getMemoryUsage(bool inclusive) const
SYS_FORCE_INLINE exint findCharIndex(char c) const
Find the location of the character (or -1 if not found)
SYS_FORCE_INLINE const char * buffer() const
SYS_NO_DISCARD_RESULT bool UTstringIsFloat(const StringT &str, bool skip_spaces=false, bool loose=false, bool allow_underscore=false)
friend void swap(UT_StringHolder &a, UT_StringHolder &b)
SYS_FORCE_INLINE UT_StringRef(UT_StringSentinelType, const char *str)
str==nullptr turns into sentinel, otherwise act like UT_StringRef(str)
SYS_FORCE_INLINE UT_StringHolder(const char *data, uint32 length)
static const UT_StringHolder theEmptyString
SYS_FORCE_INLINE UT_StringRef(const UT_StringRef &s) noexcept
Shares a reference with the source.
bool operator>=(const UT_StringRef &k) const
const char * findWord(const char *word) const
SYS_FORCE_INLINE const UT_StringHolder & UTmakeUnsafeRef(const UT_StringRef &ref)
Convert a UT_StringRef into a UT_StringHolder that is a shallow reference.
GLint GLint GLsizei GLint GLenum format
SYS_NO_DISCARD_RESULT int UTstringCountChar(const StringT &str, int c)
SYS_FORCE_INLINE UT_StringRef()
SYS_NO_DISCARD_RESULT bool UTstringStartsWith(const T &str, const char *prefix, bool case_sensitive=true, exint len=-1)
SYS_FORCE_INLINE UT_StringHolder & operator=(UT_StringHolder &&s)
void harden()
Take shallow copy and make it deep.
SYS_FORCE_INLINE void makeSentinel()
void saveAscii(std::ostream &os) const
bool operator!=(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Inequality operator, does exact floating point comparisons.
SYS_FORCE_INLINE exint findCharIndex(const char *str, exint start_offset) const
Find the first location of any of the characters in the str passed in.
SYS_FORCE_INLINE UT_StringHolder(UT_StringHolder &&a) noexcept
Move constructor. Steals the working data from the original.
#define SYS_NO_DISCARD_RESULT
static SYS_FORCE_INLINE unsigned hash_string(const char *str, exint len)
SYS_FORCE_INLINE const char * c_str() const
SYS_FORCE_INLINE bool isSentinel() const
SYS_FORCE_INLINE constexpr const char * data() const
UT_StringHolder(UT_StringRef &&ref)
int spaceship(const UT_StringRef &k) const
friend SYS_FORCE_INLINE constexpr bool operator!=(const UT_StringLit &str, const char *other)
size_t format(const char *fmt, const Args &...args)
Format a string using the same formatting codes as UTformat.
friend SYS_FORCE_INLINE constexpr bool operator==(const char *other, const UT_StringLit &str)
SYS_FORCE_INLINE constexpr const char * c_str() const
bool operator<=(const UT_StringRef &k) const
OIIO_FORCEINLINE vint4 operator>>(const vint4 &a, const unsigned int bits)
GLboolean GLboolean GLboolean b
const char * findWord(const char *word) const
bool operator<(const UT_StringRef &k) const
bool operator!=(const UT_StringRef &s) const
void fastReferenceWithStrlen(const char *src, exint length)
old name of method:
SYS_NO_DISCARD_RESULT bool UTstringIsInteger(const StringT &str, bool skip_spaces=false)
SYS_FORCE_INLINE UT_StringHolder(const char *data, int32 length)
void saveBinary(std::ostream &os) const
Save string to binary stream.
SYS_FORCE_INLINE constexpr bool operator!=(const UT_StringLit &other) const
int sprintf(const char *fmt,...) SYS_PRINTF_CHECK_ATTRIBUTE(2
bool empty() const
method name that maches std::string
SYS_FORCE_INLINE UT_StringHolder(UT_StringReferenceType, const UT_StringRef &ref)
Makes a shallow reference to the contents of the UT_StringRef.
void saveBinary(std::ostream &os) const
Save string to binary stream.
friend void swap(UT_StringHolder &a, UT_StringRef &b)
SYS_FORCE_INLINE UT_StringHolder(UT_StringSentinelType sentinel)
Construct as a sentinel value.
SYS_FORCE_INLINE const UT_StringRef & asRef() const
static int compareNumberedString(const char *s1, const char *s2, bool case_sensitive=true, bool allow_negatives=false)
SYS_FORCE_INLINE UT_StringRef(const UT_String &str)
This will make a shallow reference to the contents of the string.
bool operator>(const UT_StringRef &k) const
static bool isClear(const UT_StringHolder &v)
SYS_FORCE_INLINE ~UT_StringRef()
size_t operator()(const UT_StringHolder &s) const
friend SYS_FORCE_INLINE constexpr bool operator!=(const char *other, const UT_StringLit &str)
bool operator==(const UT_String &s) const
bool load(UT_IStream &is)
Load string from stream. Use is.eof() to check eof status.
UT_StringHolder(const UT_StringRef &ref)
bool multiMatch(const char *pattern, bool case_sensitive, char separator) const
SYS_FORCE_INLINE exint lastCharIndex(char c, int occurrence_number=1) const
bool operator()(const UT_StringRef &s1, const UT_StringRef &s2) const
int SYSstrcasecmp(const char *a, const char *b)
friend class UT_StringHolder
SYS_FORCE_INLINE UT_StringHolder(UT_StringReferenceType, const char *str)
Will make a shallow reference.
SYS_FORCE_INLINE bool UTisstring(const char *s)
SYS_FORCE_INLINE const UT_StringHolder & asHolder() const
SYS_FORCE_INLINE exint countChar(char c) const
Count the number of times the character c occurs.
GA_API const UT_StringHolder N
const char * const_iterator
Iterators.
SYS_FORCE_INLINE UT_StringRef(const char *str)
Will make a shallow reference.
**If you just want to fire and args
void reference(const char *src)
SYS_FORCE_INLINE constexpr const char * buffer() const
SYS_FORCE_INLINE void swap(UT_StringRef &other)
auto sprintf(const S &fmt, const T &...args) -> std::basic_string< Char >
string_view OIIO_UTIL_API strip(string_view str, string_view chars=string_view())
friend SYS_FORCE_INLINE constexpr bool operator==(const UT_StringLit &str, const char *other)
bool startsWith(const UT_StringView &pfx, bool case_sense=true) const
Imported from UT_String.
that also have some descendant prim *whose name begins with which in turn has a child named baz where *the predicate and *a name There is also one special expression reference
static Holder * buildInline(const char *str, exint length)
SYS_FORCE_INLINE UT_StringHolder(const char *str)
Will make a copy of the provided string.
const char * c_str() const
bool operator==(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Equality operator, does exact floating point comparisons.
const char * myDataIfChars
SYS_FORCE_INLINE UT_StringRef(const std::string &str)
This will make a shallow reference to the contents of the string.
bool operator!=(const UT_String &s) const
SYS_FORCE_INLINE bool isstring() const
bool operator==(const char *s) const
SYS_FORCE_INLINE UT_StringHolder(UT_StringReferenceType, const UT_WorkBuffer &str)
This will make a shallow reference to the contents of the string.
bool multiMatch(const UT_StringMMPattern &pattern, bool *explicitly_excluded=0, int *match_index=0, ut_PatternRecord *pattern_record=nullptr) const
SYS_FORCE_INLINE UT_StringHolder(UT_StringReferenceType, const std::string &str)
This will make a shallow reference to the contents of the string.
bool isUnique() const
Returns true this object is the sole owner of the underlying string.
static const UT_StringHolder theSentinel
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
const char * fcontain(const char *pattern, bool case_sensitive=true) const
SYS_FORCE_INLINE void swap(UT_StringRef &other)
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.