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 _UNIVERSALL_REFERENCE_HXX 25 #define _UNIVERSALL_REFERENCE_HXX 26 27 #include "sal/config.h" 28 #include "xmloff/dllapi.h" 29 #include <sal/types.h> 30 #include <osl/interlck.h> 31 32 /** 33 * An instance of this class holds a pointer to an object. The lifetime of 34 * the object is controled by the instance. The constructor calls 35 * acquire() and the destructor calls release(). 36 * You could delive your class from the baseclass UniRefBase wich implements 37 * the methods acquire and release, yet. 38 */ 39 template< class T > class UniReference 40 { 41 private: 42 T* mpElement; 43 44 public: 45 /** Create an empty reference.*/ UniReference()46 UniReference() 47 : mpElement( NULL ) 48 {} 49 50 /** Destroy the reference and releases the element.*/ 51 inline ~UniReference(); 52 53 /** Create a new reference with the same element as in rRef and acquire this one.*/ 54 inline UniReference( const UniReference< T > & rRef ); 55 56 /** 57 * Create a new reference with the given element pElement and acquire this one. 58 */ 59 inline UniReference( T * pElement ); 60 61 /** 62 * Release the reference and set the new one pObj. 63 */ 64 inline UniReference< T > & operator = ( T * pElement ); 65 66 /** 67 * Release the reference and set the new one from rObj. 68 */ 69 inline UniReference< T > & operator = ( const UniReference< T > & rRef ); 70 71 /** 72 * Return the pointer to the element, may be null. 73 */ 74 inline T* operator -> () const; 75 76 /** 77 * Returns true if the pointer to the element is valid. 78 */ 79 inline sal_Bool is() const; 80 81 /** 82 * Return true if both elements refer to the same object. 83 */ 84 inline sal_Bool operator == ( const UniReference & rRef ) const; 85 86 /** 87 * Return true if both elements does not refer to the same object. 88 */ 89 inline sal_Bool operator != ( const UniReference & rRef ) const; 90 91 /** Gets implementation pointer. 92 This call does <b>not</b> acquire the implementation. 93 <br> 94 @return <b>un</b>acquired implementation pointer 95 */ 96 inline T* get() const; 97 }; 98 99 class XMLOFF_DLLPUBLIC UniRefBase 100 { 101 private: 102 /** 103 * The reference counter. 104 */ 105 oslInterlockedCount m_refCount; 106 107 public: UniRefBase()108 UniRefBase() : m_refCount( 0 ) 109 {} 110 virtual ~UniRefBase(); 111 acquire()112 void acquire() { osl_incrementInterlockedCount( &m_refCount ); } 113 void release(); 114 }; 115 116 /////////////////////////////////////////////////////////////////////////////// 117 // 118 // Inline-implementations of UniReference 119 // 120 121 /** Create a new reference with the same element as in rRef and acquire this one.*/ 122 template< class T > UniReference(const UniReference<T> & rRef)123inline UniReference< T >::UniReference( const UniReference< T > & rRef ) 124 : mpElement( rRef.mpElement ) 125 { 126 if( mpElement ) 127 mpElement->acquire(); 128 } 129 130 template< class T > ~UniReference()131inline UniReference< T >::~UniReference() 132 { 133 if( mpElement ) 134 mpElement->release(); 135 } 136 137 /** 138 * Create a new reference with the given element pElement and acquire this one. 139 * @param pInterface the interface, pointer may be null. 140 */ 141 template< class T > UniReference(T * pElement)142inline UniReference< T >::UniReference( T * pElement ) 143 : mpElement( pElement ) 144 { 145 if( mpElement ) 146 mpElement->acquire(); 147 } 148 149 /** 150 * Release the reference and set the new one pObj.<BR> 151 * <B>The operation is not thread save. You must protect all assigns to a reference class.</B> 152 */ 153 template< class T > operator =(T * pElement)154inline UniReference< T > & UniReference< T >::operator = ( T * pElement ) 155 { 156 if( pElement ) 157 pElement->acquire(); 158 if( mpElement ) 159 mpElement->release(); 160 161 mpElement = pElement; 162 163 return *this; 164 } 165 166 /** 167 * Release the reference and set the new one from rObj.<BR> 168 * <B>The operation is not thread save. You must protect all assigns to a reference class.</B> 169 */ 170 template< class T > operator =(const UniReference<T> & rRef)171inline UniReference< T > & UniReference< T >::operator = ( const UniReference< T > & rRef ) 172 { 173 return operator = ( rRef.mpElement ); 174 } 175 176 /** 177 * Return the pointer to the interface, may be null. 178 */ 179 template< class T > operator ->() const180inline T* UniReference< T >::operator -> () const 181 { 182 return get(); 183 } 184 185 /** 186 * Return the pointer to the interface, may be null. 187 */ 188 template< class T > get() const189inline T* UniReference< T >::get () const 190 { 191 return static_cast< T * >( mpElement ); 192 } 193 194 /** 195 * Returns true if the pointer to the interface is valid. 196 */ 197 template< class T > is() const198inline sal_Bool UniReference< T >::is() const 199 { 200 return (mpElement != 0); 201 } 202 /** 203 * Return true if both interfaces refer to the same object. The operation can be 204 * much more expensive than a pointer comparision.<BR> 205 * 206 * @param rRef another interface reference 207 */ 208 template< class T > operator ==(const UniReference & rRef) const209inline sal_Bool UniReference< T >::operator == ( const UniReference & rRef ) const 210 { 211 return ( mpElement == rRef.mpElement ); 212 } 213 /** 214 * Return true if both interfaces does not refer to the same object. The operation can be 215 * much more expensive than a pointer comparision.<BR> 216 * 217 * @param rRef another interface reference 218 */ 219 template< class T > operator !=(const UniReference & rRef) const220inline sal_Bool UniReference< T >::operator != ( const UniReference & rRef ) const 221 { 222 return ( ! operator == ( rRef ) ); 223 } 224 225 #endif // _UNIVERSALL_REFERENCE_HXX 226