xref: /aoo4110/main/xmloff/inc/xmloff/uniref.hxx (revision b1cdbd2c)
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)123 inline 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()131 inline 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)142 inline 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)154 inline 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)171 inline 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 ->() const180 inline 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() const189 inline 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() const198 inline 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) const209 inline 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) const220 inline sal_Bool UniReference< T >::operator != ( const UniReference & rRef ) const
221 {
222 	return ( ! operator == ( rRef ) );
223 }
224 
225 #endif	// _UNIVERSALL_REFERENCE_HXX
226