Skip to content

Commit acc51d7

Browse files
authored
Update unsafe_optional.hpp
1 parent 0c587ee commit acc51d7

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

β€Žunsafe_optional.hpp

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
#include <optional>
6868
#include <stdexcept>
6969
#include <type_traits>
70+
7071
#include "smf_control.hpp"
7172

7273
template<class T>
@@ -85,15 +86,15 @@ union unsafe_optional_data {
8586
constexpr unsafe_optional_data() noexcept : uninitialized() {}
8687
template<class... Args>
8788
constexpr explicit unsafe_optional_data(std::in_place_t, Args&&... args)
88-
: val(std::forward<Args>(args)...) {}
89+
: val(static_cast<Args&&>(args)...) {}
8990
~unsafe_optional_data() = default;
9091
};
9192

9293
// The partial specialization is the same as the primary template except
9394
// that the destructor is explicitly defined.
9495
template<class T>
9596
union unsafe_optional_data<T,
96-
std::enable_if_t<!std::is_trivially_destructible<T>{}()>
97+
std::enable_if_t<!std::is_trivially_destructible_v<T>>
9798
> {
9899
friend unsafe_optional_impl<T>;
99100
private:
@@ -103,7 +104,7 @@ union unsafe_optional_data<T,
103104
constexpr unsafe_optional_data() noexcept : uninitialized() {}
104105
template<class... Args>
105106
constexpr explicit unsafe_optional_data(std::in_place_t, Args&&... args)
106-
: val(std::forward<Args>(args)...) {}
107+
: val(static_cast<Args&&>(args)...) {}
107108
~unsafe_optional_data() {}
108109
};
109110

@@ -148,31 +149,31 @@ class unsafe_optional_impl {
148149
constexpr unsafe_optional_impl(T&& v) : data(std::in_place, std::move(v)) {}
149150
template<class... Args>
150151
constexpr explicit unsafe_optional_impl(std::in_place_t, Args&&... args)
151-
: data(std::in_place, std::forward<Args>(args)...) {}
152+
: data(std::in_place, static_cast<Args&&>(args)...) {}
152153
template <class U, class... Args,
153154
std::enable_if_t<
154-
std::is_constructible<T,std::initializer_list<U>&,Args&&...>{}(),
155+
std::is_constructible_v<T,std::initializer_list<U>&,Args&&...>,
155156
int> = 0
156157
>
157158
constexpr explicit unsafe_optional_impl(
158159
std::in_place_t, std::initializer_list<U> il, Args&&... args
159160
)
160-
: data(std::in_place, il, std::forward<Args>(args)...) {}
161+
: data(std::in_place, il, static_cast<Args&&>(args)...) {}
161162

162163
~unsafe_optional_impl() = default;
163164

164165
unsafe_optional_impl& operator=(unsafe_optional_impl const&) = default;
165166
unsafe_optional_impl& operator=(unsafe_optional_impl&&) = default;
166167

167168
template<class... Args>
168-
void emplace(Args&&... args) {
169-
::new(static_cast<void*>(std::addressof(data.val)))
170-
T(std::forward<Args>(args)...);
169+
T& emplace(Args&&... args) {
170+
return *::new(static_cast<void*>(std::addressof(data.val)))
171+
T(static_cast<Args&&>(args)...);
171172
}
172173
template<class U, class... Args>
173-
void emplace(std::initializer_list<U> il, Args&&... args) {
174-
::new(static_cast<void*>(std::addressof(data.val)))
175-
T(il, std::forward<Args>(args)...);
174+
T& emplace(std::initializer_list<U> il, Args&&... args) {
175+
return *::new(static_cast<void*>(std::addressof(data.val)))
176+
T(il, static_cast<Args&&>(args)...);
176177
}
177178

178179
constexpr T const& value() const& noexcept { return data.val; }
@@ -187,19 +188,19 @@ class unsafe_optional_impl {
187188

188189
template<class T>
189190
class unsafe_optional : public
190-
delete_copy_ctor_if<!std::is_trivially_copy_constructible<T>{}(),
191-
default_move_ctor_if<std::is_trivially_copy_constructible<T>{}(),
192-
delete_copy_assign_if<!std::is_trivially_copy_assignable<T>{}(),
193-
delete_move_assign_if<!std::is_trivially_move_assignable<T>{}(),
191+
delete_copy_ctor_if<!std::is_trivially_copy_constructible_v<T>,
192+
default_move_ctor_if<std::is_trivially_copy_constructible_v<T>,
193+
delete_copy_assign_if<!std::is_trivially_copy_assignable_v<T>,
194+
delete_move_assign_if<!std::is_trivially_move_assignable_v<T>,
194195
unsafe_optional_impl<T>
195196
>>>> {
196197
static_assert(sizeof(unsafe_optional_data<T>) == sizeof(T),
197198
"The wrapper has unintended space overhead.");
198199
static_assert(alignof(unsafe_optional_data<T>) == alignof(T),
199200
"The wrapper has a different alignment from the wrapped type.");
200-
static_assert(!std::is_reference<T>{}(), "T cannot be a reference type.");
201+
static_assert(!std::is_reference_v<T>, "T cannot be a reference type.");
201202
// unsafe_optional_impl<unsafe_optional_impl> is quite useless.
202-
static_assert(!is_unsafe_optional<std::remove_cv_t<T>>{}(),
203+
static_assert(!is_unsafe_optional_v<std::remove_cv_t<T>>,
203204
"T cannot be a unsafe_optional_impl.");
204205
// unsafe_optional<std::in_place_t> and unsafe_optional<std::nullopt_t>
205206
// are not disabled, but they may be a bit tricky to use.
@@ -211,17 +212,17 @@ class unsafe_optional : public
211212

212213
template<class T>
213214
constexpr unsafe_optional<std::decay_t<T>> make_unsafe_optional(T&& v) {
214-
return unsafe_optional<std::decay_t<T>>(std::forward<T>(v));
215+
return unsafe_optional<std::decay_t<T>>(static_cast<T&&>(v));
215216
}
216217

217218
template<class T, class...Args>
218219
constexpr unsafe_optional<T> make_unsafe_optional(Args&&... args) {
219-
return unsafe_optional<T>(std::in_place, std::forward<Args>(args)...);
220+
return unsafe_optional<T>(std::in_place, static_cast<Args&&>(args)...);
220221
}
221222

222223
template<class T, class U, class... Args>
223224
constexpr unsafe_optional<T> make_unsafe_optional(
224225
std::initializer_list<U> il, Args&&... args
225226
) {
226-
return unsafe_optional<T>(std::in_place, il, std::forward<Args>(args)...);
227+
return unsafe_optional<T>(std::in_place, il, static_cast<Args&&>(args)...);
227228
}

0 commit comments

Comments
 (0)