cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / cpp-common / bt2 / borrowed-object.hpp
1 /*
2 * Copyright 2019-2020 (c) Philippe Proulx <pproulx@efficios.com>
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7 #ifndef BABELTRACE_CPP_COMMON_BT2_BORROWED_OBJECT_HPP
8 #define BABELTRACE_CPP_COMMON_BT2_BORROWED_OBJECT_HPP
9
10 #include <functional>
11 #include <type_traits>
12
13 #include "common/assert.h"
14
15 namespace bt2 {
16
17 /*
18 * An instance of this class wraps a pointer to a libbabeltrace2 object
19 * of type `LibObjT` without managing any reference counting.
20 *
21 * This is an abstract base class for any libbabeltrace2 object wrapper.
22 *
23 * `LibObjT` is the direct libbabeltrace2 object type, for example
24 * `bt_stream_class` or `const bt_value`.
25 *
26 * The user of a borrowed object, including methods of a derived class,
27 * can call libObjPtr() to access the libbabeltrace2 object pointer.
28 *
29 * You may only build a borrowed object with a pointer which isn't
30 * `nullptr`. See `bt2::OptionalBorrowedObject` for an optional version.
31 */
32 template <typename LibObjT>
33 class BorrowedObject
34 {
35 static_assert(!std::is_pointer<LibObjT>::value, "`LibObjT` must not be a pointer");
36
37 /*
38 * This makes it possible for a `BorrowedObject<const bt_something>`
39 * instance to get assigned an instance of
40 * `BorrowedObject<bt_something>` ("copy" constructor and
41 * "assignment" operator).
42 *
43 * C++ forbids the other way around.
44 */
45 template <typename>
46 friend class BorrowedObject;
47
48 private:
49 /*
50 * Provides `val` which indicates whether or not you can assign this
51 * object from a borrowed object of type `OtherLibObjT`.
52 */
53 template <typename OtherLibObjT>
54 struct _AssignableFromConst final
55 {
56 /*
57 * If `LibObjT` is const (for example, `const bt_value`), then
58 * you may always assign from its non-const equivalent (for
59 * example, `bt_value`). In C (correct):
60 *
61 * bt_value * const meow = bt_value_bool_create_init(BT_TRUE);
62 * const bt_value * const mix = meow;
63 *
64 * If `LibObjT` is non-const, then you may not assign from its
65 * const equivalent. In C (not correct):
66 *
67 * const bt_value * const meow =
68 * bt_value_array_borrow_element_by_index_const(some_val, 17);
69 * bt_value * const mix = meow;
70 */
71 static constexpr bool val =
72 std::is_const<LibObjT>::value || !std::is_const<OtherLibObjT>::value;
73 };
74
75 protected:
76 /* This complete borrowed object */
77 using _ThisBorrowedObject = BorrowedObject<LibObjT>;
78
79 public:
80 /* libbabeltrace2 object */
81 using LibObj = LibObjT;
82
83 /* libbabeltrace2 object pointer */
84 using LibObjPtr = LibObjT *;
85
86 protected:
87 /*
88 * Builds a borrowed object to wrap the libbabeltrace2 object
89 * pointer `libObjPtr`.
90 *
91 * `libObjPtr` must not be `nullptr`.
92 */
93 explicit BorrowedObject(const LibObjPtr libObjPtr) noexcept : _mLibObjPtr {libObjPtr}
94 {
95 BT_ASSERT_DBG(libObjPtr);
96 }
97
98 /*
99 * Generic "copy" constructor.
100 *
101 * This converting constructor accepts both an instance of
102 * `_ThisBorrowedObject` and an instance (`other`) of
103 * `BorrowedObject<ConstLibObjT>`, where `ConstLibObjT` is the
104 * `const` version of `LibObjT`, if applicable.
105 *
106 * This makes it possible for a `BorrowedObject<const bt_something>`
107 * instance to be built from an instance of
108 * `BorrowedObject<bt_something>`. C++ forbids the other way around.
109 */
110 template <typename OtherLibObjT>
111 BorrowedObject(const BorrowedObject<OtherLibObjT>& other) noexcept :
112 BorrowedObject {other._mLibObjPtr}
113 {
114 static_assert(_AssignableFromConst<OtherLibObjT>::val,
115 "Don't assign a non-const wrapper from a const wrapper.");
116 }
117
118 /*
119 * Generic "assignment" operator.
120 *
121 * This operator accepts both an instance of
122 * `_ThisBorrowedObject` and an instance (`other`) of
123 * `BorrowedObject<ConstLibObjT>`, where `ConstLibObjT` is the
124 * `const` version of `LibObjT`, if applicable.
125 *
126 * This makes it possible for a `BorrowedObject<const bt_something>`
127 * instance to get assigned an instance of
128 * `BorrowedObject<bt_something>`. C++ forbids the other way around,
129 * therefore we use `_EnableIfAssignableT` to show a more relevant
130 * context in the compiler error message.
131 */
132 template <typename OtherLibObjT>
133 _ThisBorrowedObject operator=(const BorrowedObject<OtherLibObjT>& other) noexcept
134 {
135 static_assert(_AssignableFromConst<OtherLibObjT>::val,
136 "Don't assign a non-const wrapper from a const wrapper.");
137
138 _mLibObjPtr = other._mLibObjPtr;
139 return *this;
140 }
141
142 public:
143 /*
144 * Returns a hash of this object, solely based on its raw
145 * libbabeltrace2 pointer.
146 */
147 std::size_t hash() const noexcept
148 {
149 return std::hash<LibObjPtr> {}(_mLibObjPtr);
150 }
151
152 /*
153 * Returns whether or not this object is the exact same as `other`,
154 * solely based on the raw libbabeltrace2 pointers.
155 */
156 bool isSame(const _ThisBorrowedObject& other) const noexcept
157 {
158 return _mLibObjPtr == other._mLibObjPtr;
159 }
160
161 /* Wrapped libbabeltrace2 object pointer */
162 LibObjPtr libObjPtr() const noexcept
163 {
164 return _mLibObjPtr;
165 }
166
167 private:
168 LibObjPtr _mLibObjPtr;
169 };
170
171 } /* namespace bt2 */
172
173 #endif /* BABELTRACE_CPP_COMMON_BT2_BORROWED_OBJECT_HPP */
This page took 0.032644 seconds and 4 git commands to generate.