Files
asl/asl/maybe_uninit.hpp
2025-01-26 00:42:44 +01:00

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