Coverage Report

Created: 2026-04-10 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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 */