blob: 4f60e4dd7da5eaa319e113069048c3cfeffe7238 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
#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
|