diff --git a/include/bx/inline/string.inl b/include/bx/inline/string.inl index 0a84264..d7108c8 100644 --- a/include/bx/inline/string.inl +++ b/include/bx/inline/string.inl @@ -187,17 +187,93 @@ namespace bx return m_0terminated; } + template + inline FixedStringT::FixedStringT() + : m_len(0) + { + } + + template + inline FixedStringT::FixedStringT(const char* _str) + : FixedStringT() + { + set(_str); + } + + template + inline FixedStringT::FixedStringT(const StringView& _str) + : FixedStringT() + { + set(_str); + } + + template + inline FixedStringT::~FixedStringT() + { + } + + template + inline void FixedStringT::set(const char* _str) + { + set(StringView(_str) ); + } + + template + inline void FixedStringT::set(const StringView& _str) + { + int32_t copied = strCopy(m_storage, MaxCapacityT, _str); + m_len = copied; + } + + template + inline void FixedStringT::append(const StringView& _str) + { + m_len += strCopy(&m_storage[m_len], MaxCapacityT-m_len, _str); + } + + template + inline void FixedStringT::clear() + { + m_len = 0; + m_storage[0] = '\0'; + } + + template + inline bool FixedStringT::isEmpty() const + { + return 0 == m_len; + } + + template + inline int32_t FixedStringT::getLength() const + { + return m_len; + } + + template + inline const char* FixedStringT::getCPtr() const + { + return m_storage; + } + + template + inline FixedStringT::operator StringView() const + { + return StringView(m_storage, m_len); + } + template inline StringT::StringT() - : StringView() + : m_ptr("") + , m_len(0) , m_capacity(0) { - clear(); } template inline StringT::StringT(const StringT& _rhs) - : StringView() + : m_ptr("") + , m_len(0) , m_capacity(0) { set(_rhs); @@ -205,7 +281,8 @@ namespace bx template inline StringT::StringT(const StringView& _rhs) - : StringView() + : m_ptr("") + , m_len(0) , m_capacity(0) { set(_rhs); @@ -264,21 +341,38 @@ namespace bx template inline void StringT::clear() { - m_0terminated = true; - if (0 != m_capacity) { free(*AllocatorT, const_cast(m_ptr) ); - StringView::clear(); + m_ptr = ""; + m_len = 0; m_capacity = 0; } } + template + inline bool StringT::isEmpty() const + { + return 0 == m_len; + } + + template + inline int32_t StringT::getLength() const + { + return m_len; + } + template inline const char* StringT::getCPtr() const { - return getPtr(); + return m_ptr; + } + + template + inline StringT::operator StringView() const + { + return StringView(m_ptr, m_len); } inline StringView strSubstr(const StringView& _str, int32_t _start, int32_t _len) diff --git a/include/bx/string.h b/include/bx/string.h index c6e8a2f..fb59b9c 100644 --- a/include/bx/string.h +++ b/include/bx/string.h @@ -137,9 +137,66 @@ namespace bx bool m_0terminated; }; - /// ASCII string + /// Fixed capacity string. + /// + template + 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 - 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. diff --git a/tests/string_test.cpp b/tests/string_test.cpp index cf100c3..6cc130e 100644 --- a/tests/string_test.cpp +++ b/tests/string_test.cpp @@ -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");