xref: /AOO41X/main/tools/inc/tools/weakbase.h (revision 514f4c20bcebc1639918b6975cc4300e4484c27c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _TOOLS_WEAKBASE_H_
25 #define _TOOLS_WEAKBASE_H_
26 
27 #include <sal/types.h>
28 #include <osl/diagnose.h>
29 
30 /** the template classes in this header are helper to implement weak references
31     to implementation objects that are not refcounted.
32 
33     THIS IS NOT THREADSAFE
34 
35     Use this only to have 'safe' pointers to implementation objects that you
36     don't own but that you reference with a pointer.
37 
38     Example:
39 
40     class ImplClass : public tools::WeakBase< ImplClass >
41     {
42         ~ImplClass() { clearWeek(); } // not needed but safer, see method description
43         ...
44     };
45 
46     class UserClass
47     {
48         tools::WeakReference< ImplClass > mxWeakRef;
49 
50         UserClass( ImplClass* pOjbect ) : mxWeakRef( pObject ) {}
51 
52         DoSomething()
53         {
54             if( mxWeakRef.is() )
55                 mxWeakRef->DoSomethingMore();
56         }
57     };
58 */
59 namespace tools
60 {
61 
62 // --------------------------------------------------------------------
63 
64 /** private connection helper, do not use directly */
65 template <class reference_type>
66 struct WeakConnection
67 {
68     sal_Int32   mnRefCount;
69     reference_type* mpReference;
70 
WeakConnectionWeakConnection71     WeakConnection( reference_type* pReference ) : mnRefCount( 0 ), mpReference( pReference ) {};
acquireWeakConnection72     void acquire() { mnRefCount++; }
releaseWeakConnection73     void release() { mnRefCount--; if( mnRefCount == 0 ) delete this; }
74 };
75 
76 // --------------------------------------------------------------------
77 
78 /** template implementation to hold a weak reference to an instance of type reference_type */
79 template <class reference_type>
80 class WeakReference
81 {
82 public:
83     /** constructs an empty reference */
84     inline WeakReference();
85 
86     /** constructs a reference with a pointer to a class derived from WeakBase */
87     inline WeakReference( reference_type* pReference );
88 
89     /** constructs a reference with another reference */
90     inline WeakReference( const WeakReference< reference_type >& rWeakRef );
91 
92     inline ~WeakReference();
93 
94     /** returns true if the reference object is not null and still alive */
95     inline bool is() const;
96 
97     /** returns the pointer to the reference object or null */
98     inline reference_type * get() const;
99 
100     /** sets this reference to the given object or null */
101     inline void reset( reference_type* pReference );
102 
103     /** returns the pointer to the reference object or null */
104     inline reference_type * operator->() const;
105 
106     /** returns true if this instance references pReferenceObject */
107     inline sal_Bool operator== (const reference_type * pReferenceObject) const;
108 
109     /** returns true if this instance and the given weakref reference the same object */
110     inline sal_Bool operator== (const WeakReference<reference_type> & handle) const;
111 
112     /** only needed for using this class with stl containers */
113     inline sal_Bool operator!= (const WeakReference<reference_type> & handle) const;
114 
115     /** only needed for using this class with stl containers */
116     inline sal_Bool operator< (const WeakReference<reference_type> & handle) const;
117 
118     /** only needed for using this class with stl containers */
119     inline sal_Bool operator> (const WeakReference<reference_type> & handle) const;
120 
121     /** the assignment operator */
122     inline WeakReference<reference_type>& operator= (const WeakReference<reference_type> & handle);
123 
124 private:
125     WeakConnection< reference_type >* mpWeakConnection;
126 };
127 
128 // --------------------------------------------------------------------
129 
130 /** derive your implementation classes from this class if you want them to support weak references */
131 template <class reference_type>
132 class WeakBase
133 {
134     friend class WeakReference<reference_type>;
135 
136 public:
137     inline WeakBase();
138 
139     inline ~WeakBase();
140     /** clears the reference pointer in all living weak references for this instance.
141         Further created weak references will also be invalid.
142         You should call this method in the d'tor of your derived classes for an early
143         invalidate of all living weak references while youre object is already inside
144         it d'tor.
145     */
146     inline void clearWeak();
147 
148 private:
149     inline WeakConnection< reference_type >* getWeakConnection();
150     WeakConnection< reference_type >* mpWeakConnection;
151 };
152 
153 }
154 
155 #endif // _TOOLS_WEAKBASE_H_
156 
157