summaryrefslogtreecommitdiff
path: root/asl/string_builder.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'asl/string_builder.hpp')
-rw-r--r--asl/string_builder.hpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/asl/string_builder.hpp b/asl/string_builder.hpp
new file mode 100644
index 0000000..378ec48
--- /dev/null
+++ b/asl/string_builder.hpp
@@ -0,0 +1,89 @@
+#pragma once
+
+#include "asl/buffer.hpp"
+#include "asl/string.hpp"
+#include "asl/string_view.hpp"
+
+namespace asl
+{
+
+template<allocator Allocator = DefaultAllocator>
+class string_builder
+{
+ buffer<char, Allocator> m_buffer;
+
+public:
+ constexpr string_builder() requires default_constructible<Allocator> = default;
+ explicit constexpr string_builder(Allocator allocator) : m_buffer{ASL_MOVE(allocator)} {}
+
+ constexpr ~string_builder() = default;
+
+ constexpr string_builder(const string_builder&) requires copy_constructible<Allocator> = default;
+ constexpr string_builder(string_builder&&) = default;
+
+ constexpr string_builder& operator=(const string_builder&) requires copy_assignable<Allocator> = default;
+ constexpr string_builder& operator=(string_builder&&) = default;
+
+ constexpr string_view as_string_view() const
+ {
+ auto span = m_buffer.as_span();
+ return string_view{span.data(), span.size()};
+ }
+
+ void reset()
+ {
+ m_buffer.clear();
+ }
+
+ // @Todo(C++23) Deducing this
+
+ string_builder& push(string_view sv) &
+ {
+ isize_t old_size = m_buffer.size();
+ m_buffer.resize_zero(old_size + sv.size());
+ asl::memcpy(m_buffer.data() + old_size, sv.data(), sv.size());
+ return *this;
+ }
+
+ string_builder&& push(string_view sv) &&
+ {
+ isize_t old_size = m_buffer.size();
+ m_buffer.resize_zero(old_size + sv.size());
+ asl::memcpy(m_buffer.data() + old_size, sv.data(), sv.size());
+ return ASL_MOVE(*this);
+ }
+
+ string_builder& push(char c) &
+ {
+ m_buffer.push(c);
+ return *this;
+ }
+
+ string_builder&& push(char c) &&
+ {
+ m_buffer.push(c);
+ return ASL_MOVE(*this);
+ }
+
+ string<Allocator> finish() &&
+ {
+ return string<Allocator>{ASL_MOVE(m_buffer)};
+ }
+
+ template<allocator StringAllocator = Allocator>
+ string<StringAllocator> as_string()
+ requires default_constructible<StringAllocator>
+ {
+ return string<StringAllocator>{as_string_view()};
+ }
+
+ template<allocator StringAllocator = Allocator>
+ string<StringAllocator> as_string(Allocator allocator)
+ {
+ return string<StringAllocator>{as_string_view(), ASL_MOVE(allocator)};
+ }
+};
+
+string_builder() -> string_builder<>;
+
+} // namespace asl