From eb58edf811a328ddcc5e671a258be208da212630 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Fri, 3 Jan 2025 01:22:21 +0100 Subject: Add string --- asl/BUILD.bazel | 2 ++ asl/buffer.hpp | 27 ++++++++++++++++++-- asl/string.hpp | 62 ++++++++++++++++++++++++++++++++++++++++++++++ asl/tests/buffer_tests.cpp | 12 +++++++++ asl/tests/string_tests.cpp | 21 ++++++++++++++++ 5 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 asl/string.hpp create mode 100644 asl/tests/string_tests.cpp (limited to 'asl') diff --git a/asl/BUILD.bazel b/asl/BUILD.bazel index 9909bc3..54db8c7 100644 --- a/asl/BUILD.bazel +++ b/asl/BUILD.bazel @@ -19,6 +19,7 @@ cc_library( "option.hpp", "print.hpp", "span.hpp", + "string.hpp", "string_view.hpp", "utility.hpp", ], @@ -56,6 +57,7 @@ cc_library( "meta", "option", "span", + "string", "string_view", "utility", ]] diff --git a/asl/buffer.hpp b/asl/buffer.hpp index eab0a2e..90bfc96 100644 --- a/asl/buffer.hpp +++ b/asl/buffer.hpp @@ -191,10 +191,23 @@ private: public: constexpr buffer() requires default_constructible = default; + + explicit constexpr buffer(span s) + requires default_constructible + : buffer{} + { + copy_range(s); + } explicit constexpr buffer(Allocator allocator) : m_allocator{ASL_MOVE(allocator)} {} + + explicit constexpr buffer(span s, Allocator allocator) + : m_allocator{ASL_MOVE(allocator)} + { + copy_range(s); + } constexpr buffer(const buffer& other) requires copy_constructible && copyable @@ -344,12 +357,22 @@ public: } // @Todo(C++23) Deducing this - operator span() const // NOLINT(*-explicit-conversions) + constexpr operator span() const // NOLINT(*-explicit-conversions) + { + return as_span(); + } + + constexpr operator span() // NOLINT(*-explicit-conversions) + { + return as_span(); + } + + constexpr span as_span() const { return span{data(), size()}; } - operator span() // NOLINT(*-explicit-conversions) + constexpr span as_span() { return span{data(), size()}; } diff --git a/asl/string.hpp b/asl/string.hpp new file mode 100644 index 0000000..288767f --- /dev/null +++ b/asl/string.hpp @@ -0,0 +1,62 @@ +#pragma once + +#include "asl/buffer.hpp" +#include "asl/string_view.hpp" + +namespace asl +{ + +template +class string +{ + buffer m_buffer; + +public: + constexpr string() requires default_constructible = default; + explicit constexpr string(Allocator allocator) : m_buffer{ASL_MOVE(allocator)} {} + + // NOLINTNEXTLINE(*-explicit-conversions) + constexpr string(string_view sv) + requires default_constructible + : m_buffer{sv.as_span()} + {} + + constexpr string(string_view sv, Allocator allocator) + : m_buffer{sv.as_span(), ASL_MOVE(allocator)} + {} + + constexpr ~string() = default; + + constexpr string(const string&) requires copy_constructible = default; + constexpr string(string&&) = default; + + constexpr string& operator=(const string&) requires copy_assignable = default; + constexpr string& operator=(string&&) = default; + + constexpr isize_t size() const { return m_buffer.size(); } + constexpr const char* data() const { return m_buffer.data(); } + + // NOLINTNEXTLINE(*-explicit-conversions) + constexpr operator string_view() const + { + return as_string_view(); + } + + constexpr string_view as_string_view() const + { + auto span = m_buffer.as_span(); + return string_view{span.data(), span.size()}; + } + + constexpr bool operator==(const string& other) const + { + return as_string_view() == other.as_string_view(); + } + + constexpr bool operator==(string_view other) const + { + return as_string_view() == other; + } +}; + +} // namespace asl diff --git a/asl/tests/buffer_tests.cpp b/asl/tests/buffer_tests.cpp index ad26c96..f3d6446 100644 --- a/asl/tests/buffer_tests.cpp +++ b/asl/tests/buffer_tests.cpp @@ -131,6 +131,18 @@ ASL_TEST(push) ASL_TEST_EXPECT(b[6] == 7); } +ASL_TEST(from_span) +{ + int data[] = {1, 2, 4, 8}; + asl::buffer b{data}; + + ASL_TEST_EXPECT(b.size() == 4); + ASL_TEST_EXPECT(b[0] == 1); + ASL_TEST_EXPECT(b[1] == 2); + ASL_TEST_EXPECT(b[2] == 4); + ASL_TEST_EXPECT(b[3] == 8); +} + struct MoveableType { int moved{}; diff --git a/asl/tests/string_tests.cpp b/asl/tests/string_tests.cpp new file mode 100644 index 0000000..80aaf24 --- /dev/null +++ b/asl/tests/string_tests.cpp @@ -0,0 +1,21 @@ +#include "asl/string.hpp" +#include "asl/testing/testing.hpp" +#include "asl/format.hpp" + +ASL_TEST(default) +{ + asl::string s; + ASL_TEST_ASSERT(s.size() == 0); + ASL_TEST_ASSERT(s.as_string_view().size() == 0); + ASL_TEST_ASSERT(s == ""_sv); + ASL_TEST_ASSERT(s == s); +} + +ASL_TEST(from_string_view) +{ + asl::string s = "hello"_sv; + ASL_TEST_ASSERT(s.size() == 5); + ASL_TEST_ASSERT(s == "hello"_sv); +} + +static_assert(asl::formattable>); -- cgit