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