Skip to content

Commit 96c70f1

Browse files
committed
Refactor SSOVector memory management and update usage
1 parent d627e24 commit 96c70f1

3 files changed

Lines changed: 25 additions & 22 deletions

File tree

Playground/main.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
#include "Tuple.hpp"
22
#include "Printer.hpp"
33
#include "CharConv.hpp"
4+
#include "SSOVector.hpp"
5+
#include "BigInt.hpp"
46

57
using namespace ARLib;
68
int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) {
7-
auto tup = Tuple("This is a beatiful string"_s);
8-
auto tup2 = Tuple("This is another beatiful string"_s);
9-
const auto v1 = move(tup).flatten().get<0>();
10-
const auto v2 = Tuple("This is a beatiful string"_s).flatten().get<0>();
11-
const auto& v3 = tup2.get<0>();
12-
Printer::print(R"("{}" "{}" "{}")", v1, v2, tup.get<0>());
13-
Printer::print(R"("{}" "{}" "{}")", v3, tup2.get<0>(), &v3 == &tup2.get<0>());
9+
auto f2 = BigInt{ "123456781234567891234879169467981276392189732178937891237928173981239812219873218973"_s };
10+
auto g2 = BigInt{ "12837127389712389123891738127317892312987389217"_s };
11+
auto d = f2 / g2;
1412
return 0;
1513
}

