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 /source/fud_string.cpp | |
parent | 8ce397e8c0a83e49e390de9deb73d588e4931ecf (diff) |
u8 string literals
Diffstat (limited to 'source/fud_string.cpp')
-rw-r--r-- | source/fud_string.cpp | 117 |
1 files changed, 75 insertions, 42 deletions
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<const char*>(cString)); +} + StringResult String::makeFromCString(const char* cString) { return makeFromCString(cString, &globalFudAllocator); } +StringResult String::makeFromCString(const char8_t* cString, Allocator* allocator) +{ + return makeFromCString(reinterpret_cast<const char*>(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<int8_t>::max()); - output.m_repr.small.length = static_cast<uint8_t>(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<uintptr_t>(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<utf8*>(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<int8_t>::max()); - output.m_repr.small.length = static_cast<uint8_t>(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<utf8*>(dataResult.getOkay()); - output.setLarge(); - outputData = output.m_repr.large.data; } else { - outputCapacity = SsoBufSize; - static_assert(SsoBufSize < std::numeric_limits<int8_t>::max()); - output.setSmall(); - output.m_repr.small.length = static_cast<uint8_t>(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<utf8*>(dataResult.getOkay()); - output.setLarge(); - outputData = output.m_repr.large.data; } else { - outputCapacity = SsoBufSize; - static_assert(SsoBufSize < std::numeric_limits<int8_t>::max()); - output.setSmall(); - output.m_repr.small.length = static_cast<uint8_t>(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<decltype(m_repr.small.length)>((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<uint8_t>(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<utf8*>(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<int8_t>::max()); + m_repr.small.length = len & smallStringLengthMask; + outputData = m_repr.small.buffer.data(); + setSmall(); +} + } // namespace fud |