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