Coverage Report

Created: 2025-06-13 06:30

/src/wxwidgets/include/wx/sharedptr.h
Line
Count
Source (jump to first uncovered line)
1
/////////////////////////////////////////////////////////////////////////////
2
// Name:        wx/sharedptr.h
3
// Purpose:     Shared pointer based on the counted_ptr<> template, which
4
//              is in the public domain
5
// Author:      Robert Roebling, Yonat Sharon
6
// Copyright:   Robert Roebling
7
// Licence:     wxWindows licence
8
/////////////////////////////////////////////////////////////////////////////
9
10
#ifndef _WX_SHAREDPTR_H_
11
#define _WX_SHAREDPTR_H_
12
13
#include "wx/defs.h"
14
#include "wx/atomic.h"
15
16
// ----------------------------------------------------------------------------
17
// wxSharedPtr: A smart pointer with non-intrusive reference counting.
18
// ----------------------------------------------------------------------------
19
20
template <class T>
21
class wxSharedPtr
22
{
23
public:
24
    typedef T element_type;
25
26
    explicit wxSharedPtr( T* ptr = nullptr )
27
0
        : m_ref(nullptr)
28
0
    {
29
0
        if (ptr)
30
0
            m_ref = new reftype(ptr);
31
0
    }
32
33
    template<typename Deleter>
34
    explicit wxSharedPtr(T* ptr, Deleter d)
35
        : m_ref(nullptr)
36
    {
37
        if (ptr)
38
            m_ref = new reftype_with_deleter<Deleter>(ptr, d);
39
    }
40
41
0
    ~wxSharedPtr()                           { Release(); }
42
0
    wxSharedPtr(const wxSharedPtr& tocopy)   { Acquire(tocopy.m_ref); }
43
44
    wxSharedPtr& operator=( const wxSharedPtr& tocopy )
45
    {
46
        if (this != &tocopy)
47
        {
48
            Release();
49
            Acquire(tocopy.m_ref);
50
        }
51
        return *this;
52
    }
53
54
    wxSharedPtr& operator=( T* ptr )
55
0
    {
56
0
        if (get() != ptr)
57
0
        {
58
0
            Release();
59
0
            if (ptr)
60
0
                m_ref = new reftype(ptr);
61
0
        }
62
0
        return *this;
63
0
    }
64
65
    // test for pointer validity: defining conversion to unspecified_bool_type
66
    // and not more obvious bool to avoid implicit conversions to integer types
67
    typedef T *(wxSharedPtr<T>::*unspecified_bool_type)() const;
68
    operator unspecified_bool_type() const
69
0
    {
70
0
        if (m_ref && m_ref->m_ptr)
71
0
           return  &wxSharedPtr<T>::get;
72
0
        else
73
0
           return nullptr;
74
0
    }
75
76
    T& operator*() const
77
0
    {
78
0
        wxASSERT(m_ref != nullptr);
79
0
        wxASSERT(m_ref->m_ptr != nullptr);
80
0
        return *(m_ref->m_ptr);
81
0
    }
82
83
    T* operator->() const
84
0
    {
85
0
        wxASSERT(m_ref != nullptr);
86
0
        wxASSERT(m_ref->m_ptr != nullptr);
87
0
        return m_ref->m_ptr;
88
0
    }
89
90
    T* get() const
91
0
    {
92
0
        return m_ref ? m_ref->m_ptr : nullptr;
93
0
    }
94
95
    void reset( T* ptr = nullptr )
96
    {
97
        Release();
98
        if (ptr)
99
            m_ref = new reftype(ptr);
100
    }
101
102
    template<typename Deleter>
103
    void reset(T* ptr, Deleter d)
104
    {
105
        Release();
106
        if (ptr)
107
            m_ref = new reftype_with_deleter<Deleter>(ptr, d);
108
    }
109
110
    bool unique()   const    { return (m_ref ? m_ref->m_count == 1 : true); }
111
    long use_count() const   { return (m_ref ? (long)m_ref->m_count : 0); }
112
113
    template <class U>
114
    friend bool operator == (wxSharedPtr<T> const &a, wxSharedPtr<U> const &b )
115
    {
116
        return a.get() == b.get();
117
    }
118
119
    template <class U>
120
    friend bool operator != (wxSharedPtr<T> const &a, wxSharedPtr<U> const &b )
121
    {
122
        return a.get() != b.get();
123
    }
124
125
private:
126
127
    struct reftype
128
    {
129
0
        reftype(T* ptr) : m_ptr(ptr), m_count(1) {}
130
0
        virtual ~reftype() = default;
131
0
        virtual void delete_ptr() { delete m_ptr; }
132
133
        T*          m_ptr;
134
        wxAtomicInt m_count;
135
    };
136
137
    template<typename Deleter>
138
    struct reftype_with_deleter : public reftype
139
    {
140
        reftype_with_deleter(T* ptr, Deleter d) : reftype(ptr), m_deleter(d) {}
141
        virtual void delete_ptr() override { m_deleter(this->m_ptr); }
142
143
        Deleter m_deleter;
144
    };
145
146
    reftype* m_ref;
147
148
    void Acquire(reftype* ref)
149
0
    {
150
0
        m_ref = ref;
151
0
        if (ref)
152
0
            wxAtomicInc( ref->m_count );
153
0
    }
154
155
    void Release()
156
0
    {
157
0
        if (m_ref)
158
0
        {
159
0
            if (!wxAtomicDec( m_ref->m_count ))
160
0
            {
161
0
                m_ref->delete_ptr();
162
0
                delete m_ref;
163
0
            }
164
0
            m_ref = nullptr;
165
0
        }
166
0
    }
167
};
168
169
#endif // _WX_SHAREDPTR_H_