summaryrefslogtreecommitdiff
path: root/source/fud_string.cpp
diff options
context:
space:
mode:
authorDominick Allen <djallen@librehumanitas.org>2024-10-29 23:16:46 -0500
committerDominick Allen <djallen@librehumanitas.org>2024-10-29 23:16:46 -0500
commit8dcb1de91e15ff7fc66279cd9cd9ad8a70f624e0 (patch)
treec73840b15a074cf37f59bc3b2eff56cde982d74f /source/fud_string.cpp
parent8ce397e8c0a83e49e390de9deb73d588e4931ecf (diff)
u8 string literals
Diffstat (limited to 'source/fud_string.cpp')
-rw-r--r--source/fud_string.cpp117
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