Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #ifndef _RTL_REF_HXX_
30 : : #define _RTL_REF_HXX_
31 : :
32 : : #include <sal/types.h>
33 : : #include <osl/diagnose.h>
34 : : #include <osl/interlck.h>
35 : :
36 : : namespace rtl
37 : : {
38 : :
39 : : /** Interface for a reference type.
40 : : */
41 : 2025246 : class IReference
42 : : {
43 : : public:
44 : : /** @see osl_incrementInterlockedCount.
45 : : */
46 : : virtual oslInterlockedCount SAL_CALL acquire() = 0;
47 : :
48 : : /** @see osl_decrementInterlockedCount.
49 : : */
50 : : virtual oslInterlockedCount SAL_CALL release() = 0;
51 : :
52 : : #if !defined _MSC_VER // public -> protected changes mangled names there
53 : : protected:
54 : : #endif
55 : 2020530 : ~IReference() {}
56 : : // avoid warnings about virtual members and non-virtual dtor
57 : : };
58 : :
59 : :
60 : : /** Template reference class for reference type derived from IReference.
61 : : */
62 : : template <class reference_type>
63 : : class Reference
64 : : {
65 : : /** The <b>reference_type</b> body pointer.
66 : : */
67 : : reference_type * m_pBody;
68 : :
69 : :
70 : : public:
71 : : /** Constructor...
72 : : */
73 : 22830331 : inline Reference()
74 : 22830331 : : m_pBody (0)
75 : 22830331 : {}
76 : :
77 : :
78 : : /** Constructor...
79 : : */
80 : 46775970 : inline Reference (reference_type * pBody)
81 : 46775970 : : m_pBody (pBody)
82 : : {
83 [ + + ][ + + ]: 46775970 : if (m_pBody)
[ + + ][ + - ]
[ + - ][ + - ]
[ + - ]
84 : 46418375 : m_pBody->acquire();
85 : 46775970 : }
86 : :
87 : :
88 : : /** Copy constructor...
89 : : */
90 : 149973209 : inline Reference (const Reference<reference_type> & handle)
91 : 149973209 : : m_pBody (handle.m_pBody)
92 : : {
93 [ + + ][ + + ]: 149973209 : if (m_pBody)
[ + + ][ + - ]
[ + - ][ + - ]
94 : 130488409 : m_pBody->acquire();
95 : 149973209 : }
96 : :
97 : :
98 : : /** Destructor...
99 : : */
100 : 219189797 : inline ~Reference()
101 : : {
102 [ + + ][ + + ]: 219189797 : if (m_pBody)
[ + + ][ + + ]
[ + + ][ + + ]
[ + - ][ + - ]
103 : 184470548 : m_pBody->release();
104 : 219189802 : }
105 : :
106 : : /** Set...
107 : : Similar to assignment.
108 : : */
109 : : inline Reference<reference_type> &
110 : 50115434 : SAL_CALL set (reference_type * pBody)
111 : : {
112 [ + + ][ + + ]: 50115434 : if (pBody)
[ + + ][ + - ]
[ + - ][ # # ]
113 : 44643324 : pBody->acquire();
114 : 50115432 : reference_type * const pOld = m_pBody;
115 : 50115432 : m_pBody = pBody;
116 [ + + ][ + + ]: 50115432 : if (pOld)
[ + + ][ - + ]
[ - + ][ # # ]
117 : 31018047 : pOld->release();
118 : 50115432 : return *this;
119 : : }
120 : :
121 : : /** Assignment.
122 : : Unbinds this instance from its body (if bound) and
123 : : bind it to the body represented by the handle.
124 : : */
125 : : inline Reference<reference_type> &
126 : 47351679 : SAL_CALL operator= (const Reference<reference_type> & handle)
127 : : {
128 : 47351679 : return set( handle.m_pBody );
129 : : }
130 : :
131 : : /** Assignment...
132 : : */
133 : : inline Reference<reference_type> &
134 : 1376176 : SAL_CALL operator= (reference_type * pBody)
135 : : {
136 : 1376176 : return set( pBody );
137 : : }
138 : :
139 : : /** Unbind the body from this handle.
140 : : Note that for a handle representing a large body,
141 : : "handle.clear().set(new body());" _might_
142 : : perform a little bit better than "handle.set(new body());",
143 : : since in the second case two large objects exist in memory
144 : : (the old body and the new body).
145 : : */
146 : 6905585 : inline Reference<reference_type> & SAL_CALL clear()
147 : : {
148 [ + + ][ + + ]: 6905585 : if (m_pBody)
[ + + ]
149 : : {
150 : 6751825 : reference_type * const pOld = m_pBody;
151 : 6751825 : m_pBody = 0;
152 : 6751825 : pOld->release();
153 : : }
154 : 6905585 : return *this;
155 : : }
156 : :
157 : :
158 : : /** Get the body. Can be used instead of operator->().
159 : : I.e. handle->someBodyOp() and handle.get()->someBodyOp()
160 : : are the same.
161 : : */
162 : 36179891 : inline reference_type * SAL_CALL get() const
163 : : {
164 : 36179891 : return m_pBody;
165 : : }
166 : :
167 : :
168 : : /** Probably most common used: handle->someBodyOp().
169 : : */
170 : 256925775 : inline reference_type * SAL_CALL operator->() const
171 : : {
172 : : OSL_PRECOND(m_pBody, "Reference::operator->() : null body");
173 : 256925775 : return m_pBody;
174 : : }
175 : :
176 : :
177 : : /** Allows (*handle).someBodyOp().
178 : : */
179 : 5859511 : inline reference_type & SAL_CALL operator*() const
180 : : {
181 : : OSL_PRECOND(m_pBody, "Reference::operator*() : null body");
182 : 5859511 : return *m_pBody;
183 : : }
184 : :
185 : :
186 : : /** Returns True if the handle does point to a valid body.
187 : : */
188 : 185812215 : inline sal_Bool SAL_CALL is() const
189 : : {
190 : 185812215 : return (m_pBody != 0);
191 : : }
192 : :
193 : :
194 : : /** Returns True if this points to pBody.
195 : : */
196 : 397088 : inline sal_Bool SAL_CALL operator== (const reference_type * pBody) const
197 : : {
198 : 397088 : return (m_pBody == pBody);
199 : : }
200 : :
201 : :
202 : : /** Returns True if handle points to the same body.
203 : : */
204 : : inline sal_Bool
205 : 23052 : SAL_CALL operator== (const Reference<reference_type> & handle) const
206 : : {
207 : 23052 : return (m_pBody == handle.m_pBody);
208 : : }
209 : :
210 : :
211 : : /** Needed to place References into STL collection.
212 : : */
213 : : inline sal_Bool
214 : 1512019 : SAL_CALL operator!= (const Reference<reference_type> & handle) const
215 : : {
216 : 1512019 : return (m_pBody != handle.m_pBody);
217 : : }
218 : :
219 : :
220 : : /** Needed to place References into STL collection.
221 : : */
222 : : inline sal_Bool
223 : 0 : SAL_CALL operator< (const Reference<reference_type> & handle) const
224 : : {
225 : 0 : return (m_pBody < handle.m_pBody);
226 : : }
227 : :
228 : :
229 : : /** Needed to place References into STL collection.
230 : : */
231 : : inline sal_Bool
232 : : SAL_CALL operator> (const Reference<reference_type> & handle) const
233 : : {
234 : : return (m_pBody > handle.m_pBody);
235 : : }
236 : : };
237 : :
238 : : /// @cond INTERNAL
239 : : /** Enables boost::mem_fn and boost::bind to recognize Reference.
240 : : */
241 : : template <typename T>
242 : 34 : inline T * get_pointer( Reference<T> const& r )
243 : : {
244 : 34 : return r.get();
245 : : }
246 : : /// @endcond
247 : :
248 : : } // namespace rtl
249 : :
250 : : #endif /* !_RTL_REF_HXX_ */
251 : :
252 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|