summaryrefslogtreecommitdiff
path: root/asl/buffer.hpp
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2025-01-02 19:37:41 +0100
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2025-01-02 19:46:23 +0100
commita9f254dcea5cc73112ba4df96ceaf48a33fae216 (patch)
treed735d931cc99a47123118b7ceed326331f326055 /asl/buffer.hpp
parent12b864491fe9750e9fbe09e354374bb441941761 (diff)
Implement copy move & assign for buffer
Diffstat (limited to 'asl/buffer.hpp')
-rw-r--r--asl/buffer.hpp53
1 files changed, 50 insertions, 3 deletions
diff --git a/asl/buffer.hpp b/asl/buffer.hpp
index ca371d2..eab0a2e 100644
--- a/asl/buffer.hpp
+++ b/asl/buffer.hpp
@@ -5,6 +5,7 @@
#include "asl/annotations.hpp"
#include "asl/memory.hpp"
#include "asl/assert.hpp"
+#include "asl/span.hpp"
namespace asl
{
@@ -141,7 +142,7 @@ private:
isize_t other_n = other.size();
isize_t this_n = size();
resize_uninit(other_n);
- if (other_n < this_n)
+ if (other_n <= this_n)
{
relocate_assign_n(data(), other.data(), other_n);
}
@@ -168,6 +169,26 @@ private:
}
}
+ void copy_range(span<const T> to_copy)
+ {
+ isize_t this_size = size();
+ isize_t new_size = to_copy.size();
+
+ resize_uninit(to_copy.size());
+ ASL_ASSERT(capacity() >= new_size);
+ ASL_ASSERT(size() == to_copy.size());
+
+ if (new_size <= this_size)
+ {
+ copy_assign_n(data(), to_copy.data(), new_size);
+ }
+ else
+ {
+ copy_assign_n(data(), to_copy.data(), this_size);
+ copy_uninit_n(data() + this_size, to_copy.data() + this_size, new_size - this_size);
+ }
+ }
+
public:
constexpr buffer() requires default_constructible<Allocator> = default;
@@ -175,13 +196,30 @@ public:
: m_allocator{ASL_MOVE(allocator)}
{}
+ constexpr buffer(const buffer& other)
+ requires copy_constructible<Allocator> && copyable<T>
+ : m_allocator{other.m_allocator}
+ {
+ copy_range(other);
+ }
+
constexpr buffer(buffer&& other)
+ requires moveable<T>
: buffer(ASL_MOVE(other.m_allocator))
{
move_from_other(ASL_MOVE(other), false);
}
+
+ constexpr buffer& operator=(const buffer& other)
+ requires copyable<T>
+ {
+ if (&other == this) { return *this; }
+ copy_range(other);
+ return *this;
+ }
constexpr buffer& operator=(buffer&& other)
+ requires moveable<T>
{
if (&other == this) { return *this; }
move_from_other(ASL_MOVE(other), true);
@@ -193,8 +231,6 @@ public:
destroy();
}
- // @Todo Copy constructor & assignment
-
constexpr isize_t size() const
{
return decode_size(load_size_encoded());
@@ -307,6 +343,17 @@ public:
}
}
+ // @Todo(C++23) Deducing this
+ operator span<const T>() const // NOLINT(*-explicit-conversions)
+ {
+ return span<const T>{data(), size()};
+ }
+
+ operator span<T>() // NOLINT(*-explicit-conversions)
+ {
+ return span<T>{data(), size()};
+ }
+
// @Todo(C++23) Use deducing this
constexpr T& operator[](isize_t i)
{