xref: /aoo4110/main/sal/inc/rtl/ref.hxx (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski #ifndef _RTL_REF_HXX_
25*b1cdbd2cSJim Jagielski #define _RTL_REF_HXX_
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include <sal/types.h>
28*b1cdbd2cSJim Jagielski #include <osl/diagnose.h>
29*b1cdbd2cSJim Jagielski #include <osl/interlck.h>
30*b1cdbd2cSJim Jagielski 
31*b1cdbd2cSJim Jagielski namespace rtl
32*b1cdbd2cSJim Jagielski {
33*b1cdbd2cSJim Jagielski 
34*b1cdbd2cSJim Jagielski /** Interface for a reference type.
35*b1cdbd2cSJim Jagielski */
36*b1cdbd2cSJim Jagielski class IReference
37*b1cdbd2cSJim Jagielski {
38*b1cdbd2cSJim Jagielski public:
39*b1cdbd2cSJim Jagielski 	/** @see osl_incrementInterlockedCount.
40*b1cdbd2cSJim Jagielski 	 */
41*b1cdbd2cSJim Jagielski 	virtual oslInterlockedCount SAL_CALL acquire() = 0;
42*b1cdbd2cSJim Jagielski 
43*b1cdbd2cSJim Jagielski 	/** @see osl_decrementInterlockedCount.
44*b1cdbd2cSJim Jagielski 	 */
45*b1cdbd2cSJim Jagielski 	virtual oslInterlockedCount SAL_CALL release() = 0;
46*b1cdbd2cSJim Jagielski };
47*b1cdbd2cSJim Jagielski 
48*b1cdbd2cSJim Jagielski 
49*b1cdbd2cSJim Jagielski /** Template reference class for reference type derived from IReference.
50*b1cdbd2cSJim Jagielski */
51*b1cdbd2cSJim Jagielski template <class reference_type>
52*b1cdbd2cSJim Jagielski class Reference
53*b1cdbd2cSJim Jagielski {
54*b1cdbd2cSJim Jagielski 	/** The <b>reference_type</b> body pointer.
55*b1cdbd2cSJim Jagielski 	 */
56*b1cdbd2cSJim Jagielski 	reference_type * m_pBody;
57*b1cdbd2cSJim Jagielski 
58*b1cdbd2cSJim Jagielski 
59*b1cdbd2cSJim Jagielski public:
60*b1cdbd2cSJim Jagielski 	/** Constructor...
61*b1cdbd2cSJim Jagielski 	 */
Reference()62*b1cdbd2cSJim Jagielski 	inline Reference()
63*b1cdbd2cSJim Jagielski 		: m_pBody (0)
64*b1cdbd2cSJim Jagielski 	{}
65*b1cdbd2cSJim Jagielski 
66*b1cdbd2cSJim Jagielski 
67*b1cdbd2cSJim Jagielski 	/** Constructor...
68*b1cdbd2cSJim Jagielski 	 */
Reference(reference_type * pBody)69*b1cdbd2cSJim Jagielski 	inline Reference (reference_type * pBody)
70*b1cdbd2cSJim Jagielski 		: m_pBody (pBody)
71*b1cdbd2cSJim Jagielski 	{
72*b1cdbd2cSJim Jagielski 		if (m_pBody)
73*b1cdbd2cSJim Jagielski 			m_pBody->acquire();
74*b1cdbd2cSJim Jagielski 	}
75*b1cdbd2cSJim Jagielski 
76*b1cdbd2cSJim Jagielski 
77*b1cdbd2cSJim Jagielski 	/** Copy constructor...
78*b1cdbd2cSJim Jagielski 	 */
Reference(const Reference<reference_type> & handle)79*b1cdbd2cSJim Jagielski 	inline Reference (const Reference<reference_type> & handle)
80*b1cdbd2cSJim Jagielski 		: m_pBody (handle.m_pBody)
81*b1cdbd2cSJim Jagielski 	{
82*b1cdbd2cSJim Jagielski 		if (m_pBody)
83*b1cdbd2cSJim Jagielski 			m_pBody->acquire();
84*b1cdbd2cSJim Jagielski 	}
85*b1cdbd2cSJim Jagielski 
86*b1cdbd2cSJim Jagielski 
87*b1cdbd2cSJim Jagielski 	/** Destructor...
88*b1cdbd2cSJim Jagielski 	 */
~Reference()89*b1cdbd2cSJim Jagielski 	inline ~Reference()
90*b1cdbd2cSJim Jagielski 	{
91*b1cdbd2cSJim Jagielski 		if (m_pBody)
92*b1cdbd2cSJim Jagielski 			m_pBody->release();
93*b1cdbd2cSJim Jagielski 	}
94*b1cdbd2cSJim Jagielski 
95*b1cdbd2cSJim Jagielski 	/** Set...
96*b1cdbd2cSJim Jagielski 	 	Similar to assignment.
97*b1cdbd2cSJim Jagielski 	 */
98*b1cdbd2cSJim Jagielski 	inline Reference<reference_type> &
set(reference_type * pBody)99*b1cdbd2cSJim Jagielski 	SAL_CALL set (reference_type * pBody)
100*b1cdbd2cSJim Jagielski 	{
101*b1cdbd2cSJim Jagielski 		if (pBody)
102*b1cdbd2cSJim Jagielski 			pBody->acquire();
103*b1cdbd2cSJim Jagielski         reference_type * const pOld = m_pBody;
104*b1cdbd2cSJim Jagielski 		m_pBody = pBody;
105*b1cdbd2cSJim Jagielski 		if (pOld)
106*b1cdbd2cSJim Jagielski 			pOld->release();
107*b1cdbd2cSJim Jagielski 		return *this;
108*b1cdbd2cSJim Jagielski 	}
109*b1cdbd2cSJim Jagielski 
110*b1cdbd2cSJim Jagielski 	/** Assignment.
111*b1cdbd2cSJim Jagielski 	 	Unbinds this instance from its body (if bound) and
112*b1cdbd2cSJim Jagielski 	 	bind it to the body represented by the handle.
113*b1cdbd2cSJim Jagielski 	 */
114*b1cdbd2cSJim Jagielski 	inline Reference<reference_type> &
operator =(const Reference<reference_type> & handle)115*b1cdbd2cSJim Jagielski 	SAL_CALL operator= (const Reference<reference_type> & handle)
116*b1cdbd2cSJim Jagielski 	{
117*b1cdbd2cSJim Jagielski         return set( handle.m_pBody );
118*b1cdbd2cSJim Jagielski 	}
119*b1cdbd2cSJim Jagielski 
120*b1cdbd2cSJim Jagielski 	/** Assignment...
121*b1cdbd2cSJim Jagielski 	 */
122*b1cdbd2cSJim Jagielski 	inline Reference<reference_type> &
operator =(reference_type * pBody)123*b1cdbd2cSJim Jagielski 	SAL_CALL operator= (reference_type * pBody)
124*b1cdbd2cSJim Jagielski 	{
125*b1cdbd2cSJim Jagielski         return set( pBody );
126*b1cdbd2cSJim Jagielski 	}
127*b1cdbd2cSJim Jagielski 
128*b1cdbd2cSJim Jagielski 	/** Unbind the body from this handle.
129*b1cdbd2cSJim Jagielski 	 	Note that for a handle representing a large body,
130*b1cdbd2cSJim Jagielski 	 	"handle.clear().set(new body());" _might_
131*b1cdbd2cSJim Jagielski 	 	perform a little bit better than "handle.set(new body());",
132*b1cdbd2cSJim Jagielski 	 	since in the second case two large objects exist in memory
133*b1cdbd2cSJim Jagielski 	 	(the old body and the new body).
134*b1cdbd2cSJim Jagielski 	 */
clear()135*b1cdbd2cSJim Jagielski 	inline Reference<reference_type> & SAL_CALL clear()
136*b1cdbd2cSJim Jagielski 	{
137*b1cdbd2cSJim Jagielski 		if (m_pBody)
138*b1cdbd2cSJim Jagielski 		{
139*b1cdbd2cSJim Jagielski             reference_type * const pOld = m_pBody;
140*b1cdbd2cSJim Jagielski 			m_pBody = 0;
141*b1cdbd2cSJim Jagielski 			pOld->release();
142*b1cdbd2cSJim Jagielski 		}
143*b1cdbd2cSJim Jagielski 		return *this;
144*b1cdbd2cSJim Jagielski 	}
145*b1cdbd2cSJim Jagielski 
146*b1cdbd2cSJim Jagielski 
147*b1cdbd2cSJim Jagielski 	/** Get the body. Can be used instead of operator->().
148*b1cdbd2cSJim Jagielski 	 	I.e. handle->someBodyOp() and handle.get()->someBodyOp()
149*b1cdbd2cSJim Jagielski 	 	are the same.
150*b1cdbd2cSJim Jagielski 	 */
get() const151*b1cdbd2cSJim Jagielski 	inline reference_type * SAL_CALL get() const
152*b1cdbd2cSJim Jagielski 	{
153*b1cdbd2cSJim Jagielski 		return m_pBody;
154*b1cdbd2cSJim Jagielski 	}
155*b1cdbd2cSJim Jagielski 
156*b1cdbd2cSJim Jagielski 
157*b1cdbd2cSJim Jagielski 	/** Probably most common used: handle->someBodyOp().
158*b1cdbd2cSJim Jagielski 	 */
operator ->() const159*b1cdbd2cSJim Jagielski 	inline reference_type * SAL_CALL operator->() const
160*b1cdbd2cSJim Jagielski 	{
161*b1cdbd2cSJim Jagielski 		OSL_PRECOND(m_pBody, "Reference::operator->() : null body");
162*b1cdbd2cSJim Jagielski 		return m_pBody;
163*b1cdbd2cSJim Jagielski 	}
164*b1cdbd2cSJim Jagielski 
165*b1cdbd2cSJim Jagielski 
166*b1cdbd2cSJim Jagielski 	/** Allows (*handle).someBodyOp().
167*b1cdbd2cSJim Jagielski 	*/
operator *() const168*b1cdbd2cSJim Jagielski 	inline reference_type & SAL_CALL operator*() const
169*b1cdbd2cSJim Jagielski 	{
170*b1cdbd2cSJim Jagielski 		OSL_PRECOND(m_pBody, "Reference::operator*() : null body");
171*b1cdbd2cSJim Jagielski 		return *m_pBody;
172*b1cdbd2cSJim Jagielski 	}
173*b1cdbd2cSJim Jagielski 
174*b1cdbd2cSJim Jagielski 
175*b1cdbd2cSJim Jagielski 	/** Returns True if the handle does point to a valid body.
176*b1cdbd2cSJim Jagielski 	 */
is() const177*b1cdbd2cSJim Jagielski 	inline sal_Bool SAL_CALL is() const
178*b1cdbd2cSJim Jagielski 	{
179*b1cdbd2cSJim Jagielski 		return (m_pBody != 0);
180*b1cdbd2cSJim Jagielski 	}
181*b1cdbd2cSJim Jagielski 
182*b1cdbd2cSJim Jagielski 
183*b1cdbd2cSJim Jagielski 	/** Returns True if this points to pBody.
184*b1cdbd2cSJim Jagielski 	 */
operator ==(const reference_type * pBody) const185*b1cdbd2cSJim Jagielski 	inline sal_Bool SAL_CALL operator== (const reference_type * pBody) const
186*b1cdbd2cSJim Jagielski 	{
187*b1cdbd2cSJim Jagielski 		return (m_pBody == pBody);
188*b1cdbd2cSJim Jagielski 	}
189*b1cdbd2cSJim Jagielski 
190*b1cdbd2cSJim Jagielski 
191*b1cdbd2cSJim Jagielski 	/** Returns True if handle points to the same body.
192*b1cdbd2cSJim Jagielski 	 */
193*b1cdbd2cSJim Jagielski 	inline sal_Bool
operator ==(const Reference<reference_type> & handle) const194*b1cdbd2cSJim Jagielski 	SAL_CALL operator== (const Reference<reference_type> & handle) const
195*b1cdbd2cSJim Jagielski 	{
196*b1cdbd2cSJim Jagielski 		return (m_pBody == handle.m_pBody);
197*b1cdbd2cSJim Jagielski 	}
198*b1cdbd2cSJim Jagielski 
199*b1cdbd2cSJim Jagielski 
200*b1cdbd2cSJim Jagielski 	/** Needed to place References into STL collection.
201*b1cdbd2cSJim Jagielski 	 */
202*b1cdbd2cSJim Jagielski 	inline sal_Bool
operator !=(const Reference<reference_type> & handle) const203*b1cdbd2cSJim Jagielski 	SAL_CALL operator!= (const Reference<reference_type> & handle) const
204*b1cdbd2cSJim Jagielski 	{
205*b1cdbd2cSJim Jagielski 		return (m_pBody != handle.m_pBody);
206*b1cdbd2cSJim Jagielski 	}
207*b1cdbd2cSJim Jagielski 
208*b1cdbd2cSJim Jagielski 
209*b1cdbd2cSJim Jagielski 	/** Needed to place References into STL collection.
210*b1cdbd2cSJim Jagielski 	 */
211*b1cdbd2cSJim Jagielski 	inline sal_Bool
operator <(const Reference<reference_type> & handle) const212*b1cdbd2cSJim Jagielski 	SAL_CALL operator< (const Reference<reference_type> & handle) const
213*b1cdbd2cSJim Jagielski 	{
214*b1cdbd2cSJim Jagielski 		return (m_pBody < handle.m_pBody);
215*b1cdbd2cSJim Jagielski 	}
216*b1cdbd2cSJim Jagielski 
217*b1cdbd2cSJim Jagielski 
218*b1cdbd2cSJim Jagielski 	/** Needed to place References into STL collection.
219*b1cdbd2cSJim Jagielski 	 */
220*b1cdbd2cSJim Jagielski 	inline sal_Bool
operator >(const Reference<reference_type> & handle) const221*b1cdbd2cSJim Jagielski 	SAL_CALL operator> (const Reference<reference_type> & handle) const
222*b1cdbd2cSJim Jagielski 	{
223*b1cdbd2cSJim Jagielski 		return (m_pBody > handle.m_pBody);
224*b1cdbd2cSJim Jagielski 	}
225*b1cdbd2cSJim Jagielski };
226*b1cdbd2cSJim Jagielski 
227*b1cdbd2cSJim Jagielski /** @internal
228*b1cdbd2cSJim Jagielski     Enables boost::mem_fn and boost::bind to recognize Reference.
229*b1cdbd2cSJim Jagielski */
230*b1cdbd2cSJim Jagielski template <typename T>
get_pointer(Reference<T> const & r)231*b1cdbd2cSJim Jagielski inline T * get_pointer( Reference<T> const& r )
232*b1cdbd2cSJim Jagielski {
233*b1cdbd2cSJim Jagielski     return r.get();
234*b1cdbd2cSJim Jagielski }
235*b1cdbd2cSJim Jagielski 
236*b1cdbd2cSJim Jagielski } // namespace rtl
237*b1cdbd2cSJim Jagielski 
238*b1cdbd2cSJim Jagielski #endif /* !_RTL_REF_HXX_ */
239