Skip to content

Commit a82e9a6

Browse files
committed
Implement uninitialized_dynamic_array in terms of dynamic_array_data
1 parent 4b4fef4 commit a82e9a6

File tree

1 file changed

+32
-39
lines changed

1 file changed

+32
-39
lines changed

source/containers/uninitialized_dynamic_array.cpp

Lines changed: 32 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ module;
99

1010
export module containers.uninitialized_dynamic_array;
1111

12+
import containers.dynamic_array_data;
13+
1214
import bounded;
1315
import std_module;
1416

@@ -21,78 +23,69 @@ struct [[clang::trivial_abi]] uninitialized_dynamic_array {
2123
template<typename U, typename OtherCapacity>
2224
friend struct uninitialized_dynamic_array;
2325

24-
constexpr uninitialized_dynamic_array() noexcept requires bounded::constructible_from<Capacity, bounded::constant_t<0>>:
25-
m_ptr(nullptr),
26-
m_capacity(0_bi)
27-
{
28-
}
29-
constexpr uninitialized_dynamic_array(bounded::constant_t<0>) noexcept requires bounded::constructible_from<Capacity, bounded::constant_t<0>>:
30-
m_ptr(nullptr),
31-
m_capacity(0_bi)
32-
{
26+
constexpr uninitialized_dynamic_array() noexcept requires bounded::constructible_from<Capacity, bounded::constant_t<0>> = default;
27+
constexpr uninitialized_dynamic_array(bounded::constant_t<0>) noexcept requires bounded::constructible_from<Capacity, bounded::constant_t<0>> {
3328
}
3429
constexpr explicit uninitialized_dynamic_array(Capacity capacity):
35-
m_ptr(allocate(capacity)),
36-
m_capacity(capacity)
30+
m_storage(allocate(capacity))
3731
{
3832
}
3933
template<typename OtherCapacity>
4034
constexpr explicit uninitialized_dynamic_array(uninitialized_dynamic_array<T, OtherCapacity> && other) noexcept:
41-
m_ptr(other.release()),
42-
m_capacity(bounded::assume_in_range<Capacity>(other.m_capacity))
35+
m_storage(
36+
other.m_storage.pointer,
37+
bounded::assume_in_range<Capacity>(other.m_storage.size)
38+
)
4339
{
40+
other.m_storage.pointer = nullptr;
4441
}
4542
constexpr uninitialized_dynamic_array(uninitialized_dynamic_array && other) noexcept:
46-
m_ptr(other.release()),
47-
m_capacity(std::exchange(other.m_capacity, {}))
43+
m_storage(other.m_storage)
4844
{
45+
other.m_storage.pointer = nullptr;
46+
other.m_storage.size = {};
4947
}
5048
constexpr auto operator=(uninitialized_dynamic_array && other) & noexcept -> uninitialized_dynamic_array & {
51-
auto const original_ptr = release();
52-
m_ptr = other.release();
53-
auto const original_capacity = std::exchange(m_capacity, other.m_capacity);
54-
deallocate(original_ptr, original_capacity);
49+
auto const original_storage = m_storage;
50+
m_storage = other.m_storage;
51+
other.m_storage.pointer = nullptr;
52+
deallocate(original_storage);
5553
return *this;
5654
}
5755
constexpr ~uninitialized_dynamic_array() noexcept {
58-
deallocate(m_ptr, m_capacity);
56+
deallocate(m_storage);
5957
}
6058
friend constexpr auto swap(uninitialized_dynamic_array & lhs, uninitialized_dynamic_array & rhs) noexcept -> void {
61-
std::swap(lhs.m_ptr, rhs.m_ptr);
62-
std::swap(lhs.m_capacity, rhs.m_capacity);
59+
std::swap(lhs.m_storage, rhs.m_storage);
6360
}
6461

6562
constexpr auto data() const noexcept -> T const * {
66-
return m_ptr;
63+
return m_storage.pointer;
6764
}
6865
constexpr auto data() noexcept -> T * {
69-
return m_ptr;
66+
return m_storage.pointer;
7067
}
7168
constexpr auto capacity() const noexcept -> Capacity {
72-
BOUNDED_ASSERT(m_ptr != nullptr or m_capacity == 0_bi);
73-
return m_capacity;
69+
BOUNDED_ASSERT(m_storage.pointer != nullptr or m_storage.size == 0_bi);
70+
return m_storage.size;
7471
}
7572

7673
constexpr auto replace_allocation(Capacity new_capacity) -> void {
77-
deallocate(m_ptr, m_capacity);
78-
m_ptr = allocate(new_capacity);
79-
m_capacity = new_capacity;
74+
deallocate(m_storage);
75+
m_storage = allocate(new_capacity);
8076
}
8177

8278
private:
83-
constexpr auto release() & noexcept -> T * {
84-
return std::exchange(m_ptr, nullptr);
85-
}
86-
static constexpr auto allocate(Capacity const capacity) -> T * {
87-
return std::allocator<T>().allocate(static_cast<std::size_t>(capacity));
79+
using storage_t = dynamic_array_data<T, Capacity>;
80+
static constexpr auto allocate(Capacity const capacity) -> storage_t {
81+
return ::containers::allocate_storage<T, Capacity>(capacity);
8882
}
89-
static constexpr auto deallocate(T * const ptr, Capacity const capacity) noexcept -> void {
90-
if (ptr) {
91-
std::allocator<T>().deallocate(ptr, static_cast<std::size_t>(capacity));
83+
static constexpr auto deallocate(storage_t const storage) noexcept -> void {
84+
if (storage.pointer) {
85+
::containers::deallocate_storage(storage);
9286
}
9387
}
94-
[[no_unique_address]] T * m_ptr;
95-
[[no_unique_address]] Capacity m_capacity;
88+
storage_t m_storage;
9689
};
9790

9891
} // namespace containers

0 commit comments

Comments
 (0)