Branch data 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 delive your class from the baseclass UniRefBase wich 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 : 12004 : UniReference()
43 : 12004 : : mpElement( NULL )
44 : 12004 : {}
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 : 400 : UniRefBase() : m_refCount( 0 )
105 : 400 : {}
106 : : virtual ~UniRefBase();
107 : :
108 : 38756 : void acquire() { osl_incrementInterlockedCount( &m_refCount ); }
109 : : void release();
110 : : };
111 : :
112 : : ///////////////////////////////////////////////////////////////////////////////
113 : : //
114 : : // Inline-implementations of UniReference
115 : : //
116 : :
117 : : /** Create a new reference with the same element as in rRef and acquire this one.*/
118 : : template< class T >
119 : 13958 : inline UniReference< T >::UniReference( const UniReference< T > & rRef )
120 : 13958 : : mpElement( rRef.mpElement )
121 : : {
122 [ + - ][ + - ]: 13958 : if( mpElement )
[ + - ][ + - ]
[ # # ][ + - ]
[ + - ][ # # ]
[ + - ]
123 : 13958 : mpElement->acquire();
124 : 13958 : }
125 : :
126 : : template< class T >
127 : 30272 : inline UniReference< T >::~UniReference()
128 : : {
129 [ + + ][ + + ]: 30272 : if( mpElement )
[ + - ][ + - ]
[ + - ][ # # ]
[ + - ][ + - ]
[ # # ][ + - ]
130 : 29085 : mpElement->release();
131 : 30272 : }
132 : :
133 : : /**
134 : : * Create a new reference with the given element pElement and acquire this one.
135 : : * @param pInterface the interface, pointer may be null.
136 : : */
137 : : template< class T >
138 : 2992 : inline UniReference< T >::UniReference( T * pElement )
139 : 2992 : : mpElement( pElement )
140 : : {
141 [ + - ][ + - ]: 2992 : if( mpElement )
[ # # ]
142 : 2992 : mpElement->acquire();
143 : 2992 : }
144 : :
145 : : /**
146 : : * Release the reference and set the new one pObj.<BR>
147 : : * <B>The operation is not thread save. You must protect all assigns to a reference class.</B>
148 : : */
149 : : template< class T >
150 : 22798 : inline UniReference< T > & UniReference< T >::operator = ( T * pElement )
151 : : {
152 [ + - ][ + - ]: 22798 : if( pElement )
[ + + ][ + - ]
[ + - ][ + - ]
[ # # ][ + - ]
[ + - ][ # # ]
153 : 22672 : pElement->acquire();
154 [ - + ][ - + ]: 22798 : if( mpElement )
[ + + ][ - + ]
[ - + ][ - + ]
[ # # ][ - + ]
[ - + ][ # # ]
155 : 126 : mpElement->release();
156 : :
157 : 22798 : mpElement = pElement;
158 : :
159 : 22798 : return *this;
160 : : }
161 : :
162 : : /**
163 : : * Release the reference and set the new one from rObj.<BR>
164 : : * <B>The operation is not thread save. You must protect all assigns to a reference class.</B>
165 : : */
166 : : template< class T >
167 : 17366 : inline UniReference< T > & UniReference< T >::operator = ( const UniReference< T > & rRef )
168 : : {
169 : 17366 : return operator = ( rRef.mpElement );
170 : : }
171 : :
172 : : /**
173 : : * Return the pointer to the interface, may be null.
174 : : */
175 : : template< class T >
176 : 23627 : inline T* UniReference< T >::operator -> () const
177 : : {
178 : 23627 : return get();
179 : : }
180 : :
181 : : /**
182 : : * Return the pointer to the interface, may be null.
183 : : */
184 : : template< class T >
185 : 25136 : inline T* UniReference< T >::get () const
186 : : {
187 : 25136 : return static_cast< T * >( mpElement );
188 : : }
189 : :
190 : : /**
191 : : * Returns true if the pointer to the interface is valid.
192 : : */
193 : : template< class T >
194 : 39076 : inline sal_Bool UniReference< T >::is() const
195 : : {
196 : 39076 : return (mpElement != 0);
197 : : }
198 : : /**
199 : : * Return true if both interfaces refer to the same object. The operation can be
200 : : * much more expensive than a pointer comparision.<BR>
201 : : *
202 : : * @param rRef another interface reference
203 : : */
204 : : template< class T >
205 : : inline sal_Bool UniReference< T >::operator == ( const UniReference & rRef ) const
206 : : {
207 : : return ( mpElement == rRef.mpElement );
208 : : }
209 : : /**
210 : : * Return true if both interfaces does not refer to the same object. The operation can be
211 : : * much more expensive than a pointer comparision.<BR>
212 : : *
213 : : * @param rRef another interface reference
214 : : */
215 : : template< class T >
216 : : inline sal_Bool UniReference< T >::operator != ( const UniReference & rRef ) const
217 : : {
218 : : return ( ! operator == ( rRef ) );
219 : : }
220 : :
221 : : #endif // _UNIVERSALL_REFERENCE_HXX
222 : :
223 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|