mirror of
https://github.com/zeldaret/botw
synced 2026-05-28 08:25:01 -04:00
18c60323a9
git subrepo clone https://github.com/open-ead/sead lib/sead subrepo: subdir: "lib/sead" merged: "1b66e825d" upstream: origin: "https://github.com/open-ead/sead" branch: "master" commit: "1b66e825d" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" git subrepo clone (merge) https://github.com/open-ead/nnheaders lib/NintendoSDK subrepo: subdir: "lib/NintendoSDK" merged: "9ee21399f" upstream: origin: "https://github.com/open-ead/nnheaders" branch: "master" commit: "9ee21399f" git-subrepo: version: "0.4.3" origin: "ssh://git@github.com/ingydotnet/git-subrepo" commit: "2f68596" git subrepo clone https://github.com/open-ead/agl lib/agl subrepo: subdir: "lib/agl" merged: "7c063271b" upstream: origin: "https://github.com/open-ead/agl" branch: "master" commit: "7c063271b" git-subrepo: version: "0.4.3" origin: "ssh://git@github.com/ingydotnet/git-subrepo" commit: "2f68596" git subrepo clone https://github.com/open-ead/EventFlow lib/EventFlow subrepo: subdir: "lib/EventFlow" merged: "c35d21b34" upstream: origin: "https://github.com/open-ead/EventFlow" branch: "master" commit: "c35d21b34" git-subrepo: version: "0.4.3" origin: "ssh://git@github.com/ingydotnet/git-subrepo" commit: "2f68596"
86 lines
2.6 KiB
C++
86 lines
2.6 KiB
C++
#pragma once
|
|
|
|
#include <utility>
|
|
#include "basis/seadTypes.h"
|
|
|
|
namespace sead
|
|
{
|
|
struct InitializeTag
|
|
{
|
|
};
|
|
|
|
struct ZeroInitializeTag
|
|
{
|
|
};
|
|
|
|
/// Provides suitably aligned uninitialized storage for a type T.
|
|
/// Use this as a std::aligned_storage replacement that is easier to use and less error prone for
|
|
/// common cases (std::aligned_storage_t<sizeof(T), alignof(T)>).
|
|
template <typename T, bool AutoDestruct = false>
|
|
class StorageFor
|
|
{
|
|
public:
|
|
constexpr StorageFor() = default;
|
|
|
|
explicit StorageFor(InitializeTag) { constructDefault(); }
|
|
|
|
template <typename... Args>
|
|
explicit StorageFor(InitializeTag, Args&&... args)
|
|
{
|
|
construct(std::forward<Args>(args)...);
|
|
}
|
|
|
|
explicit StorageFor(ZeroInitializeTag) : mStorage{} { constructDefault(); }
|
|
|
|
template <typename... Args>
|
|
explicit StorageFor(ZeroInitializeTag, Args&&... args) : mStorage{}
|
|
{
|
|
construct(std::forward<Args>(args)...);
|
|
}
|
|
|
|
T* constructDefault() { return new (storage()) T; }
|
|
|
|
template <typename... Args>
|
|
T* construct(Args&&... args)
|
|
{
|
|
return new (storage()) T(std::forward<Args>(args)...);
|
|
}
|
|
|
|
~StorageFor()
|
|
{
|
|
if constexpr (AutoDestruct)
|
|
destruct();
|
|
}
|
|
|
|
/// @warning It is undefined behavior to call this if no object has been constructed.
|
|
void destruct() { data()->~T(); }
|
|
|
|
/// @warning It is undefined behavior to call this if no object has been constructed.
|
|
T& ref() { return reinterpret_cast<T&>(mStorage); }
|
|
|
|
/// @warning It is undefined behavior to call this if no object has been constructed.
|
|
const T& ref() const { return reinterpret_cast<const T&>(mStorage); }
|
|
|
|
/// @warning It is undefined behavior to call this if no object has been constructed.
|
|
T* data() { return reinterpret_cast<T*>(mStorage); }
|
|
|
|
/// @warning It is undefined behavior to call this if no object has been constructed.
|
|
const T* data() const { return reinterpret_cast<const T*>(mStorage); }
|
|
|
|
/// @warning It is undefined behavior to call this if no object has been constructed.
|
|
T* operator->() { return data(); }
|
|
/// @warning It is undefined behavior to call this if no object has been constructed.
|
|
const T* operator->() const { return data(); }
|
|
/// @warning It is undefined behavior to call this if no object has been constructed.
|
|
T& operator*() { return ref(); }
|
|
/// @warning It is undefined behavior to call this if no object has been constructed.
|
|
const T& operator*() const { return ref(); }
|
|
|
|
void* storage() { return mStorage; }
|
|
const void* storage() const { return mStorage; }
|
|
|
|
private:
|
|
alignas(T) u8 mStorage[sizeof(T)];
|
|
};
|
|
} // namespace sead
|