Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef _UNIVERSALL_REFERENCE_HXX
21 : #define _UNIVERSALL_REFERENCE_HXX
22 :
23 : #include "sal/config.h"
24 : #include "xmloff/dllapi.h"
25 : #include <sal/types.h>
26 : #include <osl/interlck.h>
27 :
28 : /**
29 : * An instance of this class holds a pointer to an object. The lifetime of
30 : * the object is controled by the instance. The constructor calls
31 : * acquire() and the destructor calls release().
32 : * You could derive your class from the baseclass UniRefBase which implements
33 : * the methods acquire and release, yet.
34 : */
35 : template< class T > class UniReference
36 : {
37 : private:
38 : T* mpElement;
39 :
40 : public:
41 : /** Create an empty reference.*/
42 56236 : UniReference()
43 56236 : : mpElement( NULL )
44 56236 : {}
45 :
46 : /** Destroy the reference and releases the element.*/
47 : inline ~UniReference();
48 :
49 : /** Create a new reference with the same element as in rRef and acquire this one.*/
50 : inline UniReference( const UniReference< T > & rRef );
51 :
52 : /**
53 : * Create a new reference with the given element pElement and acquire this one.
54 : */
55 : inline UniReference( T * pElement );
56 :
57 : /**
58 : * Release the reference and set the new one pObj.
59 : */
60 : inline UniReference< T > & operator = ( T * pElement );
61 :
62 : /**
63 : * Release the reference and set the new one from rObj.
64 : */
65 : inline UniReference< T > & operator = ( const UniReference< T > & rRef );
66 :
67 : /**
68 : * Return the pointer to the element, may be null.
69 : */
70 : inline T* operator -> () const;
71 :
72 : /**
73 : * Returns true if the pointer to the element is valid.
74 : */
75 : inline sal_Bool is() const;
76 :
77 : /**
78 : * Return true if both elements refer to the same object.
79 : */
80 : inline sal_Bool operator == ( const UniReference & rRef ) const;
81 :
82 : /**
83 : * Return true if both elements does not refer to the same object.
84 : */
85 : inline sal_Bool operator != ( const UniReference & rRef ) const;
86 :
87 : /** Gets implementation pointer.
88 : This call does <b>not</b> acquire the implementation.
89 : <br>
90 : @return <b>un</b>acquired implementation pointer
91 : */
92 : inline T* get() const;
93 : };
94 :
95 : class XMLOFF_DLLPUBLIC UniRefBase
96 : {
97 : private:
98 : /**
99 : * The reference counter.
100 : */
101 : oslInterlockedCount m_refCount;
102 :
103 : public:
104 22272 : UniRefBase() : m_refCount( 0 )
105 22272 : {}
106 : virtual ~UniRefBase();
107 :
108 119523 : void acquire() { osl_atomic_increment( &m_refCount ); }
109 : void release();
110 :
111 : };
112 :
113 : ///////////////////////////////////////////////////////////////////////////////
114 : //
115 : // Inline-implementations of UniReference
116 : //
117 :
118 : /** Create a new reference with the same element as in rRef and acquire this one.*/
119 : template< class T >
120 70528 : inline UniReference< T >::UniReference( const UniReference< T > & rRef )
121 70528 : : mpElement( rRef.mpElement )
122 : {
123 70528 : if( mpElement )
124 69523 : mpElement->acquire();
125 70528 : }
126 :
127 : template< class T >
128 140993 : inline UniReference< T >::~UniReference()
129 : {
130 140993 : if( mpElement )
131 113666 : mpElement->release();
132 140993 : }
133 :
134 : /**
135 : * Create a new reference with the given element pElement and acquire this one.
136 : * @param pInterface the interface, pointer may be null.
137 : */
138 : template< class T >
139 14274 : inline UniReference< T >::UniReference( T * pElement )
140 14274 : : mpElement( pElement )
141 : {
142 14274 : if( mpElement )
143 14274 : mpElement->acquire();
144 14274 : }
145 :
146 : /**
147 : * Release the reference and set the new one pObj.<BR>
148 : * <B>The operation is not thread save. You must protect all assigns to a reference class.</B>
149 : */
150 : template< class T >
151 43219 : inline UniReference< T > & UniReference< T >::operator = ( T * pElement )
152 : {
153 43219 : if( pElement )
154 35381 : pElement->acquire();
155 43219 : if( mpElement )
156 5477 : mpElement->release();
157 :
158 43219 : mpElement = pElement;
159 :
160 43219 : return *this;
161 : }
162 :
163 : /**
164 : * Release the reference and set the new one from rObj.<BR>
165 : * <B>The operation is not thread save. You must protect all assigns to a reference class.</B>
166 : */
167 : template< class T >
168 26432 : inline UniReference< T > & UniReference< T >::operator = ( const UniReference< T > & rRef )
169 : {
170 26432 : return operator = ( rRef.mpElement );
171 : }
172 :
173 : /**
174 : * Return the pointer to the interface, may be null.
175 : */
176 : template< class T >
177 1438995 : inline T* UniReference< T >::operator -> () const
178 : {
179 1438995 : return get();
180 : }
181 :
182 : /**
183 : * Return the pointer to the interface, may be null.
184 : */
185 : template< class T >
186 1443567 : inline T* UniReference< T >::get () const
187 : {
188 1443567 : return static_cast< T * >( mpElement );
189 : }
190 :
191 : /**
192 : * Returns true if the pointer to the interface is valid.
193 : */
194 : template< class T >
195 84477 : inline sal_Bool UniReference< T >::is() const
196 : {
197 84477 : return (mpElement != 0);
198 : }
199 : /**
200 : * Return true if both interfaces refer to the same object. The operation can be
201 : * much more expensive than a pointer comparision.<BR>
202 : *
203 : * @param rRef another interface reference
204 : */
205 : template< class T >
206 : inline sal_Bool UniReference< T >::operator == ( const UniReference & rRef ) const
207 : {
208 : return ( mpElement == rRef.mpElement );
209 : }
210 : /**
211 : * Return true if both interfaces does not refer to the same object. The operation can be
212 : * much more expensive than a pointer comparision.<BR>
213 : *
214 : * @param rRef another interface reference
215 : */
216 : template< class T >
217 : inline sal_Bool UniReference< T >::operator != ( const UniReference & rRef ) const
218 : {
219 : return ( ! operator == ( rRef ) );
220 : }
221 :
222 : #endif // _UNIVERSALL_REFERENCE_HXX
223 :
224 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|