Loading...
Searching...
No Matches
delegatedCountPtr.h
1//
2// Copyright 2024 Pixar
3//
4// Licensed under the Apache License, Version 2.0 (the "Apache License")
5// with the following modification; you may not use this file except in
6// compliance with the Apache License and the following modification to it:
7// Section 6. Trademarks. is deleted and replaced with:
8//
9// 6. Trademarks. This License does not grant permission to use the trade
10// names, trademarks, service marks, or product names of the Licensor
11// and its affiliates, except as required to comply with Section 4(c) of
12// the License and to reproduce the content of the NOTICE file.
13//
14// You may obtain a copy of the Apache License at
15//
16// http://www.apache.org/licenses/LICENSE-2.0
17//
18// Unless required by applicable law or agreed to in writing, software
19// distributed under the Apache License with the above modification is
20// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21// KIND, either express or implied. See the Apache License for the specific
22// language governing permissions and limitations under the Apache License.
23//
24
25#ifndef PXR_BASE_TF_DELEGATED_COUNT_PTR_H
26#define PXR_BASE_TF_DELEGATED_COUNT_PTR_H
27
28#include "pxr/pxr.h"
29#include "pxr/base/tf/tf.h"
30#include "pxr/base/tf/api.h"
31
33
34#include <memory>
35#include <type_traits>
36#include <utility>
37
38PXR_NAMESPACE_OPEN_SCOPE
39
45 TfDelegatedCountIncrementTag{};
46
51 TfDelegatedCountDoNotIncrementTag{};
52
79template <typename ValueType>
81public:
82 using RawPtrType = std::add_pointer_t<ValueType>;
83 using ReferenceType = std::add_lvalue_reference_t<ValueType>;
84 using element_type = ValueType;
85
86 static_assert(
87 std::is_same_v<
88 void,
89 decltype(TfDelegatedCountIncrement(std::declval<RawPtrType>()))>);
90 static_assert(
91 std::is_same_v<
92 void,
93 decltype(TfDelegatedCountDecrement(std::declval<RawPtrType>()))>);
94
95 using IncrementIsNoExcept =
96 std::integral_constant<
97 bool,
98 noexcept(TfDelegatedCountIncrement(std::declval<RawPtrType>()))>;
99 using DecrementIsNoExcept =
100 std::integral_constant<
101 bool,
102 noexcept(TfDelegatedCountDecrement(std::declval<RawPtrType>()))>;
103 using IncrementAndDecrementAreNoExcept =
104 std::integral_constant<
105 bool, IncrementIsNoExcept() && DecrementIsNoExcept()>;
106 using DereferenceIsNoExcept =
107 std::integral_constant<bool, noexcept(*std::declval<RawPtrType>())>;
108
109private:
110 template <typename ConvertibleType>
111 using _IsPtrConvertible = std::is_convertible<
112 std::add_pointer_t<ConvertibleType>, RawPtrType>;
113
114public:
116 TfDelegatedCountPtr() noexcept = default;
117
122 RawPtrType rawPointer) noexcept :
123 _pointer{rawPointer} {
124 }
125
130 RawPtrType rawPointer)
131 noexcept(IncrementIsNoExcept()) :
132 _pointer{rawPointer} {
133 _IncrementIfValid();
134 }
135
139 noexcept(IncrementIsNoExcept()) :
140 _pointer{ptr.get()} {
141 _IncrementIfValid();
142 }
143
147 template <typename OtherType>
150 std::enable_if_t<_IsPtrConvertible<OtherType>::value, int> = 0)
151 noexcept(IncrementIsNoExcept()) :
152 _pointer(ptr.get()) {
153 _IncrementIfValid();
154 }
155
160 _pointer(ptr.get()) {
161 ptr._pointer = nullptr;
162 }
163
169 noexcept(IncrementAndDecrementAreNoExcept()) {
170 // Implement copy assigment in terms of move assignment
171 return (*this = TfDelegatedCountPtr{ptr});
172 }
173
177 template <typename OtherType>
180 noexcept(IncrementAndDecrementAreNoExcept()) {
181 static_assert(_IsPtrConvertible<OtherType>::value);
182 // Implement copy assigment in terms of move assignment
183 return (*this = TfDelegatedCountPtr{ptr});
184 }
185
190 noexcept(DecrementIsNoExcept()) {
191 _DecrementIfValid();
192 _pointer = ptr.get();
193 ptr._pointer = nullptr;
194 return *this;
195 }
196
199 noexcept(DecrementIsNoExcept()) {
200 reset();
201 return *this;
202 }
203
208 ~TfDelegatedCountPtr() noexcept(DecrementIsNoExcept::value) {
209 _DecrementIfValid();
210 }
211
213 ReferenceType operator*() const noexcept(DereferenceIsNoExcept()) {
214 return *get();
215 }
216
218 RawPtrType operator->() const noexcept {
219 return get();
220 }
221
223 explicit operator bool() const noexcept { return get(); }
224
226 template <typename OtherType>
228 const TfDelegatedCountPtr<OtherType>& other) const noexcept {
229 return get() == other.get();
230 }
231
233 template <typename OtherType>
235 const TfDelegatedCountPtr<OtherType>& other) const noexcept {
236 return get() != other.get();
237 }
238
240 template <typename OtherType>
242 const TfDelegatedCountPtr<OtherType>& other) const noexcept {
243 return get() < other.get();
244 }
245
247 RawPtrType get() const noexcept { return _pointer; }
248
251 void reset() noexcept(DecrementIsNoExcept()) {
252 _DecrementIfValid();
253 _pointer = nullptr;
254 }
255
257 void swap(TfDelegatedCountPtr& other) noexcept {
258 std::swap(other._pointer, _pointer);
259 }
260
261private:
262 void _IncrementIfValid() noexcept(IncrementIsNoExcept()) {
263 if (_pointer) {
264 TfDelegatedCountIncrement(_pointer);
265 }
266 }
267
268 void _DecrementIfValid() noexcept(DecrementIsNoExcept()) {
269 if (_pointer) {
270 TfDelegatedCountDecrement(_pointer);
271 }
272 }
273
274 ValueType* _pointer{nullptr};
275};
276
280template <typename ValueType, typename... Args>
282TfMakeDelegatedCountPtr(Args&&... args) {
284 TfDelegatedCountIncrementTag,
285 new ValueType(std::forward<Args>(args)...)
286 );
287}
288
289PXR_NAMESPACE_CLOSE_SCOPE
290
291#endif
Stores a pointer to a ValueType which uses TfDelegatedCountIncrement and TfDelegatedCountDecrement to...
TfDelegatedCountPtr & operator=(const TfDelegatedCountPtr &ptr) noexcept(IncrementAndDecrementAreNoExcept())
Assign by copying from ptr.
TfDelegatedCountPtr(const TfDelegatedCountPtr< OtherType > &ptr, std::enable_if_t< _IsPtrConvertible< OtherType >::value, int >=0) noexcept(IncrementIsNoExcept())
Copy construct from ptr if it is convertible to this class's RawPtrType.
ReferenceType operator*() const noexcept(DereferenceIsNoExcept())
Dereference the underlying pointer.
TfDelegatedCountPtr(TfDelegatedCountIncrementTagType, RawPtrType rawPointer) noexcept(IncrementIsNoExcept())
Create a new pointer storing rawPointer and call TfDelegatedCountIncrement on it if it is not nullptr...
bool operator==(const TfDelegatedCountPtr< OtherType > &other) const noexcept
Return true if the underlying pointers are equivalent.
bool operator!=(const TfDelegatedCountPtr< OtherType > &other) const noexcept
Returns false if the underlying pointers are equivalent.
RawPtrType operator->() const noexcept
Arrow operator dispatch for the underlying pointer.
TfDelegatedCountPtr(const TfDelegatedCountPtr &ptr) noexcept(IncrementIsNoExcept())
Copy construct from ptr, calling TfDelegatedCountIncrement on the held pointer if it is not nullptr.
TfDelegatedCountPtr & operator=(TfDelegatedCountPtr &&ptr) noexcept(DecrementIsNoExcept())
Assign by moving from ptr.
void swap(TfDelegatedCountPtr &other) noexcept
Swap this object's held pointer with other's.
TfDelegatedCountPtr & operator=(std::nullptr_t) noexcept(DecrementIsNoExcept())
Reset this pointer to its default state (i.e. nullptr)
bool operator<(const TfDelegatedCountPtr< OtherType > &other) const noexcept
Orders based on the underlying pointer.
~TfDelegatedCountPtr() noexcept(DecrementIsNoExcept::value)
Call TfDelegatedCountDecrement on the held pointer if it is not nullptr`.
RawPtrType get() const noexcept
Return the underlying pointer.
TfDelegatedCountPtr() noexcept=default
Create a pointer storing nullptr
void reset() noexcept(DecrementIsNoExcept())
Reset the pointer to its default state (nullptr), calling TfDelegatedCountDecrement if the held point...
TfDelegatedCountPtr & operator=(const TfDelegatedCountPtr< OtherType > &ptr) noexcept(IncrementAndDecrementAreNoExcept())
Assign by copying from ptr if it is convertible to this class's RawPtrType.
TfDelegatedCountPtr(TfDelegatedCountPtr &&ptr) noexcept
Construct by moving from ptr.
Stripped down version of diagnostic.h that doesn't define std::string.
When constructing a TfDelegatedCountPtr from a raw pointer, use the TfDelegatedCountDoNotIncrementTag...
When constructing a TfDelegatedCountPtr from a raw pointer, use the TfDelegatedCountIncrementTag to e...
A file containing basic constants and definitions.