summaryrefslogtreecommitdiff
path: root/include
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 /include
parent8ce397e8c0a83e49e390de9deb73d588e4931ecf (diff)
u8 string literals
Diffstat (limited to 'include')
-rw-r--r--include/fud_c_string.hpp25
-rw-r--r--include/fud_format.hpp21
-rw-r--r--include/fud_string.hpp56
-rw-r--r--include/fud_string_view.hpp6
-rw-r--r--include/fud_utf8.hpp4
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;