Branch data Line data Source code
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 _TOOLS_WEAKBASE_H_
20 : : #define _TOOLS_WEAKBASE_H_
21 : :
22 : : #include <sal/types.h>
23 : : #include <osl/diagnose.h>
24 : :
25 : : /** the template classes in this header are helper to implement weak references
26 : : to implementation objects that are not refcounted.
27 : :
28 : : THIS IS NOT THREADSAFE
29 : :
30 : : Use this only to have 'safe' pointers to implementation objects that you
31 : : don't own but that you reference with a pointer.
32 : :
33 : : Example:
34 : :
35 : : class ImplClass : public tools::WeakBase< ImplClass >
36 : : {
37 : : ~ImplClass() { clearWeek(); } // not needed but safer, see method description
38 : : ...
39 : : };
40 : :
41 : : class UserClass
42 : : {
43 : : tools::WeakReference< ImplClass > mxWeakRef;
44 : :
45 : : UserClass( ImplClass* pOjbect ) : mxWeakRef( pObject ) {}
46 : :
47 : : DoSomething()
48 : : {
49 : : if( mxWeakRef.is() )
50 : : mxWeakRef->DoSomethingMore();
51 : : }
52 : : };
53 : : */
54 : : namespace tools
55 : : {
56 : :
57 : : /** private connection helper, do not use directly */
58 : : template <class reference_type>
59 : : struct WeakConnection
60 : : {
61 : : sal_Int32 mnRefCount;
62 : : reference_type* mpReference;
63 : :
64 : 708879 : WeakConnection( reference_type* pReference ) : mnRefCount( 0 ), mpReference( pReference ) {};
65 : 1340131 : void acquire() { mnRefCount++; }
66 [ + + ][ + + ]: 1339605 : void release() { mnRefCount--; if( mnRefCount == 0 ) delete this; }
67 : : };
68 : :
69 : : /** template implementation to hold a weak reference to an instance of type reference_type */
70 : : template <class reference_type>
71 : : class WeakReference
72 : : {
73 : : public:
74 : : /** constructs an empty reference */
75 : : inline WeakReference();
76 : :
77 : : /** constructs a reference with a pointer to a class derived from WeakBase */
78 : : inline WeakReference( reference_type* pReference );
79 : :
80 : : /** constructs a reference with another reference */
81 : : inline WeakReference( const WeakReference< reference_type >& rWeakRef );
82 : :
83 : : inline ~WeakReference();
84 : :
85 : : /** returns true if the reference object is not null and still alive */
86 : : inline bool is() const;
87 : :
88 : : /** returns the pointer to the reference object or null */
89 : : inline reference_type * get() const;
90 : :
91 : : /** sets this reference to the given object or null */
92 : : inline void reset( reference_type* pReference );
93 : :
94 : : /** returns the pointer to the reference object or null */
95 : : inline reference_type * operator->() const;
96 : :
97 : : /** returns true if this instance references pReferenceObject */
98 : : inline sal_Bool operator== (const reference_type * pReferenceObject) const;
99 : :
100 : : /** returns true if this instance and the given weakref reference the same object */
101 : : inline sal_Bool operator== (const WeakReference<reference_type> & handle) const;
102 : :
103 : : /** only needed for using this class with stl containers */
104 : : inline sal_Bool operator!= (const WeakReference<reference_type> & handle) const;
105 : :
106 : : /** only needed for using this class with stl containers */
107 : : inline sal_Bool operator< (const WeakReference<reference_type> & handle) const;
108 : :
109 : : /** only needed for using this class with stl containers */
110 : : inline sal_Bool operator> (const WeakReference<reference_type> & handle) const;
111 : :
112 : : /** the assignment operator */
113 : : inline WeakReference<reference_type>& operator= (const WeakReference<reference_type> & handle);
114 : :
115 : : private:
116 : : WeakConnection< reference_type >* mpWeakConnection;
117 : : };
118 : :
119 : : /** derive your implementation classes from this class if you want them to support weak references */
120 : : template <class reference_type>
121 : : class WeakBase
122 : : {
123 : : friend class WeakReference<reference_type>;
124 : :
125 : : public:
126 : : inline WeakBase();
127 : :
128 : : inline ~WeakBase();
129 : : /** clears the reference pointer in all living weak references for this instance.
130 : : Further created weak references will also be invalid.
131 : : You should call this method in the d'tor of your derived classes for an early
132 : : invalidate of all living weak references while youre object is already inside
133 : : it d'tor.
134 : : */
135 : : inline void clearWeak();
136 : :
137 : : private:
138 : : inline WeakConnection< reference_type >* getWeakConnection();
139 : : WeakConnection< reference_type >* mpWeakConnection;
140 : : };
141 : :
142 : : }
143 : :
144 : : #endif
145 : :
146 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|