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