diff --git a/Source/utils/static_vector.hpp b/Source/utils/static_vector.hpp index 636271628..a4874dfb3 100644 --- a/Source/utils/static_vector.hpp +++ b/Source/utils/static_vector.hpp @@ -1,12 +1,11 @@ #pragma once -#include #include #include -#include #include #include "appfat.h" +#include "utils/stdcompat/cstddef.hpp" namespace devilution { @@ -58,47 +57,53 @@ public: T &emplace_back(Args &&...args) // NOLINT(readability-identifier-naming) { assert(size_ < N); - ::new (&data_[size_]) T(std::forward(args)...); -#if __cplusplus >= 201703L - T &result = *std::launder(reinterpret_cast(&data_[size_])); -#else - T &result = *reinterpret_cast(&data_[size_]); -#endif - ++size_; - return result; + return *::new (&data_[size_++]) T(std::forward(args)...); } T &operator[](std::size_t pos) { -#if __cplusplus >= 201703L - return *std::launder(reinterpret_cast(&data_[pos])); -#else - return *reinterpret_cast(&data_[pos]); -#endif + return *data_[pos].ptr(); } const T &operator[](std::size_t pos) const { -#if __cplusplus >= 201703L - return *std::launder(reinterpret_cast(&data_[pos])); -#else - return *reinterpret_cast(&data_[pos]); -#endif + return *data_[pos].ptr(); } ~StaticVector() { for (std::size_t pos = 0; pos < size_; ++pos) { #if __cplusplus >= 201703L - std::destroy_at(std::launder(reinterpret_cast(&data_[pos]))); + std::destroy_at(data_[pos].ptr()); #else - reinterpret_cast(&data_[pos])->~T(); + data_[pos].ptr()->~T(); #endif } } private: - std::aligned_storage_t data_[N]; + struct AlignedStorage { + alignas(alignof(T)) byte data[sizeof(T)]; + + const T *ptr() const + { +#if __cplusplus >= 201703L + return std::launder(reinterpret_cast(data)); +#else + return reinterpret_cast(data); +#endif + } + + T *ptr() + { +#if __cplusplus >= 201703L + return std::launder(reinterpret_cast(data)); +#else + return reinterpret_cast(data); +#endif + } + }; + AlignedStorage data_[N]; std::size_t size_ = 0; };