util/Manual: use std::aligned_storage_t
By using std::launder(), we can re-enable -Wstrict-aliasing.
This commit is contained in:
parent
826d1b207e
commit
04041f9583
@ -31,13 +31,9 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
#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
|
||||
* manually. The object is constructed in-place, and therefore
|
||||
@ -46,8 +42,9 @@
|
||||
*/
|
||||
template<class T>
|
||||
class Manual {
|
||||
alignas(T)
|
||||
char data[sizeof(T)];
|
||||
using Storage = std::aligned_storage_t<sizeof(T), alignof(T)>;
|
||||
|
||||
Storage storage;
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool initialized = false;
|
||||
@ -77,8 +74,7 @@ public:
|
||||
void Construct(Args&&... args) {
|
||||
assert(!initialized);
|
||||
|
||||
void *p = data;
|
||||
new(p) T(std::forward<Args>(args)...);
|
||||
::new(&storage) T(std::forward<Args>(args)...);
|
||||
|
||||
#ifndef NDEBUG
|
||||
initialized = true;
|
||||
@ -99,15 +95,13 @@ public:
|
||||
reference Get() noexcept {
|
||||
assert(initialized);
|
||||
|
||||
void *p = static_cast<void *>(data);
|
||||
return *static_cast<pointer>(p);
|
||||
return *std::launder(reinterpret_cast<pointer>(&storage));
|
||||
}
|
||||
|
||||
const_reference Get() const noexcept {
|
||||
assert(initialized);
|
||||
|
||||
const void *p = static_cast<const void *>(data);
|
||||
return *static_cast<const_pointer>(p);
|
||||
return *std::launder(reinterpret_cast<const_pointer>(&storage));
|
||||
}
|
||||
|
||||
operator reference() noexcept {
|
||||
@ -126,7 +120,3 @@ public:
|
||||
return &Get();
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user