SmallString: Add missing methods

This commit is contained in:
Stenzek 2024-04-07 20:39:00 +10:00
parent daab121a14
commit 6b7cf6a432
No known key found for this signature in database
2 changed files with 143 additions and 9 deletions

View file

@ -455,7 +455,13 @@ bool SmallStringBase::equals(const SmallStringBase& str) const
bool SmallStringBase::equals(const std::string_view str) const
{
return (m_length == static_cast<u32>(str.length()) &&
(m_length == 0 || CASE_N_COMPARE(m_buffer, str.data(), m_length) == 0));
(m_length == 0 || std::memcmp(m_buffer, str.data(), m_length) == 0));
}
bool SmallStringBase::equals(const std::string& str) const
{
return (m_length == static_cast<u32>(str.length()) &&
(m_length == 0 || std::memcmp(m_buffer, str.data(), m_length) == 0));
}
bool SmallStringBase::iequals(const char* otherText) const
@ -477,24 +483,108 @@ bool SmallStringBase::iequals(const std::string_view str) const
(m_length == 0 || CASE_N_COMPARE(m_buffer, str.data(), m_length) == 0));
}
int SmallStringBase::compare(const SmallStringBase& str) const
bool SmallStringBase::iequals(const std::string& str) const
{
return std::strcmp(m_buffer, str.m_buffer);
return (m_length == static_cast<u32>(str.length()) &&
(m_length == 0 || CASE_N_COMPARE(m_buffer, str.data(), m_length) == 0));
}
int SmallStringBase::compare(const char* otherText) const
{
return std::strcmp(m_buffer, otherText);
return compare(std::string_view(otherText));
}
int SmallStringBase::compare(const SmallStringBase& str) const
{
if (m_length == 0)
return (str.m_length == 0) ? 0 : -1;
else if (str.m_length == 0)
return 1;
const int res = std::strncmp(m_buffer, str.m_buffer, std::min(m_length, str.m_length));
if (m_length == str.m_length || res != 0)
return res;
else
return (m_length > str.m_length) ? 1 : -1;
}
int SmallStringBase::compare(const std::string_view str) const
{
const u32 slength = static_cast<u32>(str.length());
if (m_length == 0)
return (slength == 0) ? 0 : -1;
else if (slength == 0)
return 1;
const int res = std::strncmp(m_buffer, str.data(), std::min(m_length, slength));
if (m_length == slength || res != 0)
return res;
else
return (m_length > slength) ? 1 : -1;
}
int SmallStringBase::icompare(const SmallStringBase& otherString) const
int SmallStringBase::compare(const std::string& str) const
{
return CASE_COMPARE(m_buffer, otherString.m_buffer);
const u32 slength = static_cast<u32>(str.length());
if (m_length == 0)
return (slength == 0) ? 0 : -1;
else if (slength == 0)
return 1;
const int res = std::strncmp(m_buffer, str.data(), std::min(m_length, slength));
if (m_length == slength || res != 0)
return res;
else
return (m_length > slength) ? 1 : -1;
}
int SmallStringBase::icompare(const char* otherText) const
{
return CASE_COMPARE(m_buffer, otherText);
return icompare(std::string_view(otherText));
}
int SmallStringBase::icompare(const SmallStringBase& str) const
{
if (m_length == 0)
return (str.m_length == 0) ? 0 : -1;
else if (str.m_length == 0)
return 1;
const int res = CASE_N_COMPARE(m_buffer, str.m_buffer, std::min(m_length, str.m_length));
if (m_length == str.m_length || res != 0)
return res;
else
return (m_length > str.m_length) ? 1 : -1;
}
int SmallStringBase::icompare(const std::string_view str) const
{
const u32 slength = static_cast<u32>(str.length());
if (m_length == 0)
return (slength == 0) ? 0 : -1;
else if (slength == 0)
return 1;
const int res = CASE_N_COMPARE(m_buffer, str.data(), std::min(m_length, slength));
if (m_length == slength || res != 0)
return res;
else
return (m_length > slength) ? 1 : -1;
}
int SmallStringBase::icompare(const std::string& str) const
{
const u32 slength = static_cast<u32>(str.length());
if (m_length == 0)
return (slength == 0) ? 0 : -1;
else if (slength == 0)
return 1;
const int res = CASE_N_COMPARE(m_buffer, str.data(), std::min(m_length, slength));
if (m_length == slength || res != 0)
return res;
else
return (m_length > slength) ? 1 : -1;
}
bool SmallStringBase::starts_with(const char* str, bool case_sensitive) const
@ -527,6 +617,16 @@ bool SmallStringBase::starts_with(const std::string_view str, bool case_sensitiv
(CASE_N_COMPARE(str.data(), m_buffer, other_length) == 0);
}
bool SmallStringBase::starts_with(const std::string& str, bool case_sensitive) const
{
const u32 other_length = static_cast<u32>(str.length());
if (other_length > m_length)
return false;
return (case_sensitive) ? (std::strncmp(str.data(), m_buffer, other_length) == 0) :
(CASE_N_COMPARE(str.data(), m_buffer, other_length) == 0);
}
bool SmallStringBase::ends_with(const char* str, bool case_sensitive) const
{
const u32 other_length = static_cast<u32>(std::strlen(str));
@ -560,6 +660,17 @@ bool SmallStringBase::ends_with(const std::string_view str, bool case_sensitive)
(CASE_N_COMPARE(str.data(), m_buffer + start_offset, other_length) == 0);
}
bool SmallStringBase::ends_with(const std::string& str, bool case_sensitive) const
{
const u32 other_length = static_cast<u32>(str.length());
if (other_length > m_length)
return false;
const u32 start_offset = m_length - other_length;
return (case_sensitive) ? (std::strncmp(str.data(), m_buffer + start_offset, other_length) == 0) :
(CASE_N_COMPARE(str.data(), m_buffer + start_offset, other_length) == 0);
}
void SmallStringBase::clear()
{
// in debug, zero whole string, in release, zero only the first character
@ -601,6 +712,16 @@ s32 SmallStringBase::find(const char* str, u32 offset) const
return at ? static_cast<s32>(at - m_buffer) : -1;
}
u32 SmallStringBase::count(char ch) const
{
const char* ptr = m_buffer;
const char* end = ptr + m_length;
u32 count = 0;
while (ptr != end)
count += static_cast<u32>(*(ptr++) == ch);
return count;
}
void SmallStringBase::resize(u32 new_size, char fill, bool shrink_if_smaller)
{
// if going larger, or we don't own the buffer, realloc

View file

@ -102,25 +102,31 @@ public:
bool equals(const char* str) const;
bool equals(const SmallStringBase& str) const;
bool equals(const std::string_view str) const;
bool equals(const std::string& str) const;
bool iequals(const char* str) const;
bool iequals(const SmallStringBase& str) const;
bool iequals(const std::string_view str) const;
bool iequals(const std::string& str) const;
// numerical compares
int compare(const char* str) const;
int compare(const SmallStringBase& str) const;
int compare(const std::string_view str) const;
int compare(const std::string& str) const;
int icompare(const char* str) const;
int icompare(const SmallStringBase& str) const;
int icompare(const std::string_view str) const;
int icompare(const std::string& str) const;
// starts with / ends with
bool starts_with(const char* str, bool case_sensitive = true) const;
bool starts_with(const std::string_view str, bool case_sensitive = true) const;
bool starts_with(const SmallStringBase& str, bool case_sensitive = true) const;
bool starts_with(const std::string_view str, bool case_sensitive = true) const;
bool starts_with(const std::string& str, bool case_sensitive = true) const;
bool ends_with(const char* str, bool case_sensitive = true) const;
bool ends_with(const std::string_view str, bool case_sensitive = true) const;
bool ends_with(const SmallStringBase& str, bool case_sensitive = true) const;
bool ends_with(const std::string_view str, bool case_sensitive = true) const;
bool ends_with(const std::string& str, bool case_sensitive = true) const;
// searches for a character inside a string
// rfind is the same except it starts at the end instead of the start
@ -133,6 +139,9 @@ public:
// returns -1 if it is not found, otherwise the offset in the string
s32 find(const char* str, u32 offset = 0) const;
// returns the number of instances of the specified character
u32 count(char ch) const;
// removes characters from string
void erase(s32 offset, s32 count = std::numeric_limits<s32>::max());
@ -182,15 +191,19 @@ public:
ALWAYS_INLINE bool operator==(const char* str) const { return equals(str); }
ALWAYS_INLINE bool operator==(const SmallStringBase& str) const { return equals(str); }
ALWAYS_INLINE bool operator==(const std::string_view str) const { return equals(str); }
ALWAYS_INLINE bool operator==(const std::string& str) const { return equals(str); }
ALWAYS_INLINE bool operator!=(const char* str) const { return !equals(str); }
ALWAYS_INLINE bool operator!=(const SmallStringBase& str) const { return !equals(str); }
ALWAYS_INLINE bool operator!=(const std::string_view str) const { return !equals(str); }
ALWAYS_INLINE bool operator!=(const std::string& str) const { return !equals(str); }
ALWAYS_INLINE bool operator<(const char* str) const { return (compare(str) < 0); }
ALWAYS_INLINE bool operator<(const SmallStringBase& str) const { return (compare(str) < 0); }
ALWAYS_INLINE bool operator<(const std::string_view str) const { return (compare(str) < 0); }
ALWAYS_INLINE bool operator<(const std::string& str) const { return (compare(str) < 0); }
ALWAYS_INLINE bool operator>(const char* str) const { return (compare(str) > 0); }
ALWAYS_INLINE bool operator>(const SmallStringBase& str) const { return (compare(str) > 0); }
ALWAYS_INLINE bool operator>(const std::string_view str) const { return (compare(str) > 0); }
ALWAYS_INLINE bool operator>(const std::string& str) const { return (compare(str) > 0); }
SmallStringBase& operator=(const SmallStringBase& copy);
SmallStringBase& operator=(const char* str);