Nix
2.93.0-dev
Lix: A modern, delicious implementation of the Nix package manager; unstable internal interfaces
Loading...
Searching...
No Matches
manually-drop.hh
1
#pragma once
3
#include <atomic>
4
#include <cassert>
5
#include <utility>
6
7
namespace
nix {
8
10
template
<
typename
T>
11
class
ManuallyDrop
12
{
13
alignas
(
alignof
(T))
char
data[
sizeof
(T)];
14
// We have to use atomic<bool> here since once_flag reattempts if the
15
// callee throws (double destruction? yikes)
16
std::atomic<bool> destroyed =
false
;
17
18
public
:
19
explicit
ManuallyDrop
(T && t)
20
{
21
::new (data) T(std::move(t));
22
}
23
25
template
<
typename
... Arg>
26
ManuallyDrop
(std::in_place_t, Arg &&... args)
27
{
28
::new (data) T(std::forward<Arg>(args)...);
29
}
30
31
ManuallyDrop
(
ManuallyDrop<T>
&& other)
32
{
33
::new (data)
ManuallyDrop<T>
(other.take());
34
}
35
36
~ManuallyDrop() {}
37
38
// FIXME(jade): do some "deducing this" nonsense to implement all the const
39
// whatevers for this class. my clangd didn't like it when i tried, so that
40
// is Later Work. this language is horrific.
41
43
T &
get
()
44
{
45
// SAFETY: this should genuinely never happen and it doesn't matter the
46
// ordering of other stuff relative to it.
47
assert(!destroyed.load(std::memory_order_relaxed));
48
return
reinterpret_cast<
T &
>
(data);
49
}
50
51
T & operator*()
52
{
53
return
get
();
54
}
55
56
T * operator->()
57
{
58
return
&
get
();
59
}
60
71
T &&
take
() &&
72
{
73
// SAFETY: this is relatively lock-like in structure, reordering-wise
74
bool
wasDestroyed = destroyed.exchange(
true
, std::memory_order_acq_rel);
75
assert(!wasDestroyed);
76
return
std::move(
reinterpret_cast<
T &
>
(data));
77
}
78
80
void
destroy
()
81
{
82
// SAFETY: this is relatively lock-like in structure, reordering-wise
83
bool
wasDestroyed = destroyed.exchange(
true
, std::memory_order_acq_rel);
84
if
(!wasDestroyed) {
85
get
().~T();
86
}
87
}
88
};
89
}
nix::ManuallyDrop
Definition
manually-drop.hh:12
nix::ManuallyDrop::get
T & get()
Definition
manually-drop.hh:43
nix::ManuallyDrop::destroy
void destroy()
Definition
manually-drop.hh:80
nix::ManuallyDrop::take
T && take() &&
Definition
manually-drop.hh:71
nix::ManuallyDrop::ManuallyDrop
ManuallyDrop(std::in_place_t, Arg &&... args)
Definition
manually-drop.hh:26
lix
libutil
manually-drop.hh
Generated by
1.10.0