util/Manual: use std::aligned_storage_t

By using std::launder(), we can re-enable -Wstrict-aliasing.
This commit is contained in:
Max Kellermann 2022-05-31 16:08:11 +02:00 committed by Max Kellermann
parent 826d1b207e
commit 04041f9583

View File

@ -31,13 +31,9 @@
#include <cassert> #include <cassert>
#include <new> #include <new>
#include <type_traits>
#include <utility> #include <utility>
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
/** /**
* Container for an object that gets constructed and destructed * Container for an object that gets constructed and destructed
* manually. The object is constructed in-place, and therefore * manually. The object is constructed in-place, and therefore
@ -46,8 +42,9 @@
*/ */
template<class T> template<class T>
class Manual { class Manual {
alignas(T) using Storage = std::aligned_storage_t<sizeof(T), alignof(T)>;
char data[sizeof(T)];
Storage storage;
#ifndef NDEBUG #ifndef NDEBUG
bool initialized = false; bool initialized = false;
@ -77,8 +74,7 @@ public:
void Construct(Args&&... args) { void Construct(Args&&... args) {
assert(!initialized); assert(!initialized);
void *p = data; ::new(&storage) T(std::forward<Args>(args)...);
new(p) T(std::forward<Args>(args)...);
#ifndef NDEBUG #ifndef NDEBUG
initialized = true; initialized = true;
@ -99,15 +95,13 @@ public:
reference Get() noexcept { reference Get() noexcept {
assert(initialized); assert(initialized);
void *p = static_cast<void *>(data); return *std::launder(reinterpret_cast<pointer>(&storage));
return *static_cast<pointer>(p);
} }
const_reference Get() const noexcept { const_reference Get() const noexcept {
assert(initialized); assert(initialized);
const void *p = static_cast<const void *>(data); return *std::launder(reinterpret_cast<const_pointer>(&storage));
return *static_cast<const_pointer>(p);
} }
operator reference() noexcept { operator reference() noexcept {
@ -126,7 +120,3 @@ public:
return &Get(); return &Get();
} }
}; };
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif