73 lines
2.4 KiB
C++
73 lines
2.4 KiB
C++
#pragma once
|
|
|
|
#include "asl/meta.hpp"
|
|
#include "asl/utility.hpp"
|
|
#include "asl/memory.hpp"
|
|
|
|
namespace asl
|
|
{
|
|
|
|
template<is_object T>
|
|
union maybe_uninit
|
|
{
|
|
private:
|
|
T m_value;
|
|
|
|
public:
|
|
constexpr maybe_uninit() requires trivially_default_constructible<T> = default;
|
|
constexpr maybe_uninit() requires (!trivially_default_constructible<T>) {} // NOLINT
|
|
|
|
template<typename... Args>
|
|
explicit constexpr maybe_uninit(in_place_t, Args&&... args)
|
|
requires constructible_from<T, Args&&...>
|
|
: m_value{ASL_FWD(args)...}
|
|
{}
|
|
|
|
constexpr maybe_uninit(const maybe_uninit&) requires trivially_copy_constructible<T> = default;
|
|
constexpr maybe_uninit(const maybe_uninit&) requires (!trivially_copy_constructible<T>) {} // NOLINT
|
|
|
|
constexpr maybe_uninit(maybe_uninit&&) requires trivially_move_constructible<T> = default;
|
|
constexpr maybe_uninit(maybe_uninit&&) requires (!trivially_move_constructible<T>) {} // NOLINT
|
|
|
|
constexpr maybe_uninit& operator=(const maybe_uninit&) requires trivially_copy_assignable<T> = default;
|
|
constexpr maybe_uninit& operator=(const maybe_uninit&) requires (!trivially_copy_assignable<T>) {}
|
|
|
|
constexpr maybe_uninit& operator=(maybe_uninit&&) requires trivially_move_assignable<T> = default;
|
|
constexpr maybe_uninit& operator=(maybe_uninit&&) requires (!trivially_move_assignable<T>) {}
|
|
|
|
constexpr ~maybe_uninit() requires trivially_destructible<T> = default;
|
|
constexpr ~maybe_uninit() requires (!trivially_destructible<T>) {} // NOLINT
|
|
|
|
// @Safety Value must not have been initialized yet
|
|
template<typename... Args>
|
|
constexpr void construct_unsafe(Args&&... args)
|
|
requires constructible_from<T, Args&&...>
|
|
{
|
|
construct_at<T>(&m_value, ASL_FWD(args)...);
|
|
}
|
|
|
|
// @Safety Value must have been initialized
|
|
template<typename U>
|
|
constexpr void assign_unsafe(U&& value)
|
|
requires assignable_from<T&, U&&>
|
|
{
|
|
m_value = ASL_FWD(value);
|
|
}
|
|
|
|
// @Safety Value must have been initialized
|
|
constexpr void destroy_unsafe()
|
|
{
|
|
if constexpr (!trivially_destructible<T>)
|
|
{
|
|
destroy(&m_value);
|
|
}
|
|
}
|
|
|
|
// @Safety Value must have been initialized
|
|
constexpr const T& as_init_unsafe() const& { return m_value; }
|
|
constexpr T& as_init_unsafe() & { return m_value; }
|
|
constexpr T&& as_init_unsafe() && { return ASL_MOVE(m_value); }
|
|
};
|
|
|
|
} // namespace asl
|