summaryrefslogtreecommitdiff
path: root/asl
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2025-01-03 01:22:21 +0100
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2025-01-03 01:22:21 +0100
commiteb58edf811a328ddcc5e671a258be208da212630 (patch)
treea739433160dc93e7c652142389c62d5e389c16f3 /asl
parent05de08dab9f962e554d0b29ca7157669fdb061e9 (diff)
Add string
Diffstat (limited to 'asl')
-rw-r--r--asl/BUILD.bazel2
-rw-r--r--asl/buffer.hpp27
-rw-r--r--asl/string.hpp62
-rw-r--r--asl/tests/buffer_tests.cpp12
-rw-r--r--asl/tests/string_tests.cpp21
5 files changed, 122 insertions, 2 deletions
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<Allocator> = default;
+
+ explicit constexpr buffer(span<const T> s)
+ requires default_constructible<Allocator>
+ : buffer{}
+ {
+ copy_range(s);
+ }
explicit constexpr buffer(Allocator allocator)
: m_allocator{ASL_MOVE(allocator)}
{}
+
+ explicit constexpr buffer(span<const T> s, Allocator allocator)
+ : m_allocator{ASL_MOVE(allocator)}
+ {
+ copy_range(s);
+ }
constexpr buffer(const buffer& other)
requires copy_constructible<Allocator> && copyable<T>
@@ -344,12 +357,22 @@ public:
}
// @Todo(C++23) Deducing this
- operator span<const T>() const // NOLINT(*-explicit-conversions)
+ constexpr operator span<const T>() const // NOLINT(*-explicit-conversions)
+ {
+ return as_span();
+ }
+
+ constexpr operator span<T>() // NOLINT(*-explicit-conversions)
+ {
+ return as_span();
+ }
+
+ constexpr span<const T> as_span() const
{
return span<const T>{data(), size()};
}
- operator span<T>() // NOLINT(*-explicit-conversions)
+ constexpr span<T> as_span()
{
return span<T>{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<allocator Allocator = DefaultAllocator>
+class string
+{
+ buffer<char, Allocator> m_buffer;
+
+public:
+ constexpr string() requires default_constructible<Allocator> = default;
+ explicit constexpr string(Allocator allocator) : m_buffer{ASL_MOVE(allocator)} {}
+
+ // NOLINTNEXTLINE(*-explicit-conversions)
+ constexpr string(string_view sv)
+ requires default_constructible<Allocator>
+ : 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<Allocator> = default;
+ constexpr string(string&&) = default;
+
+ constexpr string& operator=(const string&) requires copy_assignable<Allocator> = 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<int> 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<asl::string<>>);