diff options
Diffstat (limited to 'framework/src')
-rw-r--r-- | framework/src/errors.h | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/framework/src/errors.h b/framework/src/errors.h index 9c48f32a..5ee1a667 100644 --- a/framework/src/errors.h +++ b/framework/src/errors.h | |||
@@ -84,45 +84,48 @@ struct StorageBase | |||
84 | protected: | 84 | protected: |
85 | // Rule of 5 {{{ | 85 | // Rule of 5 {{{ |
86 | 86 | ||
87 | constexpr void copyPartFromOther(const StorageBase &other) | 87 | StorageBase(const StorageBase &other) : mIsValue(other.mIsValue) |
88 | { | 88 | { |
89 | // This is a constructor, you have to construct object, not assign them | ||
90 | // (hence the placement new) | ||
89 | if (mIsValue) { | 91 | if (mIsValue) { |
90 | mValue = other.mValue; | 92 | new (std::addressof(mValue)) Type(other.mValue); |
91 | } else { | 93 | } else { |
92 | mError = other.mError; | 94 | new (std::addressof(mError)) Unexpected<Error>(other.mError); |
93 | } | 95 | } |
94 | } | 96 | } |
95 | 97 | ||
96 | void movePartFromOther(StorageBase &&other) | 98 | StorageBase(StorageBase &&other) : mIsValue(other.mIsValue) |
97 | { | 99 | { |
100 | // This is a constructor, you have to construct object, not assign them | ||
101 | // (hence the placement new) | ||
98 | if (mIsValue) { | 102 | if (mIsValue) { |
99 | mValue = std::move(other.mValue); | 103 | new (std::addressof(mValue)) Type(std::move(other.mValue)); |
100 | } else { | 104 | } else { |
101 | mError = std::move(other.mError); | 105 | new (std::addressof(mError)) Unexpected<Error>(std::move(other.mError)); |
102 | } | 106 | } |
103 | } | 107 | } |
104 | 108 | ||
105 | StorageBase(const StorageBase &other) : mIsValue(other.mIsValue) | ||
106 | { | ||
107 | copyPartFromOther(other); | ||
108 | } | ||
109 | |||
110 | StorageBase(StorageBase &&other) : mIsValue(other.mIsValue) | ||
111 | { | ||
112 | movePartFromOther(std::move(other)); | ||
113 | } | ||
114 | |||
115 | constexpr StorageBase &operator=(const StorageBase &other) | 109 | constexpr StorageBase &operator=(const StorageBase &other) |
116 | { | 110 | { |
117 | mIsValue = other.mIsValue; | 111 | mIsValue = other.mIsValue; |
118 | copyPartFromOther(other); | 112 | if (mIsValue) { |
113 | mValue = other.mValue; | ||
114 | } else { | ||
115 | mError = other.mError; | ||
116 | } | ||
119 | return *this; | 117 | return *this; |
120 | } | 118 | } |
121 | 119 | ||
122 | constexpr StorageBase &operator=(StorageBase &&other) | 120 | constexpr StorageBase &operator=(StorageBase &&other) |
123 | { | 121 | { |
122 | this->~StorageBase(); | ||
124 | mIsValue = other.mIsValue; | 123 | mIsValue = other.mIsValue; |
125 | movePartFromOther(other); | 124 | if (mIsValue) { |
125 | mValue = std::move(other.mValue); | ||
126 | } else { | ||
127 | mError = std::move(other.mError); | ||
128 | } | ||
126 | return *this; | 129 | return *this; |
127 | } | 130 | } |
128 | 131 | ||
@@ -216,6 +219,11 @@ struct ExpectedBase : detail::Storage<Error, Type> | |||
216 | Q_ASSERT(this->mIsValue); | 219 | Q_ASSERT(this->mIsValue); |
217 | return this->mValue; | 220 | return this->mValue; |
218 | } | 221 | } |
222 | Type &&value() && | ||
223 | { | ||
224 | Q_ASSERT(this->mIsValue); | ||
225 | return std::move(this->mValue); | ||
226 | } | ||
219 | }; | 227 | }; |
220 | 228 | ||
221 | // Write functions here when dev API related and when Type == void | 229 | // Write functions here when dev API related and when Type == void |