Commit | Line | Data |
---|---|---|
a0a4f314 JG |
1 | /* |
2 | * Copyright (C) 2024 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
3 | * | |
4 | * SPDX-License-Identifier: LGPL-2.1-only | |
5 | * | |
6 | */ | |
7 | ||
8 | #ifndef LTTNG_REFERENCE_H | |
9 | #define LTTNG_REFERENCE_H | |
10 | ||
11 | #include <algorithm> | |
12 | #include <utility> | |
13 | ||
14 | namespace lttng { | |
15 | ||
16 | template <typename ReferencedType, typename CustomDeleter> | |
17 | class non_copyable_reference { | |
18 | public: | |
16d64977 JG |
19 | using referenced_type = ReferencedType; |
20 | using deleter = CustomDeleter; | |
a0a4f314 JG |
21 | |
22 | non_copyable_reference(non_copyable_reference&& other) noexcept : _value(other._value) | |
23 | { | |
16d64977 JG |
24 | _value = other._value; |
25 | other.release(); | |
a0a4f314 JG |
26 | } |
27 | ||
28 | non_copyable_reference() = delete; | |
29 | non_copyable_reference(const non_copyable_reference&) = delete; | |
16d64977 JG |
30 | non_copyable_reference& operator=(non_copyable_reference&& other) noexcept |
31 | { | |
32 | if (this != &other) { | |
33 | _clean_up(); | |
34 | _value = other._value; | |
35 | other.release(); | |
36 | } | |
37 | ||
38 | return *this; | |
39 | } | |
40 | ||
a0a4f314 JG |
41 | non_copyable_reference& operator=(const non_copyable_reference&) = delete; |
42 | ||
43 | ReferencedType& get() const noexcept | |
44 | { | |
45 | return *_value; | |
46 | } | |
47 | ||
48 | ReferencedType *operator->() const noexcept | |
49 | { | |
50 | return _value; | |
51 | } | |
52 | ||
53 | ReferencedType& operator*() const noexcept | |
54 | { | |
55 | return *_value; | |
56 | } | |
57 | ||
16d64977 JG |
58 | void release() noexcept |
59 | { | |
60 | _value = nullptr; | |
61 | } | |
62 | ||
a0a4f314 | 63 | ~non_copyable_reference() |
16d64977 JG |
64 | { |
65 | _clean_up(); | |
66 | } | |
67 | ||
68 | private: | |
69 | explicit non_copyable_reference(ReferencedType& instance) noexcept : _value(&instance) | |
70 | { | |
71 | } | |
72 | ||
73 | void _clean_up() | |
a0a4f314 JG |
74 | { |
75 | if (!_value) { | |
76 | return; | |
77 | } | |
78 | ||
07c4863f | 79 | const typename CustomDeleter::deleter del; |
a0a4f314 | 80 | del(_value); |
16d64977 | 81 | release(); |
a0a4f314 JG |
82 | } |
83 | ||
16d64977 JG |
84 | template <typename FactoryReferencedType, typename FactoryCustomDeleter> |
85 | friend non_copyable_reference<FactoryReferencedType, FactoryCustomDeleter> | |
86 | make_non_copyable_reference(FactoryReferencedType&); | |
87 | ||
a0a4f314 JG |
88 | ReferencedType *_value = nullptr; |
89 | }; | |
90 | ||
16d64977 JG |
91 | template <typename ReferencedType, typename CustomDeleter> |
92 | non_copyable_reference<ReferencedType, CustomDeleter> | |
93 | make_non_copyable_reference(ReferencedType& instance) | |
94 | { | |
95 | return non_copyable_reference<ReferencedType, CustomDeleter>(instance); | |
96 | } | |
97 | ||
a0a4f314 JG |
98 | } /* namespace lttng */ |
99 | ||
100 | #endif /* LTTNG_REFERENCE_H */ |