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