f8ba33fed325bff435ab7800c7e30f53341b80ab
[lttng-tools.git] / src / common / reference.hpp
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 <common/macros.hpp>
12
13 #include <algorithm>
14 #include <utility>
15
16 namespace lttng {
17
18 template <typename ReferencedType, typename CustomDeleter>
19 class non_copyable_reference {
20 public:
21 using referenced_type = ReferencedType;
22 using deleter = CustomDeleter;
23
24 non_copyable_reference(non_copyable_reference&& other) noexcept : _value(other._value)
25 {
26 _value = other._value;
27 other.release();
28 }
29
30 non_copyable_reference() = delete;
31 non_copyable_reference(const non_copyable_reference&) = delete;
32 non_copyable_reference& operator=(non_copyable_reference&& other) noexcept
33 {
34 if (this != &other) {
35 _clean_up();
36 _value = other._value;
37 other.release();
38 }
39
40 return *this;
41 }
42
43 non_copyable_reference& operator=(const non_copyable_reference&) = delete;
44
45 ReferencedType& get() const noexcept
46 {
47 return *_value;
48 }
49
50 ReferencedType *operator->() const noexcept
51 {
52 return _value;
53 }
54
55 ReferencedType& operator*() const noexcept
56 {
57 return *_value;
58 }
59
60 void release() noexcept
61 {
62 _value = nullptr;
63 }
64
65 ~non_copyable_reference()
66 {
67 _clean_up();
68 }
69
70 private:
71 explicit non_copyable_reference(ReferencedType& instance) noexcept : _value(&instance)
72 {
73 }
74
75 void _clean_up()
76 {
77 if (!_value) {
78 return;
79 }
80
81 DIAGNOSTIC_PUSH
82 DIAGNOSTIC_IGNORE_INJECTED_CLASS_NAME
83 static_assert(std::is_class<typename CustomDeleter::deleter>::value,
84 "CustomDeleter must define a 'deleter' callable class.");
85 const typename CustomDeleter::deleter del;
86 DIAGNOSTIC_POP
87
88 del(_value);
89 release();
90 }
91
92 template <typename FactoryReferencedType, typename FactoryCustomDeleter>
93 friend non_copyable_reference<FactoryReferencedType, FactoryCustomDeleter>
94 make_non_copyable_reference(FactoryReferencedType&);
95
96 ReferencedType *_value = nullptr;
97 };
98
99 template <typename ReferencedType, typename CustomDeleter>
100 non_copyable_reference<ReferencedType, CustomDeleter>
101 make_non_copyable_reference(ReferencedType& instance)
102 {
103 return non_copyable_reference<ReferencedType, CustomDeleter>(instance);
104 }
105
106 } /* namespace lttng */
107
108 #endif /* LTTNG_REFERENCE_H */
This page took 0.034242 seconds and 5 git commands to generate.