diff options
author | Dominick Allen <djallen@librehumanitas.org> | 2024-10-29 23:16:46 -0500 |
---|---|---|
committer | Dominick Allen <djallen@librehumanitas.org> | 2024-10-29 23:16:46 -0500 |
commit | 8dcb1de91e15ff7fc66279cd9cd9ad8a70f624e0 (patch) | |
tree | c73840b15a074cf37f59bc3b2eff56cde982d74f /include | |
parent | 8ce397e8c0a83e49e390de9deb73d588e4931ecf (diff) |
u8 string literals
Diffstat (limited to 'include')
-rw-r--r-- | include/fud_c_string.hpp | 25 | ||||
-rw-r--r-- | include/fud_format.hpp | 21 | ||||
-rw-r--r-- | include/fud_string.hpp | 56 | ||||
-rw-r--r-- | include/fud_string_view.hpp | 6 | ||||
-rw-r--r-- | include/fud_utf8.hpp | 4 |
5 files changed, 57 insertions, 55 deletions
diff --git a/include/fud_c_string.hpp b/include/fud_c_string.hpp index 44e0dc8..d55ba30 100644 --- a/include/fud_c_string.hpp +++ b/include/fud_c_string.hpp @@ -50,6 +50,31 @@ constexpr ssize_t cStringLength(const char* str) return cStringLength(str, maxLength); } +constexpr ssize_t cStringLength(const char8_t* str, size_t maxLength) +{ + if (str == nullptr || maxLength > (SSIZE_MAX - 1)) { + return -1; + } + + ssize_t size = 0; + + while (str[size] != 0 && static_cast<size_t>(size) < maxLength) { + size++; + } + + if (str[size] != 0 && static_cast<size_t>(size) == maxLength) { + return static_cast<ssize_t>(maxLength) + 1; + } + + return size; +} + +constexpr ssize_t cStringLength(const char8_t* str) +{ + constexpr auto maxLength = SSIZE_MAX - 1; + return cStringLength(str, maxLength); +} + } // namespace fud #endif diff --git a/include/fud_format.hpp b/include/fud_format.hpp index c06643d..4d38c26 100644 --- a/include/fud_format.hpp +++ b/include/fud_format.hpp @@ -24,7 +24,7 @@ #include "fud_option.hpp" #include "fud_result.hpp" #include "fud_status.hpp" -#include "fud_string.hpp" +#include "fud_string.hpp" // IWYU pragma: keep #include "fud_string_convert.hpp" #include "fud_string_view.hpp" #include "fud_utf8.hpp" @@ -42,18 +42,18 @@ constexpr size_t maxIntCharCount = bitsPerOctal * sizeof(uint64_t) + 4; struct FormatString { template <size_t N> - consteval FormatString(const char (&input)[N]) : m_size{N - 1}, m_data{input} + consteval FormatString(const utf8 (&input)[N]) : m_size{N - 1}, m_data{input} { static_assert(N > 0); } StringView view() { - return StringView{m_size, reinterpret_cast<const utf8*>(m_data)}; + return StringView{m_size, m_data}; } size_t m_size; - const char* m_data; + const utf8* m_data; }; struct FormatAlign { @@ -1127,7 +1127,7 @@ void fillScientificBuffer(IntCharArray& buffer, Significand significand, uint8_t } } - forEach(Span<uint8_t>{buffer.data(), bufferLength}, [&](uint8_t digit) { + forEach(Span<utf8>{buffer.data(), bufferLength}, [&](uint8_t digit) { return static_cast<uint8_t>(digit + '0'); }); @@ -1485,17 +1485,6 @@ FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& for return result; } -namespace fudTest { -inline void test() -{ - StringView prefix{0, ""}; - String sink{}; - - static_cast<void>(format(sink, FormatCharMode::Unchecked, "HELL YEAH")); - static_cast<void>(format(sink, FormatCharMode::Unchecked, "HELL YEAH", 1, true, "ye")); -} -} // namespace fudTest - } // namespace fud #endif diff --git a/include/fud_string.hpp b/include/fud_string.hpp index cdc6b91..226bb89 100644 --- a/include/fud_string.hpp +++ b/include/fud_string.hpp @@ -60,6 +60,7 @@ class String { * \returns FudStatus::AllocFailure if the allocator fails. */ static StringResult makeFromCString(const char* cString); + static StringResult makeFromCString(const char8_t* cString); /** \brief Create a string from a C String, specifying the allocator. * @@ -73,6 +74,7 @@ class String { * \returns FudStatus::AllocFailure if the allocator fails. */ static StringResult makeFromCString(const char* cString, Allocator* allocator); + static StringResult makeFromCString(const char8_t* cString, Allocator* allocator); /** \brief Create a string from concatenating multiple C Strings. * @@ -151,24 +153,15 @@ class String { String output{}; output.m_allocator = reinterpret_cast<uintptr_t>(allocator); utf8* data{nullptr}; - size_t capacity = totalLength + 1; - bool isLarge = capacity > SsoBufSize; + size_t outputCapacity = totalLength + 1; + bool isLarge = outputCapacity > SsoBufSize; if (isLarge) { - output.m_repr.large.capacity = capacity; - output.m_repr.large.length = totalLength; - auto dataResult = output.allocator()->allocate(output.m_repr.large.capacity); - if (dataResult.isError()) { - return StringResult::error(dataResult.getError()); + auto status = output.makeLarge(outputCapacity, totalLength, data); + if (status != FudStatus::Success) { + return StringResult::error(status); } - output.m_repr.large.data = static_cast<utf8*>(dataResult.getOkay()); - data = output.m_repr.large.data; - output.setLarge(); } else { - capacity = SsoBufSize; - static_assert(SsoBufSize < std::numeric_limits<int8_t>::max()); - output.m_repr.small.length = static_cast<uint8_t>(totalLength) & smallStringLengthMask; - data = output.m_repr.small.buffer.data(); - output.setSmall(); + output.makeSmall(outputCapacity, totalLength, data); } fudAssert(data != nullptr); @@ -176,7 +169,11 @@ class String { size_t cumulativeLength = 0; for (size_t idx = 0; idx < strPointers.size(); ++idx) { const auto* cString = strPointers[idx]; - auto copyStatus = copyMem(data + cumulativeLength, capacity - cumulativeLength, cString, lengths[idx]); + auto copyStatus = copyMem( + data + cumulativeLength, + outputCapacity - cumulativeLength, + cString, + lengths[idx]); fudAssert(copyStatus == FudStatus::Success); cumulativeLength += lengths[idx]; } @@ -368,28 +365,13 @@ class String { m_allocator &= allocatorMask; } - void addToLength(size_t augend) - { - if (isLarge()) { - fudAssert(m_repr.large.length + augend < maxStringLength); - m_repr.large.length += augend; - } else { - fudAssert(m_repr.small.length + augend < maxSmallStringLength); - m_repr.small.length = static_cast<decltype(m_repr.small.length)>((m_repr.small.length + augend)) & - smallStringLengthMask; - } - } + void addToLength(size_t augend); - void setLength(size_t newLength) - { - if (isLarge()) { - fudAssert(newLength < maxStringLength); - m_repr.large.length = newLength; - } else { - fudAssert(newLength < maxSmallStringLength); - m_repr.small.length = static_cast<uint8_t>(newLength) & smallStringLengthMask; - } - } + void setLength(size_t newLength); + + FudStatus makeLarge(size_t cap, size_t len, utf8*& outputData); + + void makeSmall(size_t& cap, size_t len, utf8*& outputData); }; } // namespace fud diff --git a/include/fud_string_view.hpp b/include/fud_string_view.hpp index 972630a..6403c27 100644 --- a/include/fud_string_view.hpp +++ b/include/fud_string_view.hpp @@ -30,6 +30,12 @@ namespace fud { class String; struct StringView { + template <size_t N> + consteval StringView(const utf8 (&input)[N]) : m_length{N - 1}, m_data{input} + { + static_assert(N > 0); + } + constexpr StringView() noexcept = default; constexpr StringView(const StringView& rhs) noexcept = default; diff --git a/include/fud_utf8.hpp b/include/fud_utf8.hpp index 3d53feb..414352f 100644 --- a/include/fud_utf8.hpp +++ b/include/fud_utf8.hpp @@ -29,7 +29,7 @@ namespace fud { -using utf8 = unsigned char; +using utf8 = char8_t; class String; struct StringView; @@ -385,7 +385,7 @@ struct FudUtf8 { } } - [[nodiscard]] constexpr const uint8_t* data() const noexcept + [[nodiscard]] constexpr const utf8* data() const noexcept { if (!valid()) { return nullptr; |