Skip to content

Commit 3791af2

Browse files
committed
Implement stable_vector in terms of bounded_vector. Unfortunately, vector cannot be implemented that way yet because of deduction guides and the timing of template instantiation.
1 parent ba1121f commit 3791af2

File tree

1 file changed

+15
-107
lines changed

1 file changed

+15
-107
lines changed

source/containers/stable_vector.cpp

Lines changed: 15 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -3,126 +3,34 @@
33
// (See accompanying file LICENSE_1_0.txt or copy at
44
// http://www.boost.org/LICENSE_1_0.txt)
55

6-
module;
7-
8-
#include <bounded/assert.hpp>
9-
10-
#include <operators/bracket.hpp>
11-
#include <operators/forward.hpp>
12-
136
export module containers.stable_vector;
147

15-
import containers.algorithms.destroy_range;
16-
import containers.assign;
17-
import containers.assign_to_empty;
18-
import containers.assign_to_empty_into_capacity;
19-
import containers.begin_end;
20-
import containers.c_array;
21-
import containers.common_functions;
22-
import containers.compare_container;
23-
import containers.contiguous_iterator;
24-
import containers.data;
25-
import containers.initializer_range;
8+
import containers.bounded_vector;
269
import containers.maximum_array_size;
27-
import containers.uninitialized_dynamic_array;
2810

29-
import bounded;
3011
import std_module;
3112

32-
using namespace bounded::literal;
33-
3413
namespace containers {
3514

3615
// See https://probablydance.com/2013/05/13/4gb-per-vector/
3716
// `capacity_` cannot be `array_size_type<T>` because that would not support
3817
// incomplete types.
3918
export template<typename T, array_size_type<std::byte> capacity_>
40-
struct [[clang::trivial_abi]] stable_vector : private lexicographical_comparison::base {
41-
// Allocates the full capacity
42-
constexpr stable_vector() = default;
43-
44-
constexpr explicit stable_vector(constructor_initializer_range<stable_vector> auto && source) {
45-
::containers::assign_to_empty(*this, OPERATORS_FORWARD(source));
46-
}
47-
48-
template<std::size_t source_size> requires(source_size <= capacity_)
49-
constexpr stable_vector(c_array<T, source_size> && source) {
50-
::containers::assign_to_empty_into_capacity(*this, std::move(source));
51-
}
52-
template<std::same_as<empty_c_array_parameter> Source = empty_c_array_parameter>
53-
constexpr stable_vector(Source) {
54-
}
55-
56-
// TODO: Support trivial relocatability
57-
constexpr stable_vector(stable_vector && other) noexcept:
58-
m_storage(std::move(other.m_storage)),
59-
m_size(std::exchange(other.m_size, 0_bi))
60-
{
61-
}
62-
constexpr stable_vector(stable_vector const & other) {
63-
::containers::assign_to_empty_into_capacity(*this, other);
64-
}
65-
66-
constexpr ~stable_vector() {
67-
::containers::destroy_range(*this);
68-
}
69-
70-
constexpr auto operator=(stable_vector && other) & noexcept -> stable_vector & {
71-
::containers::destroy_range(*this);
72-
m_storage = std::move(other.m_storage);
73-
m_size = other.m_size;
74-
other.m_size = 0_bi;
75-
return *this;
76-
}
77-
constexpr auto operator=(stable_vector const & other) & -> stable_vector & {
78-
if (this == std::addressof(other)) {
79-
return *this;
80-
}
81-
if (!m_storage.data()) {
82-
BOUNDED_ASSERT(m_size == 0_bi);
83-
m_storage = storage_type(capacity());
84-
}
85-
containers::assign(*this, other);
86-
return *this;
87-
}
88-
89-
friend constexpr auto swap(stable_vector & lhs, stable_vector & rhs) noexcept -> void {
90-
swap(lhs.m_storage, rhs.m_storage);
91-
std::swap(lhs.m_size, rhs.m_size);
92-
}
93-
94-
constexpr auto data() const -> T const * {
95-
return m_storage.data();
96-
}
97-
constexpr auto data() -> T * {
98-
return m_storage.data();
99-
}
100-
constexpr auto size() const {
101-
return m_size;
102-
}
103-
104-
OPERATORS_BRACKET_SEQUENCE_RANGE_DEFINITIONS
105-
106-
static constexpr auto capacity() {
107-
return bounded::constant<capacity_>;
108-
}
109-
// Assumes that elements are already constructed in the spare capacity
110-
constexpr auto set_size(auto const new_size) -> void {
111-
BOUNDED_ASSERT(new_size <= capacity());
112-
m_size = new_size;
113-
}
114-
115-
constexpr operator std::span<T const>() const {
116-
return std::span<T const>(containers::data(*this), static_cast<std::size_t>(size()));
117-
}
118-
constexpr operator std::span<T>() {
119-
return std::span<T>(containers::data(*this), static_cast<std::size_t>(size()));
120-
}
121-
19+
struct [[clang::trivial_abi]] stable_vector : private bounded_vector<T, capacity_, capacity_> {
12220
private:
123-
using storage_type = uninitialized_dynamic_array<T, decltype(capacity())>;
124-
storage_type m_storage{capacity()};
125-
[[no_unique_address]] bounded::integer<0, bounded::normalize<capacity_>> m_size = 0_bi;
21+
using base = bounded_vector<T, capacity_, capacity_>;
22+
public:
23+
using base::base;
24+
friend constexpr auto swap(stable_vector & lhs, stable_vector & rhs) noexcept -> void {
25+
swap(static_cast<base &>(lhs), static_cast<base &>(rhs));
26+
}
27+
using base::data;
28+
using base::size;
29+
using base::operator[];
30+
using base::capacity;
31+
using base::set_size;
32+
using base::operator std::span<T const>;
33+
using base::operator std::span<T>;
12634
};
12735

12836
} // namespace containers

0 commit comments

Comments
 (0)