xref: /AOO41X/main/xmloff/inc/xmloff/uniref.hxx (revision ecfe53c5d1886e1e0d215b0d140d05282ab1c477)
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