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 <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
|
|
||||||
|
Loading…
Reference in New Issue
Block a user