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