|
|
|
|
@ -1,12 +1,11 @@
|
|
|
|
|
#pragma once |
|
|
|
|
|
|
|
|
|
#include <cstddef> |
|
|
|
|
#include <initializer_list> |
|
|
|
|
#include <memory> |
|
|
|
|
#include <type_traits> |
|
|
|
|
#include <utility> |
|
|
|
|
|
|
|
|
|
#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>(args)...); |
|
|
|
|
#if __cplusplus >= 201703L |
|
|
|
|
T &result = *std::launder(reinterpret_cast<T *>(&data_[size_])); |
|
|
|
|
#else |
|
|
|
|
T &result = *reinterpret_cast<T *>(&data_[size_]); |
|
|
|
|
#endif |
|
|
|
|
++size_; |
|
|
|
|
return result; |
|
|
|
|
return *::new (&data_[size_++]) T(std::forward<Args>(args)...); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
T &operator[](std::size_t pos) |
|
|
|
|
{ |
|
|
|
|
#if __cplusplus >= 201703L |
|
|
|
|
return *std::launder(reinterpret_cast<T *>(&data_[pos])); |
|
|
|
|
#else |
|
|
|
|
return *reinterpret_cast<T *>(&data_[pos]); |
|
|
|
|
#endif |
|
|
|
|
return *data_[pos].ptr(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const T &operator[](std::size_t pos) const |
|
|
|
|
{ |
|
|
|
|
#if __cplusplus >= 201703L |
|
|
|
|
return *std::launder(reinterpret_cast<const T *>(&data_[pos])); |
|
|
|
|
#else |
|
|
|
|
return *reinterpret_cast<const T *>(&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<T *>(&data_[pos]))); |
|
|
|
|
std::destroy_at(data_[pos].ptr()); |
|
|
|
|
#else |
|
|
|
|
reinterpret_cast<T *>(&data_[pos])->~T(); |
|
|
|
|
data_[pos].ptr()->~T(); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
std::aligned_storage_t<sizeof(T), alignof(T)> data_[N]; |
|
|
|
|
struct AlignedStorage { |
|
|
|
|
alignas(alignof(T)) byte data[sizeof(T)]; |
|
|
|
|
|
|
|
|
|
const T *ptr() const |
|
|
|
|
{ |
|
|
|
|
#if __cplusplus >= 201703L |
|
|
|
|
return std::launder(reinterpret_cast<const T *>(data)); |
|
|
|
|
#else |
|
|
|
|
return reinterpret_cast<const T *>(data); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
T *ptr() |
|
|
|
|
{ |
|
|
|
|
#if __cplusplus >= 201703L |
|
|
|
|
return std::launder(reinterpret_cast<T *>(data)); |
|
|
|
|
#else |
|
|
|
|
return reinterpret_cast<T *>(data); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
AlignedStorage data_[N]; |
|
|
|
|
std::size_t size_ = 0; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|