cpp-common/bt2: make `bt2::BorrowedObject::LibObj` public
[babeltrace.git] / src / cpp-common / bt2 / borrowed-object.hpp
CommitLineData
01bf7a3a
PP
1/*
2 * Copyright 2019-2020 (c) Philippe Proulx <pproulx@efficios.com>
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
0d218157
PP
7#ifndef BABELTRACE_CPP_COMMON_BT2_BORROWED_OBJECT_HPP
8#define BABELTRACE_CPP_COMMON_BT2_BORROWED_OBJECT_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 *
75aa724c
PP
26 * The user of a borrowed object, including methods of a derived class,
27 * can call libObjPtr() to access the libbabeltrace2 object pointer.
01bf7a3a
PP
28 */
29template <typename LibObjT>
0d218157 30class BorrowedObject
01bf7a3a
PP
31{
32 static_assert(!std::is_pointer<LibObjT>::value, "`LibObjT` must not be a pointer");
33
34 /*
0d218157 35 * This makes it possible for a `BorrowedObject<const bt_something>`
01bf7a3a 36 * instance to get assigned an instance of
0d218157
PP
37 * `BorrowedObject<bt_something>` ("copy" constructor and
38 * "assignment" operator).
01bf7a3a
PP
39 *
40 * C++ forbids the other way around.
41 */
96643d28 42 template <typename>
0d218157 43 friend class BorrowedObject;
01bf7a3a 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 /* This complete borrowed object */
0d218157 74 using _ThisBorrowedObject = BorrowedObject<LibObjT>;
01bf7a3a 75
d246c457
PP
76public:
77 /* libbabeltrace2 object */
78 using LibObj = LibObjT;
79
80 /* libbabeltrace2 object pointer */
81 using LibObjPtr = LibObjT *;
82
83protected:
01bf7a3a
PP
84 /*
85 * Builds a borrowed object to wrap the libbabeltrace2 object
86 * pointer `libObjPtr`.
87 *
88 * `libObjPtr` must not be `nullptr`.
89 */
d246c457 90 explicit BorrowedObject(const LibObjPtr libObjPtr) noexcept : _mLibObjPtr {libObjPtr}
01bf7a3a 91 {
bec20c88 92 BT_ASSERT_DBG(libObjPtr);
01bf7a3a
PP
93 }
94
95 /*
5b2d3ebb 96 * Generic "copy" constructor.
01bf7a3a
PP
97 *
98 * This converting constructor accepts both an instance of
0d218157
PP
99 * `_ThisBorrowedObject` and an instance (`other`) of
100 * `BorrowedObject<ConstLibObjT>`, where `ConstLibObjT` is the
101 * `const` version of `LibObjT`, if applicable.
01bf7a3a 102 *
0d218157 103 * This makes it possible for a `BorrowedObject<const bt_something>`
01bf7a3a 104 * instance to be built from an instance of
0d218157 105 * `BorrowedObject<bt_something>`. C++ forbids the other way around.
01bf7a3a
PP
106 */
107 template <typename OtherLibObjT>
0d218157
PP
108 BorrowedObject(const BorrowedObject<OtherLibObjT>& other) noexcept :
109 BorrowedObject {other._mLibObjPtr}
01bf7a3a 110 {
462e8628
PP
111 static_assert(_AssignableFromConst<OtherLibObjT>::val,
112 "Don't assign a non-const wrapper from a const wrapper.");
01bf7a3a
PP
113 }
114
115 /*
5b2d3ebb 116 * Generic "assignment" operator.
01bf7a3a
PP
117 *
118 * This operator accepts both an instance of
0d218157
PP
119 * `_ThisBorrowedObject` and an instance (`other`) of
120 * `BorrowedObject<ConstLibObjT>`, where `ConstLibObjT` is the
121 * `const` version of `LibObjT`, if applicable.
01bf7a3a 122 *
0d218157 123 * This makes it possible for a `BorrowedObject<const bt_something>`
01bf7a3a 124 * instance to get assigned an instance of
0d218157 125 * `BorrowedObject<bt_something>`. C++ forbids the other way around,
462e8628
PP
126 * therefore we use `_EnableIfAssignableT` to show a more relevant
127 * context in the compiler error message.
01bf7a3a
PP
128 */
129 template <typename OtherLibObjT>
ac30a470 130 _ThisBorrowedObject operator=(const BorrowedObject<OtherLibObjT>& other) noexcept
01bf7a3a 131 {
462e8628
PP
132 static_assert(_AssignableFromConst<OtherLibObjT>::val,
133 "Don't assign a non-const wrapper from a const wrapper.");
134
01bf7a3a
PP
135 _mLibObjPtr = other._mLibObjPtr;
136 return *this;
137 }
138
feeaa247
FD
139public:
140 /*
0d218157
PP
141 * Returns a hash of this object, solely based on its raw
142 * libbabeltrace2 pointer.
feeaa247
FD
143 */
144 std::size_t hash() const noexcept
145 {
d246c457 146 return std::hash<LibObjPtr> {}(_mLibObjPtr);
feeaa247
FD
147 }
148
149 /*
150 * Returns whether or not this object is the exact same as `other`,
151 * solely based on the raw libbabeltrace2 pointers.
152 */
0d218157 153 bool isSame(const _ThisBorrowedObject& other) const noexcept
feeaa247
FD
154 {
155 return _mLibObjPtr == other._mLibObjPtr;
156 }
157
b5f55e9f 158 /* Wrapped libbabeltrace2 object pointer */
d246c457 159 LibObjPtr libObjPtr() const noexcept
01bf7a3a
PP
160 {
161 return _mLibObjPtr;
162 }
163
164private:
d246c457 165 LibObjPtr _mLibObjPtr;
01bf7a3a
PP
166};
167
b5f55e9f 168} /* namespace bt2 */
01bf7a3a 169
0d218157 170#endif /* BABELTRACE_CPP_COMMON_BT2_BORROWED_OBJECT_HPP */
This page took 0.040976 seconds and 4 git commands to generate.