From 8dcb1de91e15ff7fc66279cd9cd9ad8a70f624e0 Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Tue, 29 Oct 2024 23:16:46 -0500 Subject: u8 string literals --- source/fud_string.cpp | 117 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 75 insertions(+), 42 deletions(-) (limited to 'source/fud_string.cpp') diff --git a/source/fud_string.cpp b/source/fud_string.cpp index edb25da..058c813 100644 --- a/source/fud_string.cpp +++ b/source/fud_string.cpp @@ -23,11 +23,20 @@ namespace fud { +StringResult String::makeFromCString(const char8_t* cString) { + return makeFromCString(reinterpret_cast(cString)); +} + StringResult String::makeFromCString(const char* cString) { return makeFromCString(cString, &globalFudAllocator); } +StringResult String::makeFromCString(const char8_t* cString, Allocator* allocator) +{ + return makeFromCString(reinterpret_cast(cString), allocator); +} + StringResult String::makeFromCString(const char* cString, Allocator* allocator) { if (allocator == nullptr) { @@ -59,7 +68,7 @@ StringResult String::makeFromCString(const char* cString, Allocator* allocator) if (isLarge) { output.m_repr.large.capacity = capacity; output.m_repr.large.length = length; - auto dataResult = output.allocator()->allocate(output.m_repr.large.capacity); + auto dataResult = output.allocator()->allocate(capacity); if (dataResult.isError()) { return StringResult::error(dataResult.getError()); } @@ -69,7 +78,7 @@ StringResult String::makeFromCString(const char* cString, Allocator* allocator) } else { capacity = SsoBufSize; static_assert(SsoBufSize < std::numeric_limits::max()); - output.m_repr.small.length = static_cast(length) & smallStringLengthMask; + output.m_repr.small.length = length & smallStringLengthMask; data = output.m_repr.small.buffer.data(); output.setSmall(); } @@ -136,24 +145,19 @@ StringResult String::from(StringView view, Allocator* allocator) String output{}; output.m_allocator = reinterpret_cast(allocator); - size_t capacity = view.length() + 1U; - bool isLarge = capacity > SsoBufSize; + size_t outputCapacity = view.length() + 1U; + bool isLarge = outputCapacity > SsoBufSize; utf8* data{nullptr}; if (isLarge) { - output.m_repr.large.capacity = capacity; - output.m_repr.large.length = view.length(); - output.m_repr.large.data = static_cast(M_TakeOrReturn(StringResult, output.allocator()->allocate(capacity))); - data = output.m_repr.large.data; - output.setLarge(); + auto status = output.makeLarge(outputCapacity, view.length(), data); + if (status != FudStatus::Success) { + return StringResult::error(status); + } } else { - capacity = SsoBufSize; - static_assert(SsoBufSize < std::numeric_limits::max()); - output.m_repr.small.length = static_cast(view.length()) & smallStringLengthMask; - data = output.m_repr.small.buffer.data(); - output.setSmall(); + output.makeSmall(outputCapacity, view.length(), data); } fudAssert(data != nullptr); - auto copyStatus = copyMem(data, capacity, view.m_data, view.length()); + auto copyStatus = copyMem(data, outputCapacity, view.m_data, view.length()); fudAssert(copyStatus == FudStatus::Success); auto terminateStatus = output.nullTerminate(); @@ -630,21 +634,12 @@ StringResult String::catenate(const char* rhs) const size_t outputCapacity = outputLength + 1; utf8* outputData{nullptr}; if (outputCapacity > SsoBufSize) { - output.m_repr.large.capacity = outputCapacity; - output.m_repr.large.length = outputLength; - auto dataResult = output.allocator()->allocate(output.m_repr.large.capacity); - if (dataResult.isError()) { - return StringResult::error(dataResult.getError()); + auto status = output.makeLarge(outputCapacity, outputLength, outputData); + if (status != FudStatus::Success) { + return StringResult::error(status); } - output.m_repr.large.data = static_cast(dataResult.getOkay()); - output.setLarge(); - outputData = output.m_repr.large.data; } else { - outputCapacity = SsoBufSize; - static_assert(SsoBufSize < std::numeric_limits::max()); - output.setSmall(); - output.m_repr.small.length = static_cast(outputLength) & smallStringLengthMask; - outputData = output.m_repr.small.buffer.data(); + output.makeSmall(outputCapacity, outputLength, outputData); } fudAssert(outputData != nullptr); @@ -674,24 +669,15 @@ StringResult String::catenate(const String& rhs) const String output{}; output.m_allocator = m_allocator; size_t outputLength = length() + rhs.length(); - size_t outputCapacity = outputLength + 1; + size_t outputCapacity = outputLength + 1; utf8* outputData{nullptr}; if (outputCapacity > SsoBufSize) { - output.m_repr.large.capacity = outputCapacity; - output.m_repr.large.length = outputLength; - auto dataResult = output.allocator()->allocate(output.m_repr.large.capacity); - if (dataResult.isError()) { - return StringResult::error(dataResult.getError()); + auto status = output.makeLarge(outputCapacity, outputLength, outputData); + if (status != FudStatus::Success) { + return StringResult::error(status); } - output.m_repr.large.data = static_cast(dataResult.getOkay()); - output.setLarge(); - outputData = output.m_repr.large.data; } else { - outputCapacity = SsoBufSize; - static_assert(SsoBufSize < std::numeric_limits::max()); - output.setSmall(); - output.m_repr.small.length = static_cast(outputLength) & smallStringLengthMask; - outputData = output.m_repr.small.buffer.data(); + output.makeSmall(outputCapacity, outputLength, outputData); } auto status = copyMem(outputData, outputCapacity, data(), length()); @@ -750,4 +736,51 @@ const utf8* String::end() const return data() + size(); } +void String::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((m_repr.small.length + augend)) & + smallStringLengthMask; + } +} + +void String::setLength(size_t newLength) +{ + if (isLarge()) { + fudAssert(newLength < maxStringLength); + m_repr.large.length = newLength; + } else { + fudAssert(newLength < maxSmallStringLength); + m_repr.small.length = static_cast(newLength) & smallStringLengthMask; + } +} + +FudStatus String::makeLarge(size_t cap, size_t len, utf8*& outputData) +{ + m_repr.large.capacity = cap; + m_repr.large.length = len; + auto dataResult = allocator()->allocate(cap); + if (dataResult.isError()) { + return dataResult.getError(); + } + m_repr.large.data = static_cast(dataResult.getOkay()); + outputData = m_repr.large.data; + setLarge(); + return FudStatus::Success; +} + +void String::makeSmall(size_t& cap, size_t len, utf8*& outputData) +{ + fudAssert(len < SsoBufSize); + cap = SsoBufSize; + static_assert(SsoBufSize < std::numeric_limits::max()); + m_repr.small.length = len & smallStringLengthMask; + outputData = m_repr.small.buffer.data(); + setSmall(); +} + } // namespace fud -- cgit v1.2.3