GDAL
ogr_refcountedptr.h
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
18#include <cstddef>
19#include <utility>
20
27template <class T> struct OGRRefCountedPtrBase
28{
29 public:
35 inline ~OGRRefCountedPtrBase()
36 {
37 reset(nullptr);
38 }
39
44 inline OGRRefCountedPtrBase(const OGRRefCountedPtrBase &other)
45 : OGRRefCountedPtrBase(other.m_poRawPtr, true)
46 {
47 }
48
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
69 inline OGRRefCountedPtrBase(OGRRefCountedPtrBase &&other)
70 {
71 std::swap(m_poRawPtr, other.m_poRawPtr);
72 }
73
80 inline OGRRefCountedPtrBase &operator=(OGRRefCountedPtrBase &&other)
81 {
82 reset(nullptr);
83 std::swap(m_poRawPtr, other.m_poRawPtr);
84 return *this;
85 }
86
93 inline void reset(T *poRawPtr = nullptr, bool add_ref = true)
94 {
95#ifdef __GNUC__
96#pragma GCC diagnostic push
97#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
98#endif
99 if (m_poRawPtr)
100 m_poRawPtr->Release();
101 m_poRawPtr = poRawPtr;
102 if (m_poRawPtr && add_ref)
103 m_poRawPtr->Reference();
104#ifdef __GNUC__
105#pragma GCC diagnostic pop
106#endif
107 }
108
110 inline T *get() const
111 {
112 return m_poRawPtr;
113 }
114
120 inline T &operator*() const
121 {
122 return *m_poRawPtr;
123 }
124
128 inline T *operator->() const
129 {
130 return m_poRawPtr;
131 }
132
134 inline explicit operator bool() const
135 {
136 return m_poRawPtr != nullptr;
137 }
138
139 protected:
140 inline explicit OGRRefCountedPtrBase(T *poRawPtr = nullptr,
141 bool add_ref = true)
142 : m_poRawPtr(poRawPtr)
143 {
144#ifdef __GNUC__
145#pragma GCC diagnostic push
146#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
147#endif
148 if (m_poRawPtr && add_ref)
149 m_poRawPtr->Reference();
150#ifdef __GNUC__
151#pragma GCC diagnostic pop
152#endif
153 }
154
155 private:
156 T *m_poRawPtr{};
157};
158
168template <class T> struct OGRRefCountedPtr : public OGRRefCountedPtrBase<T>
169{
170};
171
172template <class T>
173inline bool operator==(const OGRRefCountedPtr<T> &lhs, std::nullptr_t)
174{
175 return lhs.get() == nullptr;
176}
177
178template <class T>
179inline bool operator==(std::nullptr_t, const OGRRefCountedPtr<T> &rhs)
180{
181 return rhs.get() == nullptr;
182}
183
184template <class T>
185inline bool operator!=(const OGRRefCountedPtr<T> &lhs, std::nullptr_t)
186{
187 return lhs.get() != nullptr;
188}
189
190template <class T>
191inline bool operator!=(std::nullptr_t, const OGRRefCountedPtr<T> &rhs)
192{
193 return rhs.get() != nullptr;
194}
195
198#endif /* OGR_REFCOUNTEDPTR_INCLUDED */