All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
delegatedCountPtr.h
1//
2// Copyright 2024 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7
8#ifndef PXR_BASE_TF_DELEGATED_COUNT_PTR_H
9#define PXR_BASE_TF_DELEGATED_COUNT_PTR_H
10
11#include "pxr/pxr.h"
12#include "pxr/base/tf/tf.h"
13#include "pxr/base/tf/api.h"
14
16
17#include <memory>
18#include <type_traits>
19#include <utility>
20
21PXR_NAMESPACE_OPEN_SCOPE
22
28 TfDelegatedCountIncrementTag{};
29
34 TfDelegatedCountDoNotIncrementTag{};
35
62template <typename ValueType>
64public:
65 using RawPtrType = std::add_pointer_t<ValueType>;
66 using ReferenceType = std::add_lvalue_reference_t<ValueType>;
67 using element_type = ValueType;
68
69 static_assert(
70 std::is_same_v<
71 void,
72 decltype(TfDelegatedCountIncrement(std::declval<RawPtrType>()))>);
73 static_assert(
74 std::is_same_v<
75 void,
76 decltype(TfDelegatedCountDecrement(std::declval<RawPtrType>()))>);
77
78 using IncrementIsNoExcept =
79 std::integral_constant<
80 bool,
81 noexcept(TfDelegatedCountIncrement(std::declval<RawPtrType>()))>;
82 using DecrementIsNoExcept =
83 std::integral_constant<
84 bool,
85 noexcept(TfDelegatedCountDecrement(std::declval<RawPtrType>()))>;
86 using IncrementAndDecrementAreNoExcept =
87 std::integral_constant<
88 bool, IncrementIsNoExcept() && DecrementIsNoExcept()>;
89 using DereferenceIsNoExcept =
90 std::integral_constant<bool, noexcept(*std::declval<RawPtrType>())>;
91
92private:
93 template <typename ConvertibleType>
94 using _IsPtrConvertible = std::is_convertible<
95 std::add_pointer_t<ConvertibleType>, RawPtrType>;
96
97public:
99 TfDelegatedCountPtr() noexcept = default;
100
105 RawPtrType rawPointer) noexcept :
106 _pointer{rawPointer} {
107 }
108
113 RawPtrType rawPointer)
114 noexcept(IncrementIsNoExcept()) :
115 _pointer{rawPointer} {
116 _IncrementIfValid();
117 }
118
122 noexcept(IncrementIsNoExcept()) :
123 _pointer{ptr.get()} {
124 _IncrementIfValid();
125 }
126
130 template <typename OtherType>
133 std::enable_if_t<_IsPtrConvertible<OtherType>::value, int> = 0)
134 noexcept(IncrementIsNoExcept()) :
135 _pointer(ptr.get()) {
136 _IncrementIfValid();
137 }
138
143 _pointer(ptr.get()) {
144 ptr._pointer = nullptr;
145 }
146
152 noexcept(IncrementAndDecrementAreNoExcept()) {
153 // Implement copy assigment in terms of move assignment
154 return (*this = TfDelegatedCountPtr{ptr});
155 }
156
160 template <typename OtherType>
163 noexcept(IncrementAndDecrementAreNoExcept()) {
164 static_assert(_IsPtrConvertible<OtherType>::value);
165 // Implement copy assigment in terms of move assignment
166 return (*this = TfDelegatedCountPtr{ptr});
167 }
168
173 noexcept(DecrementIsNoExcept()) {
174 _DecrementIfValid();
175 _pointer = ptr.get();
176 ptr._pointer = nullptr;
177 return *this;
178 }
179
182 noexcept(DecrementIsNoExcept()) {
183 reset();
184 return *this;
185 }
186
191 ~TfDelegatedCountPtr() noexcept(DecrementIsNoExcept::value) {
192 _DecrementIfValid();
193 }
194
196 ReferenceType operator*() const noexcept(DereferenceIsNoExcept()) {
197 return *get();
198 }
199
201 RawPtrType operator->() const noexcept {
202 return get();
203 }
204
206 explicit operator bool() const noexcept { return get(); }
207
209 template <typename OtherType>
211 const TfDelegatedCountPtr<OtherType>& other) const noexcept {
212 return get() == other.get();
213 }
214
216 template <typename OtherType>
218 const TfDelegatedCountPtr<OtherType>& other) const noexcept {
219 return get() != other.get();
220 }
221
223 template <typename OtherType>
225 const TfDelegatedCountPtr<OtherType>& other) const noexcept {
226 return get() < other.get();
227 }
228
230 RawPtrType get() const noexcept { return _pointer; }
231
234 void reset() noexcept(DecrementIsNoExcept()) {
235 _DecrementIfValid();
236 _pointer = nullptr;
237 }
238
240 void swap(TfDelegatedCountPtr& other) noexcept {
241 std::swap(other._pointer, _pointer);
242 }
243
244private:
245 void _IncrementIfValid() noexcept(IncrementIsNoExcept()) {
246 if (_pointer) {
247 TfDelegatedCountIncrement(_pointer);
248 }
249 }
250
251 void _DecrementIfValid() noexcept(DecrementIsNoExcept()) {
252 if (_pointer) {
253 TfDelegatedCountDecrement(_pointer);
254 }
255 }
256
257 ValueType* _pointer{nullptr};
258};
259
263template <typename ValueType, typename... Args>
265TfMakeDelegatedCountPtr(Args&&... args) {
267 TfDelegatedCountIncrementTag,
268 new ValueType(std::forward<Args>(args)...)
269 );
270}
271
272PXR_NAMESPACE_CLOSE_SCOPE
273
274#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.