Skip to content

Commit f2b6be4

Browse files
committed
Added noexcept specifiers to all data containers
1 parent 6bf474e commit f2b6be4

5 files changed

Lines changed: 36 additions & 19 deletions

File tree

src/array19.lib/array19/DynamicArrayOf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ template<class T> struct DynamicArrayOf final {
2828

2929
public:
3030
DynamicArrayOf() = default;
31-
~DynamicArrayOf() noexcept(std::is_nothrow_destructible_v<Element>) {
31+
~DynamicArrayOf() noexcept {
3232
if (m_pointer) {
3333
Utils::destruct(amend());
3434
Utils::deallocate(Slice{m_pointer, m_capacity});

src/optional19.lib/optional19/Optional.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ template<class T> struct OptionalStorage<T, false> {
3939
bool m_valid{};
4040

4141
OptionalStorage() = default;
42-
~OptionalStorage() {
42+
~OptionalStorage() noexcept {
4343
if (m_valid) {
4444
auto p = std::launder(reinterpret_cast<T*>(m_storage));
4545
p->~T();
@@ -49,13 +49,13 @@ template<class T> struct OptionalStorage<T, false> {
4949
new (this->m_storage) T(std::move(v));
5050
this->m_valid = true;
5151
}
52-
OptionalStorage(const OptionalStorage& o) {
52+
OptionalStorage(const OptionalStorage& o) noexcept(std::is_nothrow_copy_constructible_v<T>) {
5353
if (o.m_valid) {
5454
new (this->m_storage) T(o.value());
5555
this->m_valid = true;
5656
}
5757
}
58-
OptionalStorage& operator=(const OptionalStorage& o) {
58+
OptionalStorage& operator=(const OptionalStorage& o) noexcept(std::is_nothrow_copy_assignable_v<T>) {
5959
if (o.m_valid) {
6060
if (this->m_valid)
6161
amend() = o.value();
@@ -70,13 +70,13 @@ template<class T> struct OptionalStorage<T, false> {
7070
}
7171
return *this;
7272
}
73-
OptionalStorage(OptionalStorage&& o) {
73+
OptionalStorage(OptionalStorage&& o) noexcept {
7474
if (o.m_valid) {
7575
new (this->m_storage) T(std::move(o.amend()));
7676
this->m_valid = true;
7777
}
7878
}
79-
OptionalStorage& operator=(OptionalStorage&& o) {
79+
OptionalStorage& operator=(OptionalStorage&& o) noexcept {
8080
if (o.m_valid) {
8181
if (this->m_valid)
8282
amend() = std::move(o.amend());

src/partial19.lib/partial19/Partial.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ template<class... Ts> struct Partial {
8686
enum : size_t { count = sizeof...(Ts), max_align = sliceMaximum(sliceOfCArray(alignof_ts)) };
8787

8888
private:
89+
static constexpr bool isNothrowCopyConstructible() {
90+
return (true && ... && std::is_nothrow_copy_constructible_v<Ts>);
91+
}
92+
static constexpr bool isNothrowCopyAssignable() {
93+
return (true && ... && std::is_nothrow_copy_constructible_v<Ts>);
94+
}
95+
8996
Bits m_bits{};
9097
uint8_t* m_pointer{};
9198

@@ -108,12 +115,12 @@ template<class... Ts> struct Partial {
108115
}
109116

110117
// copy
111-
Partial(const Partial& o) {
118+
Partial(const Partial& o) noexcept(isNothrowCopyConstructible()) {
112119
auto hasValue = [&](auto i) { return o.m_bits[i]; };
113120
auto factory = [&]<class T>(Type<T>*, void* ptr) { new (ptr) T(o.of<T>()); };
114121
*this = fromFactory(hasValue, factory);
115122
}
116-
auto operator=(const Partial& o) -> Partial& {
123+
auto operator=(const Partial& o) noexcept(isNothrowCopyAssignable()) -> Partial& {
117124
auto hasValue = [&](auto i) { return o.m_bits[i]; };
118125
auto factory = [&]<class T>(Type<T>*, void* ptr) { new (ptr) T(o.of<T>()); };
119126
*this = fromFactory(hasValue, factory);

src/tuple19.lib/tuple19/Tuple.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "meta19/RemoveReference.h"
44
#include "meta19/Type.h"
55

6+
#include <type_traits>
67
#include <utility>
78

89
namespace tuple19 {
@@ -32,15 +33,18 @@ template<class T, size_t I> constexpr auto indexOf(TupleEntry<I, T>*) -> size_t
3233
} // namespace details
3334

3435
template<class... Ts> struct Tuple {
35-
3636
private:
37+
static constexpr bool isNothrowCopyConstructible() {
38+
return (true && ... && std::is_nothrow_copy_constructible_v<Ts>);
39+
}
3740
template<class Is> struct IndexedTuple;
3841

3942
template<size_t... Is> struct IndexedTuple<std::index_sequence<Is...>> : details::TupleEntry<Is, Ts>... {
4043

4144
constexpr IndexedTuple() = default;
42-
constexpr IndexedTuple(const Ts&... ts) : details::TupleEntry<Is, Ts>({ts})... {}
43-
constexpr IndexedTuple(Ts&&... ts) : details::TupleEntry<Is, Ts>({std::move(ts)})... {}
45+
constexpr IndexedTuple(const Ts&... ts) noexcept(isNothrowCopyConstructible())
46+
: details::TupleEntry<Is, Ts>({ts})... {}
47+
constexpr IndexedTuple(Ts&&... ts) noexcept : details::TupleEntry<Is, Ts>({std::move(ts)})... {}
4448

4549
bool operator==(const IndexedTuple&) const = default;
4650

@@ -60,8 +64,8 @@ template<class... Ts> struct Tuple {
6064

6165
public:
6266
constexpr Tuple() = default;
63-
constexpr Tuple(const Ts&... ts) : indexed(ts...) {}
64-
constexpr Tuple(Ts&&... ts) : indexed(std::move(ts)...) {}
67+
constexpr Tuple(const Ts&... ts) noexcept(isNothrowCopyConstructible()) : indexed(ts...) {}
68+
constexpr Tuple(Ts&&... ts) noexcept : indexed(std::move(ts)...) {}
6569

6670
bool operator==(const Tuple&) const = default;
6771

src/variant19.lib/variant19/Variant.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ template<class... Ts> struct Variant {
106106
enum { npos = sizeof...(Ts) }; // invalid state after exception - only destruction checks!
107107

108108
private:
109+
static constexpr bool isNothrowCopyConstructible() {
110+
return (true && ... && std::is_nothrow_copy_constructible_v<Ts>);
111+
}
112+
static constexpr bool isNothrowCopyAssignable() {
113+
return (true && ... && std::is_nothrow_copy_constructible_v<Ts>);
114+
}
109115
template<class> struct IndexedVariant;
110116

111117
template<size_t... Is> struct IndexedVariant<std::index_sequence<Is...>> {
@@ -118,20 +124,20 @@ template<class... Ts> struct Variant {
118124
WhichValue which{npos};
119125
alignas(Ts...) std::byte storage[storage_size];
120126

121-
constexpr IndexedVariant() {
127+
constexpr IndexedVariant() noexcept(std::is_nothrow_default_constructible_v<First>) {
122128
constructAs<First>();
123129
which = 0; // only initialize once constuction was successful
124130
}
125-
~IndexedVariant() {
131+
~IndexedVariant() noexcept {
126132
if (which == npos) return;
127133
destruct();
128134
}
129135

130-
constexpr IndexedVariant(const IndexedVariant& o) {
136+
constexpr IndexedVariant(const IndexedVariant& o) noexcept(isNothrowCopyConstructible()) {
131137
(((Is == o.which ? (constructAs<Ts>(*o.asPtr<Ts>()), 0) : 0), ...));
132138
which = o.which;
133139
}
134-
constexpr auto operator=(const IndexedVariant& o) -> IndexedVariant& {
140+
constexpr auto operator=(const IndexedVariant& o) noexcept(isNothrowCopyAssignable()) -> IndexedVariant& {
135141
if (which == o.which) {
136142
(((Is == o.which ? (*amendAsPtr<Ts>() = *o.asPtr<Ts>(), 0) : 0), ...));
137143
}
@@ -144,11 +150,11 @@ template<class... Ts> struct Variant {
144150
return *this;
145151
}
146152

147-
constexpr IndexedVariant(IndexedVariant&& o) {
153+
constexpr IndexedVariant(IndexedVariant&& o) noexcept {
148154
(((Is == o.which ? (constructAs<Ts>(std::move(*o.amendAsPtr<Ts>())), 0) : 0), ...));
149155
which = o.which; // o.which is needed for destruction!
150156
}
151-
constexpr auto operator=(IndexedVariant&& o) -> IndexedVariant& {
157+
constexpr auto operator=(IndexedVariant&& o) noexcept -> IndexedVariant& {
152158
if (which == o.which) {
153159
(((Is == o.which ? (*amendAsPtr<Ts>() = std::move(*o.amendAsPtr<Ts>()), 0) : 0), ...));
154160
}

0 commit comments

Comments
 (0)