Added FixedStringT.

This commit is contained in:
Branimir Karadžić
2025-09-19 20:36:42 -07:00
parent eda38395dd
commit 2fe4b15234
3 changed files with 197 additions and 17 deletions

View File

@@ -187,17 +187,93 @@ namespace bx
return m_0terminated;
}
template<uint16_t MaxCapacityT>
inline FixedStringT<MaxCapacityT>::FixedStringT()
: m_len(0)
{
}
template<uint16_t MaxCapacityT>
inline FixedStringT<MaxCapacityT>::FixedStringT(const char* _str)
: FixedStringT<MaxCapacityT>()
{
set(_str);
}
template<uint16_t MaxCapacityT>
inline FixedStringT<MaxCapacityT>::FixedStringT(const StringView& _str)
: FixedStringT<MaxCapacityT>()
{
set(_str);
}
template<uint16_t MaxCapacityT>
inline FixedStringT<MaxCapacityT>::~FixedStringT()
{
}
template<uint16_t MaxCapacityT>
inline void FixedStringT<MaxCapacityT>::set(const char* _str)
{
set(StringView(_str) );
}
template<uint16_t MaxCapacityT>
inline void FixedStringT<MaxCapacityT>::set(const StringView& _str)
{
int32_t copied = strCopy(m_storage, MaxCapacityT, _str);
m_len = copied;
}
template<uint16_t MaxCapacityT>
inline void FixedStringT<MaxCapacityT>::append(const StringView& _str)
{
m_len += strCopy(&m_storage[m_len], MaxCapacityT-m_len, _str);
}
template<uint16_t MaxCapacityT>
inline void FixedStringT<MaxCapacityT>::clear()
{
m_len = 0;
m_storage[0] = '\0';
}
template<uint16_t MaxCapacityT>
inline bool FixedStringT<MaxCapacityT>::isEmpty() const
{
return 0 == m_len;
}
template<uint16_t MaxCapacityT>
inline int32_t FixedStringT<MaxCapacityT>::getLength() const
{
return m_len;
}
template<uint16_t MaxCapacityT>
inline const char* FixedStringT<MaxCapacityT>::getCPtr() const
{
return m_storage;
}
template<uint16_t MaxCapacityT>
inline FixedStringT<MaxCapacityT>::operator StringView() const
{
return StringView(m_storage, m_len);
}
template<AllocatorI** AllocatorT>
inline StringT<AllocatorT>::StringT()
: StringView()
: m_ptr("")
, m_len(0)
, m_capacity(0)
{
clear();
}
template<AllocatorI** AllocatorT>
inline StringT<AllocatorT>::StringT(const StringT<AllocatorT>& _rhs)
: StringView()
: m_ptr("")
, m_len(0)
, m_capacity(0)
{
set(_rhs);
@@ -205,7 +281,8 @@ namespace bx
template<AllocatorI** AllocatorT>
inline StringT<AllocatorT>::StringT(const StringView& _rhs)
: StringView()
: m_ptr("")
, m_len(0)
, m_capacity(0)
{
set(_rhs);
@@ -264,21 +341,38 @@ namespace bx
template<AllocatorI** AllocatorT>
inline void StringT<AllocatorT>::clear()
{
m_0terminated = true;
if (0 != m_capacity)
{
free(*AllocatorT, const_cast<char*>(m_ptr) );
StringView::clear();
m_ptr = "";
m_len = 0;
m_capacity = 0;
}
}
template<AllocatorI** AllocatorT>
inline bool StringT<AllocatorT>::isEmpty() const
{
return 0 == m_len;
}
template<AllocatorI** AllocatorT>
inline int32_t StringT<AllocatorT>::getLength() const
{
return m_len;
}
template<AllocatorI** AllocatorT>
inline const char* StringT<AllocatorT>::getCPtr() const
{
return getPtr();
return m_ptr;
}
template<AllocatorI** AllocatorT>
inline StringT<AllocatorT>::operator StringView() const
{
return StringView(m_ptr, m_len);
}
inline StringView strSubstr(const StringView& _str, int32_t _start, int32_t _len)

View File

@@ -137,9 +137,66 @@ namespace bx
bool m_0terminated;
};
/// ASCII string
/// Fixed capacity string.
///
template<uint16_t MaxCapacityT>
class FixedStringT
{
public:
///
FixedStringT();
///
FixedStringT(const char* _str);
///
FixedStringT(const StringView& _str);
///
~FixedStringT();
///
void set(const char* _str);
///
void set(const StringView& _str);
///
void append(const StringView& _str);
///
void clear();
/// Returns `true` if string is empty.
///
bool isEmpty() const;
/// Returns string length.
///
int32_t getLength() const;
/// Returns zero-terminated C string pointer.
///
const char* getCPtr() const;
/// Implicitly converts FixedStringT to StringView.
///
operator StringView() const;
private:
char m_storage[MaxCapacityT];
int32_t m_len;
};
///
using FixedString64 = FixedStringT<64>;
using FixedString256 = FixedStringT<256>;
using FixedString1024 = FixedStringT<1024>;
/// Dynamic string
///
template<AllocatorI** AllocatorT>
class StringT : public StringView
class StringT
{
public:
///
@@ -169,12 +226,26 @@ namespace bx
///
void clear();
/// Returns `true` if string is empty.
///
bool isEmpty() const;
/// Returns string length.
///
int32_t getLength() const;
/// Returns zero-terminated C string pointer.
///
const char* getCPtr() const;
/// Implicitly converts StringT to StringView.
///
operator StringView() const;
protected:
int32_t m_capacity;
const char* m_ptr;
int32_t m_len;
int32_t m_capacity;
};
/// Returns true if character is part of white space set.

View File

@@ -498,7 +498,7 @@ TEST_CASE("StringView", "[string]")
st.append(bx::StringView("test", 2) );
REQUIRE(10 == st.getLength() );
REQUIRE(0 == bx::strCmp(st.getPtr(), "testtestte") );
REQUIRE(0 == bx::strCmp(st.getCPtr(), "testtestte") );
st.clear();
REQUIRE(0 == st.getLength() );
@@ -628,18 +628,32 @@ TEST_CASE("0terminated", "[string]")
typedef bx::StringT<&g_allocator> String;
String st;
REQUIRE(st.is0Terminated() );
st = strTrimPrefix(t0, "13");
REQUIRE(2 == st.getLength() );
REQUIRE(st.is0Terminated() );
st = strTrimSuffix(t0, "89");
REQUIRE(2 == st.getLength() );
REQUIRE(st.is0Terminated() );
}
TEST(tinystl_string_constructor) {
TEST_CASE("FixedStringT", "[string]")
{
bx::FixedString64 fs64("1389");
bx::FixedString256 fs256(fs64);
REQUIRE(0 == strCmp(fs64, fs256) );
REQUIRE(0 == strCmp(fs64, "1389") );
REQUIRE(0 == strCmp(fs256, "1389") );
fs64.append("9831");
REQUIRE(8 == fs64.getLength() );
REQUIRE(0 != strCmp(fs64, fs256) );
REQUIRE(0 != strCmp(fs64, "13899831") );
}
TEST(tinystl_string_constructor)
{
using tinystl::string;
{
string s;
@@ -672,7 +686,8 @@ TEST(tinystl_string_constructor) {
}
}
TEST(tinystl_string_assign) {
TEST(tinystl_string_assign)
{
using tinystl::string;
{
const string other("hello");