include/SSOVector.hpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ class SSOVector {
1414
// if grow internal has been called, it means that we need to grow out of situ
1515
HARD_ASSERT(new_capacity > m_capacity, "New capacity should be bigger than existing capacity")
1616
if (m_capacity == SSO) {
17-
m_storage = allocate_uninitialized<T>(new_capacity);
17+
m_storage = allocate_uninitialized<T>(new_capacity);
1818
m_capacity = new_capacity;
1919
if constexpr (SSO != 0) UninitializedMoveConstruct(m_storage, addressof(m_situ_storage[0]), m_size);
2020
} else {
2121
T* new_storage = allocate_uninitialized<T>(new_capacity);
2222
UninitializedMoveConstruct(new_storage, m_storage, m_size);
23-
deallocate<T, DeallocType::Multiple>(m_storage);
23+
destroy_if_not_sso();
2424
m_storage = new_storage;
2525
m_capacity = new_capacity;
2626
}
@@ -30,6 +30,12 @@ class SSOVector {
3030
if (m_size == m_capacity) { grow_to_capacity(m_capacity + 1); }
3131
new (&m_storage[m_size++]) T{ move(item) };
3232
}
33+
void destroy_if_not_sso() {
34+
if (m_capacity > SSO && m_storage != nullptr) {
35+
for (size_t i = 0; i < m_size; ++i) { m_storage[i].~T(); }
36+
deallocate<T, DeallocType::Multiple>(m_storage);
37+
}
38+
}
3339

3440
public:
3541
constexpr SSOVector() = default;
@@ -46,7 +52,7 @@ class SSOVector {
4652
requires(OTHER_SSO != SSO)
4753
: m_size(other.size()) {
4854
if (other.size() > SSO) {
49-
m_storage = allocate_uninitialized<T>(other.capacity());
55+
m_storage = allocate_uninitialized<T>(other.capacity());
5056
m_capacity = other.capacity();
5157
}
5258
UninitializedCopyConstruct(m_storage, other.storage(), other.size());
@@ -87,7 +93,7 @@ class SSOVector {
8793
{
8894
m_size = other.size();
8995
if (m_size > m_capacity) {
90-
if (m_capacity != SSO) deallocate<T, DeallocType::Multiple>(m_storage);
96+
destroy_if_not_sso();
9197
m_storage = allocate_initialized<T>(other.capacity());
9298
m_capacity = other.capacity();
9399
}
@@ -117,11 +123,11 @@ class SSOVector {
117123
if (m_capacity > SSO && other.m_size > m_capacity) {
118124
// if we're already not in situ and we can't fit the other vector, let's resize
119125
// if we're already not in situ *but* we can fit the other vector, we don't do anything
120-
deallocate<T, DeallocType::Multiple>(m_storage);
126+
destroy_if_not_sso();
121127
allocate_initialized<T>(other.m_size);
122128
} else if (other.m_capacity == SSO && m_capacity > SSO) {
123129
// if the other one is in situ but we're not, then we delete our storage, since we don't really need it
124-
deallocate<T, DeallocType::Multiple>(m_storage);
130+
destroy_if_not_sso();
125131
m_storage = SSO != 0 ? addressof(m_situ_storage[0]) : m_situ_storage;
126132
}
127133
m_size = other.m_size;
@@ -131,7 +137,7 @@ class SSOVector {
131137
}
132138
SSOVector& operator=(SSOVector&& other) noexcept {
133139
if (this == &other) return *this;
134-
if (m_capacity > SSO) { deallocate<T, DeallocType::Multiple>(m_storage); }
140+
destroy_if_not_sso();
135141
m_size = other.m_size;
136142
m_capacity = other.m_capacity;
137143
if (other.m_capacity == SSO) {
@@ -178,7 +184,7 @@ class SSOVector {
178184
}
179185
void release_strong() {
180186
if (m_capacity != SSO) {
181-
deallocate<T, DeallocType::Multiple>(m_storage);
187+
destroy_if_not_sso();
182188
m_storage = SSO != 0 ? addressof(m_situ_storage[0]) : m_situ_storage;
183189
m_capacity = SSO;
184190
}
@@ -208,6 +214,7 @@ class SSOVector {
208214
m_capacity = basic_growth(m_capacity + 1);
209215
m_storage = allocate_uninitialized<T>(m_capacity);
210216
UninitializedCopyConstruct(m_storage + sizeof(T), storage, m_size);
217+
for (size_t i = 0; i < m_size; i++) { storage[i].~T(); }
211218
deallocate<T, DeallocType::Multiple>(storage);
212219
}
213220
} else {
@@ -228,9 +235,7 @@ class SSOVector {
228235
{
229236
if (new_size < m_size) return;
230237
if (new_size > m_capacity) { grow_to_capacity(new_size); }
231-
for (size_t i = m_size; i < new_size; i++) {
232-
new (&m_storage[i]) T{};
233-
}
238+
for (size_t i = m_size; i < new_size; i++) { new (&m_storage[i]) T{}; }
234239
m_size = new_size;
235240
}
236241
void reserve(size_t new_capacity) {
@@ -243,9 +248,7 @@ class SSOVector {
243248
}
244249
const T& last() const { return m_storage[m_size - 1]; }
245250
T& last() { return m_storage[m_size - 1]; }
246-
~SSOVector() {
247-
if (m_capacity > SSO) deallocate<T, DeallocType::Multiple>(m_storage);
248-
}
251+
~SSOVector() { destroy_if_not_sso(); }
249252
};
250253
template <Printable T, size_t S>
251254
struct PrintInfo<SSOVector<T, S>> {

include/Stream.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ struct CharacterStream : public BaseStream {
5656
virtual Result<String> read_line(bool& eof_reached) = 0;
5757
virtual bool is_open() const = 0;
5858
virtual bool operator==(const CharacterStream& other) const { return this == &other; }
59+
virtual bool is_filestream() const { return false; }
5960
virtual ~CharacterStream() = default;
6061
};
6162
class FileStream : public CharacterStream {
@@ -77,10 +78,11 @@ class FileStream : public CharacterStream {
7778
size_t seek(size_t) override;
7879
bool operator==(const FileStream& other) const;
7980
bool operator==(const CharacterStream& other) const override {
80-
if (const auto* fs = dynamic_cast<const FileStream*>(&other); fs != nullptr) { return *this == *fs; }
81+
if (other.is_filestream()) { return *this == static_cast<const FileStream&>(other); }
8182
return false;
8283
}
8384
bool is_open() const override { return m_file.is_open(); }
85+
bool is_filestream() const override { return true; }
8486
virtual ~FileStream() = default;
8587
};
8688
class BufferedFileStream : public FileStream {

0 commit comments

Comments
 (0)