From e5acc1eaa7e342b64ccfaaef5ea502cd623e41d5 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Thu, 23 Jan 2025 00:17:27 +0100 Subject: Add string_builder --- asl/string_builder.hpp | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 asl/string_builder.hpp (limited to 'asl/string_builder.hpp') 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 +class string_builder +{ + buffer m_buffer; + +public: + constexpr string_builder() requires default_constructible = 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 = default; + constexpr string_builder(string_builder&&) = default; + + constexpr string_builder& operator=(const string_builder&) requires copy_assignable = 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 finish() && + { + return string{ASL_MOVE(m_buffer)}; + } + + template + string as_string() + requires default_constructible + { + return string{as_string_view()}; + } + + template + string as_string(Allocator allocator) + { + return string{as_string_view(), ASL_MOVE(allocator)}; + } +}; + +string_builder() -> string_builder<>; + +} // namespace asl -- cgit