blob: 3b2f75596feb6514145da16364932e12b218a585 (
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
73
74
|
// Copyright 2025 Steven Le Rouzic
//
// SPDX-License-Identifier: BSD-3-Clause
#pragma once
#include "asl/base/meta.hpp"
#include "asl/base/utility.hpp"
#include "asl/memory/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
explicit constexpr maybe_uninit(in_place_t, auto&&... args)
requires constructible_from<T, decltype(args)...>
: m_value{std::forward<decltype(args)>(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>) { return *this; } // NOLINT
constexpr maybe_uninit& operator=(maybe_uninit&&) requires trivially_move_assignable<T> = default;
constexpr maybe_uninit& operator=(maybe_uninit&&) requires (!trivially_move_assignable<T>) { return *this; } // NOLINT
constexpr ~maybe_uninit() requires trivially_destructible<T> = default;
constexpr ~maybe_uninit() requires (!trivially_destructible<T>) {} // NOLINT
// @Safety Value must not have been initialized yet
constexpr void construct_unsafe(auto&&... args)
requires constructible_from<T, decltype(args)...>
{
construct_at<T>(&m_value, std::forward<decltype(args)>(args)...);
}
// @Safety Value must have been initialized
constexpr void assign_unsafe(auto&& value)
requires assignable_from<T&, decltype(value)>
{
m_value = std::forward<decltype(value)>(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 auto&& as_init_unsafe(this auto&& self)
{
return std::forward<decltype(self)>(self).m_value;
}
};
} // namespace asl
|