xref: /trunk/main/tools/inc/tools/weakbase.h (revision 514f4c20)
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 
WeakConnectiontools::WeakConnection71 	WeakConnection( reference_type* pReference ) : mnRefCount( 0 ), mpReference( pReference ) {};
acquiretools::WeakConnection72 	void acquire() { mnRefCount++; }
releasetools::WeakConnection73 	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