/src/gdal/ogr/ogr_refcountedptr.h
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: OGR |
4 | | * Purpose: Smart pointer around a class that has built-in reference counting. |
5 | | * Author: Even Rouault <even dot rouault at spatialys.com> |
6 | | * |
7 | | ****************************************************************************** |
8 | | * Copyright (c) 2026, Even Rouault <even dot rouault at spatialys.com> |
9 | | * |
10 | | * SPDX-License-Identifier: MIT |
11 | | ****************************************************************************/ |
12 | | |
13 | | #ifndef OGR_REFCOUNTEDPTR_INCLUDED |
14 | | #define OGR_REFCOUNTEDPTR_INCLUDED |
15 | | |
16 | | /*! @cond Doxygen_Suppress */ |
17 | | |
18 | | #include <cstddef> |
19 | | #include <utility> |
20 | | |
21 | | /** Base (non-instantiable) class for OGRRefCountedPtr. |
22 | | * |
23 | | * Only intended to be used as the base class for OGRRefCountedPtr. |
24 | | * Done that way so its constructor is protected and force specializations |
25 | | * of redefining a public one (calling it) |
26 | | */ |
27 | | template <class T> struct OGRRefCountedPtrBase |
28 | | { |
29 | | public: |
30 | | /** Destructor. |
31 | | * |
32 | | * Release the raw pointer, that is decrease its reference count and delete |
33 | | * the object when it reaches zero. |
34 | | */ |
35 | | inline ~OGRRefCountedPtrBase() |
36 | 0 | { |
37 | 0 | reset(nullptr); |
38 | 0 | } Unexecuted instantiation: OGRRefCountedPtrBase<OGRSpatialReference>::~OGRRefCountedPtrBase() Unexecuted instantiation: OGRRefCountedPtrBase<OGRFeatureDefn>::~OGRRefCountedPtrBase() |
39 | | |
40 | | /** Copy constructor. |
41 | | * |
42 | | * Increases the reference count |
43 | | */ |
44 | | inline OGRRefCountedPtrBase(const OGRRefCountedPtrBase &other) |
45 | 0 | : OGRRefCountedPtrBase(other.m_poRawPtr, true) |
46 | 0 | { |
47 | 0 | } |
48 | | |
49 | | /** Copy constructor |
50 | | * |
51 | | * Set the raw pointer to the one used by other, and increase the reference |
52 | | * count. |
53 | | */ |
54 | | // cppcheck-suppress operatorEqVarError |
55 | | inline OGRRefCountedPtrBase &operator=(const OGRRefCountedPtrBase &other) |
56 | | { |
57 | | if (this != &other) |
58 | | { |
59 | | reset(other.m_poRawPtr); |
60 | | } |
61 | | return *this; |
62 | | } |
63 | | |
64 | | /** Move constructor |
65 | | * |
66 | | * Borrows the raw pointer managed by other, without changing its reference |
67 | | * count, and set the managed raw pointer of other to null. |
68 | | */ |
69 | | inline OGRRefCountedPtrBase(OGRRefCountedPtrBase &&other) |
70 | 0 | { |
71 | 0 | std::swap(m_poRawPtr, other.m_poRawPtr); |
72 | 0 | } |
73 | | |
74 | | /** Move assignment operator. |
75 | | * |
76 | | * Release the current managed raw pointer and borrow the |
77 | | * one from other. |
78 | | * Does not change the reference count of the borrowed raw pointer. |
79 | | */ |
80 | | inline OGRRefCountedPtrBase &operator=(OGRRefCountedPtrBase &&other) |
81 | 0 | { |
82 | 0 | reset(nullptr); |
83 | 0 | std::swap(m_poRawPtr, other.m_poRawPtr); |
84 | 0 | return *this; |
85 | 0 | } |
86 | | |
87 | | /** Reset the managed raw pointer. |
88 | | * |
89 | | * Release the current managed raw pointer and manages a new one. |
90 | | * By default, increases the reference count of the new raw pointer (when |
91 | | * not null). |
92 | | */ |
93 | | inline void reset(T *poRawPtr = nullptr, bool add_ref = true) |
94 | 0 | { |
95 | 0 | #ifdef __GNUC__ |
96 | 0 | #pragma GCC diagnostic push |
97 | 0 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" |
98 | 0 | #endif |
99 | 0 | if (m_poRawPtr) |
100 | 0 | m_poRawPtr->Release(); |
101 | 0 | m_poRawPtr = poRawPtr; |
102 | 0 | if (m_poRawPtr && add_ref) |
103 | 0 | m_poRawPtr->Reference(); |
104 | 0 | #ifdef __GNUC__ |
105 | 0 | #pragma GCC diagnostic pop |
106 | 0 | #endif |
107 | 0 | } Unexecuted instantiation: OGRRefCountedPtrBase<OGRSpatialReference>::reset(OGRSpatialReference*, bool) Unexecuted instantiation: OGRRefCountedPtrBase<OGRFeatureDefn>::reset(OGRFeatureDefn*, bool) |
108 | | |
109 | | /** Returns the raw pointer without changing its reference count */ |
110 | | inline T *get() const |
111 | 0 | { |
112 | 0 | return m_poRawPtr; |
113 | 0 | } Unexecuted instantiation: OGRRefCountedPtrBase<OGRSpatialReference>::get() const Unexecuted instantiation: OGRRefCountedPtrBase<OGRFeatureDefn>::get() const |
114 | | |
115 | | /** Returns a reference to the raw pointer without changing its reference |
116 | | * count. |
117 | | * |
118 | | * Must be only called when get() != nullptr. |
119 | | */ |
120 | | inline T &operator*() const |
121 | | { |
122 | | return *m_poRawPtr; |
123 | | } |
124 | | |
125 | | /** Forwards the access to a member or a call to a method of the raw |
126 | | * pointer. |
127 | | */ |
128 | | inline T *operator->() const |
129 | 0 | { |
130 | 0 | return m_poRawPtr; |
131 | 0 | } Unexecuted instantiation: OGRRefCountedPtrBase<OGRSpatialReference>::operator->() const Unexecuted instantiation: OGRRefCountedPtrBase<OGRFeatureDefn>::operator->() const |
132 | | |
133 | | /** Returns whether the raw pointer is null. */ |
134 | | inline explicit operator bool() const |
135 | 0 | { |
136 | 0 | return m_poRawPtr != nullptr; |
137 | 0 | } Unexecuted instantiation: OGRRefCountedPtrBase<OGRSpatialReference>::operator bool() const Unexecuted instantiation: OGRRefCountedPtrBase<OGRFeatureDefn>::operator bool() const |
138 | | |
139 | | protected: |
140 | | inline explicit OGRRefCountedPtrBase(T *poRawPtr = nullptr, |
141 | | bool add_ref = true) |
142 | 0 | : m_poRawPtr(poRawPtr) |
143 | 0 | { |
144 | 0 | #ifdef __GNUC__ |
145 | 0 | #pragma GCC diagnostic push |
146 | 0 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" |
147 | 0 | #endif |
148 | 0 | if (m_poRawPtr && add_ref) |
149 | 0 | m_poRawPtr->Reference(); |
150 | 0 | #ifdef __GNUC__ |
151 | 0 | #pragma GCC diagnostic pop |
152 | 0 | #endif |
153 | 0 | } Unexecuted instantiation: OGRRefCountedPtrBase<OGRSpatialReference>::OGRRefCountedPtrBase(OGRSpatialReference*, bool) Unexecuted instantiation: OGRRefCountedPtrBase<OGRFeatureDefn>::OGRRefCountedPtrBase(OGRFeatureDefn*, bool) |
154 | | |
155 | | private: |
156 | | T *m_poRawPtr{}; |
157 | | }; |
158 | | |
159 | | /** Smart pointer around a class that has built-in reference counting. |
160 | | * |
161 | | * It uses the Reference() and Release() methods of the wrapped class for |
162 | | * reference counting. The reference count is increased when assigning a raw |
163 | | * pointer to the smart pointer, and decreased when releasing it. |
164 | | * Somewhat similar to https://www.boost.org/doc/libs/latest/libs/smart_ptr/doc/html/smart_ptr.html#intrusive_ptr |
165 | | * |
166 | | * Only meant for T = OGRFeatureDefn and OGRSpatialReference |
167 | | */ |
168 | | template <class T> struct OGRRefCountedPtr : public OGRRefCountedPtrBase<T> |
169 | | { |
170 | | }; |
171 | | |
172 | | template <class T> |
173 | | inline bool operator==(const OGRRefCountedPtr<T> &lhs, std::nullptr_t) |
174 | 0 | { |
175 | 0 | return lhs.get() == nullptr; |
176 | 0 | } |
177 | | |
178 | | template <class T> |
179 | | inline bool operator==(std::nullptr_t, const OGRRefCountedPtr<T> &rhs) |
180 | | { |
181 | | return rhs.get() == nullptr; |
182 | | } |
183 | | |
184 | | template <class T> |
185 | | inline bool operator!=(const OGRRefCountedPtr<T> &lhs, std::nullptr_t) |
186 | 0 | { |
187 | 0 | return lhs.get() != nullptr; |
188 | 0 | } |
189 | | |
190 | | template <class T> |
191 | | inline bool operator!=(std::nullptr_t, const OGRRefCountedPtr<T> &rhs) |
192 | | { |
193 | | return rhs.get() != nullptr; |
194 | | } |
195 | | |
196 | | /*! @endcond */ |
197 | | |
198 | | #endif /* OGR_REFCOUNTEDPTR_INCLUDED */ |