From d40316270172b66935b7a4c606f8cd2e8b8fc475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=80=D0=B0=D0=BD=D0=B8=D0=BC=D0=B8=D1=80=20=D0=9A?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D1=9F=D0=B8=D1=9B?= Date: Thu, 4 May 2023 20:09:54 -0700 Subject: [PATCH] Added bx::StringLiteral. --- include/bx/inline/sort.inl | 6 ++++++ include/bx/inline/string.inl | 31 +++++++++++++++++++++++++++++++ include/bx/string.h | 35 +++++++++++++++++++++++++++++++++++ src/string.cpp | 28 ++++++++++++---------------- tests/string_test.cpp | 29 +++++++++++++++++++++++++++++ 5 files changed, 113 insertions(+), 16 deletions(-) diff --git a/include/bx/inline/sort.inl b/include/bx/inline/sort.inl index 3b47e1e..6a4ca7f 100644 --- a/include/bx/inline/sort.inl +++ b/include/bx/inline/sort.inl @@ -29,6 +29,12 @@ namespace bx return strCmp(*(const char**)_lhs, *(const char**)_rhs); } + template<> + inline int32_t compareAscending(const void* _lhs, const void* _rhs) + { + return strCmp(*(const StringLiteral*)_lhs, *(const StringLiteral*)_rhs); + } + template<> inline int32_t compareAscending(const void* _lhs, const void* _rhs) { diff --git a/include/bx/inline/string.inl b/include/bx/inline/string.inl index a669460..60d17e5 100644 --- a/include/bx/inline/string.inl +++ b/include/bx/inline/string.inl @@ -37,11 +37,42 @@ namespace bx va_end(argList); } + inline constexpr StringLiteral::StringLiteral() + : m_ptr("") + , m_len(0) + { + } + + template + inline constexpr StringLiteral::StringLiteral(const char (&str)[SizeT]) + : m_ptr(str) + , m_len(SizeT - 1) + { + BX_ASSERT('\0' == m_ptr[SizeT - 1], "Must be 0 terminated."); + } + + inline constexpr int32_t StringLiteral::getLength() const + { + return m_len; + } + + inline constexpr const char* StringLiteral::getCPtr() const + { + return m_ptr; + } + inline StringView::StringView() { clear(); } + inline constexpr StringView::StringView(const StringLiteral& _str) + : m_ptr(_str.getCPtr() ) + , m_len(_str.getLength() ) + , m_0terminated(true) + { + } + inline StringView::StringView(const StringView& _rhs, int32_t _start, int32_t _len) { set(_rhs, _start, _len); diff --git a/include/bx/string.h b/include/bx/string.h index 73f02a3..5e81400 100644 --- a/include/bx/string.h +++ b/include/bx/string.h @@ -20,14 +20,46 @@ namespace bx }; }; + /// Zero-terminated string literal. + /// + class StringLiteral + { + public: + /// Construct default/empty string literal. + /// + constexpr StringLiteral(); + + /// Construct string literal from C-style string literal. + /// + template + constexpr StringLiteral(const char (&str)[SizeT]); + + /// Returns string length. + /// + constexpr int32_t getLength() const; + + /// Returns zero-terminated C string pointer to string literal. + /// + constexpr const char* getCPtr() const; + + private: + const char* m_ptr; + int32_t m_len; + }; + /// Non-zero-terminated string view. /// class StringView { public: + /// Construct default/empty string view. /// StringView(); + /// Construct string view from string literal. + /// + constexpr StringView(const StringLiteral& _str); + /// StringView(const StringView& _rhs, int32_t _start = 0, int32_t _len = INT32_MAX); @@ -75,12 +107,15 @@ namespace bx const char* getTerm() const; /// Returns `true` if string is empty. + /// bool isEmpty() const; /// Returns string length. + /// int32_t getLength() const; /// Returns `true` if string is zero terminated. + /// bool is0Terminated() const; protected: diff --git a/src/string.cpp b/src/string.cpp index 06446e2..3896479 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -734,12 +734,12 @@ namespace bx int32_t width; int32_t base; int32_t prec; - char fill; + char fill; uint8_t bits; - bool left; - bool upper; - bool spec; - bool sign; + bool left; + bool upper; + bool spec; + bool sign; }; static int32_t write(WriterI* _writer, const char* _str, int32_t _len, const Param& _param, Error* _err) @@ -956,7 +956,7 @@ namespace bx } else if ('%' == ch) { - // %[Flags][Width][.Precision][Leegth]Type + // %[Flags][Width][.Precision][Length]Type read(&reader, ch, &err); Param param; @@ -1074,8 +1074,8 @@ namespace bx { case 'h': param.bits = sizeof(signed char )*8; break; case 'l': param.bits = sizeof(long long int)*8; break; - case '3': - case '6': + + case '3': case '6': read(&reader, ch, &err); switch (ch) { @@ -1134,12 +1134,9 @@ namespace bx }; break; - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': + case 'e': case 'E': + case 'f': case 'F': + case 'g': case 'G': param.upper = isUpper(ch); size += write(_writer, va_arg(_argList, double), param, _err); break; @@ -1148,8 +1145,7 @@ namespace bx size += write(_writer, va_arg(_argList, void*), param, _err); break; - case 'x': - case 'X': + case 'x': case 'X': param.base = 16; param.upper = isUpper(ch); switch (param.bits) diff --git a/tests/string_test.cpp b/tests/string_test.cpp index 3600ea9..3f5a076 100644 --- a/tests/string_test.cpp +++ b/tests/string_test.cpp @@ -12,6 +12,35 @@ bx::AllocatorI* g_allocator; +TEST_CASE("StringLiteral", "") +{ + constexpr bx::StringLiteral tmp[] = { "1389", "abvgd", "mac", "pod" }; + + REQUIRE(bx::isSorted(tmp, BX_COUNTOF(tmp) ) ); + + static_assert(4 == tmp[0].getLength() ); + REQUIRE(0 == bx::strCmp("1389", tmp[0]) ); + + static_assert(5 == tmp[1].getLength() ); + REQUIRE(0 == bx::strCmp("abvgd", tmp[1]) ); + + static_assert(3 == tmp[2].getLength() ); + REQUIRE(0 == bx::strCmp("mac", tmp[2]) ); + + static_assert(3 == tmp[3].getLength() ); + REQUIRE(0 == bx::strCmp("pod", tmp[3]) ); + + constexpr bx::StringLiteral copy = tmp[0]; + + static_assert(4 == copy.getLength() ); + REQUIRE(0 == bx::strCmp("1389", copy) ); + + constexpr bx::StringView sv = tmp[1]; + + REQUIRE(5 == sv.getLength() ); + REQUIRE(0 == bx::strCmp("abvgd", sv) ); +} + TEST_CASE("stringPrintfTy", "") { std::string test;