39 #ifndef __UT_StringHolder_h__
40 #define __UT_StringHolder_h__
58 #if __cplusplus >= 202002L
68 template <
typename T>
class UT_Array;
71 class ut_PatternRecord;
79 namespace UT {
inline namespace Literal {
104 , myHash(SYSstring_hash(str, myLength, true))
111 return myData ? myData :
"";
115 #if __cplusplus >= 202002L
116 template <std::same_as<const
char *> T>
123 explicit operator bool()
const {
return myLength > 0; }
125 #if __cplusplus >= 202002L
127 const char & operator[](
size_t i)
const {
return data()[i]; }
141 if (other ==
nullptr)
142 return (str.myLength == 0);
143 if (str.myData ==
nullptr)
146 if (__builtin_is_constant_evaluated())
149 for (
int32 i = 0; i < str.myLength + 1; ++i)
151 if (str.myData[i] != other[i])
156 return !strcmp(str.myData, other);
158 return !__builtin_strcmp(str.myData, other);
164 return (str == other);
169 return !(str == other);
174 return !(str == other);
189 if ((a.myLength != b.myLength) || (a.myHash != b.myHash))
195 if ((a.myData ==
nullptr) || (b.myData ==
nullptr))
200 return ! SYSmemcmp(a.myData, b.myData, a.myLength);
246 if (myStorageMode == STORE_INLINE)
247 return myDataIfInline;
264 if (myRefCount.add(-1) == 0)
268 int64 getMemoryUsage(
bool inclusive)
const;
272 return myRefCount.relaxedLoad() == 1 && myStorageMode != STORE_EXTERNAL;
277 return myDataIfInline;
282 if (myStorageMode == STORE_MALLOC && myRefCount.relaxedLoad() == 1)
284 myStorageMode = STORE_EXTERNAL;
285 return (
char*)myData;
300 char myDataIfInline[
sizeof(
const char *)];
318 _reference(str, strlen(str));
327 _reference(data, length);
358 , myLength(
s.myLength)
368 , myLength(
s.myLength)
390 , myHash(SENTINEL_HASH)
399 , myHash(str ? 0 : SENTINEL_HASH)
402 _reference(str, strlen(str));
408 return myHash == SENTINEL_HASH && !myLength;
417 myHash = SENTINEL_HASH;
424 return !myLength && myDataIfHolder && myDataIfHolder->isUnique();
433 myLength = s.myLength;
457 return myHash == s.myHash;
465 if (myHash && s.myHash && myHash != s.myHash)
474 return (!s || !*s) && !myHash;
481 if (myDataIfChars == s)
486 return ::strcmp(
c_str(), s) == 0;
510 else if (kl > minlen)
519 {
return spaceship(k) < 0; }
521 {
return spaceship(k) <= 0; }
523 {
return spaceship(k) > 0; }
525 {
return spaceship(k) >= 0; }
538 explicit operator bool()
const {
return isstring(); }
560 char separator)
const
563 pattern, case_sensitive, separator);
566 const char *separators =
", ",
567 bool *explicitly_excluded = 0,
568 int *match_index = 0,
569 ut_PatternRecord *pattern_record=
nullptr)
const
572 pattern, case_sensitive, separators, explicitly_excluded,
573 match_index, pattern_record);
576 bool *explicitly_excluded = 0,
577 int *match_index = 0,
578 ut_PatternRecord *pattern_record=
nullptr)
const
581 pattern, explicitly_excluded, match_index, pattern_record);
586 bool matchRegex(
const char *expr)
const;
594 bool isFloat(
bool skip_spaces =
false,
bool loose =
false)
const
600 #if __cplusplus >= 202002L
601 template <std::same_as<const
char *> T>
603 operator T() const noexcept
607 operator const char *()
const
619 #if __cplusplus >= 202002L
621 const char &operator[](
size_t i)
const {
return c_str()[i]; }
644 UTswap(myLength, other.myLength);
645 UTswap(myHash, other.myHash);
655 {
return myData !=
nullptr; }
659 {
return myData ==
nullptr; }
663 {
return myData ==
nullptr; }
671 if (!SYSisspace(ptr[i]))
681 const char *str =
c_str();
682 const void *
ptr = ::memchr(str, c,
length());
683 return ptr ? (
const char *)ptr - str : -1;
694 const char *found_char = strpbrk(ptr, str);
696 return found_char -
ptr;
706 if (start_offset <
length())
708 const char *str =
c_str();
709 const void *
ptr = ::memchr(str+start_offset, c,
712 return (
const char *)ptr - str;
725 const char *found_char = strpbrk(ptr+start_offset, str);
727 return found_char -
ptr;
736 const char *str =
c_str();
738 const void *
start = SYSmemrchr(str, c, n);
741 n = (
const char *)start - str;
743 if (occurrence_number <= 0)
745 start = (n == 0) ?
nullptr : SYSmemrchr(str, c, n-1);
774 return myDataIfChars;
776 else if (myDataIfHolder)
777 return myDataIfHolder->c_str();
780 #if SYS_IS_GCC_GE(6, 0) && !SYS_IS_GCC_GE(8, 0)
783 const char *
volatile empty =
"";
800 else if (myDataIfHolder)
801 return myDataIfHolder->length();
808 if (!myHash && myData)
834 int64 mem = inclusive ?
sizeof(*this) : 0;
835 if (!myLength && myDataIfHolder)
836 mem += myDataIfHolder->getMemoryUsage(
true);
845 return SYSstring_hash(str, len,
true);
854 return SYSstring_hash(str, len,
true);
866 UT_StringRef forceValidVariableName(
const char *safechars =
nullptr)
const;
881 setHolder(Holder::buildInline(src, src ? strlen(src) : 0));
886 void adoptFromMalloc(
const char *str,
exint length);
900 adoptFromMalloc(str.myData, strlen(str.myData));
904 str.myIsReference =
true;
914 char *stealAsMalloc();
917 static bool verifyStringLit();
943 if (!myLength && myDataIfHolder)
944 myDataIfHolder->incref();
950 if (!myLength && myDataIfHolder)
951 myDataIfHolder->decref();
955 void setHolder(Holder* holder)
958 myDataIfHolder = holder;
970 myDataIfHolder = Holder::buildInline(myDataIfChars, myLength);
995 static constexpr
uint32 SENTINEL_HASH = 0xdeadbeef;
1008 return ref.operator==(lit.
asRef());
1013 return ref.operator==(lit.
asRef());
1018 return ref.operator!=(lit.
asRef());
1023 return ref.operator!=(lit.
asRef());
1032 return ref.operator==(
buf);
1037 return ref.operator!=(
buf);
1046 return str.operator==(lit.
asRef());
1051 return str.operator==(lit.
asRef());
1056 return str.operator!=(lit.
asRef());
1061 return str.operator!=(lit.
asRef());
1068 return str.operator==(
buf);
1125 : UT_StringHolder(data,
exint(length)) { }
1128 : UT_StringHolder(data,
exint(length)) { }
1276 template<
typename... Args>
1279 return format(fmt, {args...});
1281 size_t format(
const char *fmt, std::initializer_list<UT::Format::ArgValue>
args);
1284 template<
typename... Args>
1288 return sprintf(fmt, {args...});
1290 size_t sprintf(
const char *fmt, std::initializer_list<UT::Format::ArgValue>
args);
1307 int strip(
const char *chars);
1330 bool trimBoundingSpace();
1336 bool trimSpace(
bool leave_single_space_between_words =
false);
1347 void getRelativePath(
const char *src_fullpath,
1348 const char *dest_fullpath,
1349 bool file_path =
false,
1350 bool allow_relative_path_from_root =
true);
1353 const char *
s, std::size_t
const length);
1355 const char *
s, std::size_t
const length);
1369 myDataIfChars = str;
1379 myHash = SYSstring_hash_literal(str);
1429 namespace UT {
inline namespace Literal {
1467 template <
typename T>
1468 struct DefaultClearer;
1479 static const bool clearNeedsDestruction =
false;
1483 #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
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
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()
bool contains(const char *pattern, bool case_sensitive=true) const
#define SYS_DEPRECATED_HDK_REPLACE(__V__, __R__)
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, float failrelative, float warnrelative, ROI roi={}, int nthreads=0)
bool isEmpty() const
Same as !isstring()
static void clear(UT_StringHolder &v)
SYS_NO_DISCARD_RESULT bool UTstringStartsWith(const T &str, const char *prefix, bool case_sensitive=true, exint len=-1)
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
PUGI__FN PUGI__UNSIGNED_OVERFLOW unsigned int hash_string(const char_t *str)
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.
bool operator!=(const char *s) const
SYS_FORCE_INLINE bool hasNonSpace() const
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
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.
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.
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)
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)
int substitute(const char *find, const char *replacement, exint count=-1)
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
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_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
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.
static SYS_FORCE_INLINE unsigned hashString(const char *str, exint len)
constexpr bool operator!=(const UT_StringLit &a, const UT_StringLit &b)
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
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.
int sprintf(const char *fmt,...) SYS_PRINTF_CHECK_ATTRIBUTE(2
bool empty() const
method name that maches std::string
int substitute(const char *find, const char *replacement, exint count=-1)
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)
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
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)
OIIO_UTIL_API const char * c_str(string_view str)
constexpr bool operator==(const UT_StringLit &a, const UT_StringLit &b)
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
const char * fcontain(const char *pattern, bool case_sensitive=true) const
SYS_FORCE_INLINE void swap(UT_StringRef &other)