Coverage Report

Created: 2025-07-07 10:01

/src/libreoffice/include/tools/weakbase.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
#ifndef INCLUDED_TOOLS_WEAKBASE_H
20
#define INCLUDED_TOOLS_WEAKBASE_H
21
22
#include <sal/types.h>
23
#include <rtl/ref.hxx>
24
#include <tools/toolsdllapi.h>
25
26
/** the template classes in this header are helper to implement weak references
27
    to implementation objects that are not refcounted.
28
29
    THIS IS NOT THREADSAFE
30
31
    Use this only to have 'safe' pointers to implementation objects that you
32
    don't own but that you reference with a pointer.
33
34
    Example:
35
36
    class ImplClass : public tools::WeakBase< ImplClass >
37
    {
38
        ~ImplClass() { clearWeek(); } // not needed but safer, see method description
39
        ...
40
    };
41
42
    class UserClass
43
    {
44
        tools::WeakReference< ImplClass > mxWeakRef;
45
46
        UserClass( ImplClass* pObject ) : mxWeakRef( pObject ) {}
47
48
        DoSomething()
49
        {
50
            if( mxWeakRef.is() )
51
                mxWeakRef->DoSomethingMore();
52
        }
53
    };
54
*/
55
namespace tools
56
{
57
class WeakBase;
58
59
/** private connection helper, do not use directly */
60
struct WeakConnection
61
{
62
    sal_Int32   mnRefCount;
63
    WeakBase*   mpReference;
64
65
0
    WeakConnection() : mnRefCount( 0 ), mpReference( nullptr ) {};
66
0
    WeakConnection( WeakBase* pReference ) : mnRefCount( 0 ), mpReference( pReference ) {};
67
0
    void acquire() { mnRefCount++; }
68
0
    void release() { mnRefCount--; if( mnRefCount == 0 ) delete this; }
69
};
70
71
/** template implementation to hold a weak reference to an instance of type reference_type */
72
template <class reference_type>
73
class SAL_WARN_UNUSED WeakReference
74
{
75
public:
76
    /** constructs an empty reference */
77
    inline WeakReference();
78
79
    /** constructs a reference with a pointer to a class derived from WeakBase */
80
    inline WeakReference( reference_type* pReference );
81
82
    /** constructs a reference from another reference */
83
    inline WeakReference( const WeakReference< reference_type >& rWeakRef );
84
85
    /** move a reference from another reference */
86
    inline WeakReference( WeakReference< reference_type >&& rWeakRef );
87
88
    /** returns true if the reference object is not null and still alive */
89
    inline bool is() const;
90
91
    /** returns true if the reference object is not null and still alive */
92
    operator bool() const { return is(); }
93
94
    /** returns the pointer to the reference object or null */
95
    inline reference_type * get() const;
96
97
    /** sets this reference to the given object or null */
98
    inline void reset( reference_type* pReference );
99
100
    /** resets this reference to null */
101
    inline void reset();
102
103
    /** returns the pointer to the reference object or null */
104
    inline reference_type * operator->() const;
105
106
    /** returns a ref to the reference object */
107
    inline reference_type& operator*() const;
108
109
    /** returns true if this instance references pReferenceObject */
110
    inline bool operator== (const reference_type * pReferenceObject) const;
111
112
    /** returns true if this instance and the given weakref reference the same object */
113
    inline bool operator== (const WeakReference<reference_type> & handle) const;
114
115
    /** only needed for using this class with stl containers */
116
    inline bool operator!= (const WeakReference<reference_type> & handle) const;
117
118
    /** only needed for using this class with stl containers */
119
    inline bool operator< (const WeakReference<reference_type> & handle) const;
120
121
    /** only needed for using this class with stl containers */
122
    inline bool operator> (const WeakReference<reference_type> & handle) const;
123
124
    /** the assignment operator */
125
    inline WeakReference<reference_type>& operator= (const WeakReference<reference_type> & handle);
126
127
    /** the move assignment operator */
128
    inline WeakReference<reference_type>& operator= (WeakReference<reference_type> && handle);
129
130
private:
131
    rtl::Reference<WeakConnection> mpWeakConnection;
132
};
133
134
/** derive your implementation classes from this class if you want them to support weak references */
135
class TOOLS_DLLPUBLIC WeakBase
136
{
137
    template<typename T> friend class WeakReference;
138
139
public:
140
554k
    WeakBase() {}
141
    virtual ~WeakBase();
142
    /** clears the reference pointer in all living weak references for this instance.
143
        Further created weak references will also be invalid.
144
        You should call this method in the d'tor of your derived classes for an early
145
        invalidate of all living weak references while your object is already inside
146
        it d'tor.
147
    */
148
    inline void clearWeak();
149
150
private:
151
    inline WeakConnection* getWeakConnection();
152
    rtl::Reference<WeakConnection> mpWeakConnection;
153
};
154
155
}
156
157
#endif
158
159
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */