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 31109 : WeakConnection( reference_type* pReference ) : mnRefCount( 0 ), mpReference( pReference ) {};
65 69341 : void acquire() { mnRefCount++; }
66 68492 : 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: */
|