1/** @file scim_pointer.h
2 * @brief Smart pointer class interface.
3 *
4 * Provides a reference-counted-object aware smart pointer class.
5 *
6 * Most code of this file are came from Inti project.
7 */
8
9/*
10 * Smart Common Input Method
11 *
12 * Copyright (c) 2002-2005 James Su <suzhe@tsinghua.org.cn>
13 * Copyright (c) 2002 The Inti Development Team.
14 *
15 *
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2 of the License, or (at your option) any later version.
20 *
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU Lesser General Public License for more details.
25 *
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this program; if not, write to the
28 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
29 * Boston, MA 02111-1307 USA
30 *
31 * $Id: scim_pointer.h,v 1.11 2005/01/10 08:30:54 suzhe Exp $
32 */
33
34#ifndef __SCIM_POINTER_H
35#define __SCIM_POINTER_H
36
37namespace scim {
38
39/**
40 * @addtogroup Accessories
41 * @{
42 */
43
44/**
45 * @class Pointer
46 * @brief Smart pointer template class.
47 *
48 * Pointer is a standard auto_ptr-like smart pointer for managing heap
49 * allocated reference counted objects. T must be a class derived from
50 * scim::ReferencedObject.
51 */
52
53template <typename T>
54class Pointer
55{
56 T *t;
57
58 void set(T *object)
59 {
60 if (object)
61 {
62 if (!object->is_referenced())
63 object->ref();
64 object->set_referenced(false);
65 }
66 if (t)
67 t->unref();
68 t = object;
69 }
70
71 template<typename T1, typename T2>
72 friend bool operator == (const Pointer<T1>& t1, const Pointer<T2>& t2);
73
74public:
75//! @name Constructors
76//! @{
77
78 Pointer(T *object = 0) : t(0)
79 {
80 set(object);
81 }
82 //!< Construct a new smart pointer.
83 //!< @param object - a pointer to an object allocated on the heap.
84 //!<
85 //!< <BR>Initialize a new Pointer with any dumb pointer.
86
87 Pointer(Pointer& src) : t(0)
88 {
89 set(src.get());
90 }
91 //!< Copy constructor.
92 //!< @param src - a reference to a smart pointer.
93 //!<
94 //!< <BR>Initialize a new Pointer with any compatible Pointer.
95
96 template <typename T1>
97 Pointer(const Pointer<T1>& src) : t(0)
98 {
99 set(src.get());
100 }
101 //!< Copy constructor.
102 //!< @param src - a Pointer to type T1 where T1 is derived from T.
103 //!<
104 //!< <BR>Initialize a new Pointer of type T from a Pointer of type T1,
105 //!< only if T1 is derived from T.
106
107 ~Pointer()
108 {
109 set(0);
110 }
111 //!< Destructor.
112 //!< Decreases the object reference count.
113
114 Pointer& operator=(T *object)
115 {
116 set(object);
117 return *this;
118 }
119 //!< Assignment operator.
120 //!< @param object - a pointer to an object allocated on the heap.
121 //!<
122 //!< <BR>Releases the current dumb pointer, if any and assigns <EM>object</EM>
123 //!< to this Pointer, incrementing its reference count.
124
125 Pointer& operator=(const Pointer& src)
126 {
127 set(src.get());
128 return *this;
129 }
130 //!< Assignment operator.
131 //!< @param src - a reference to a smart pointer.
132 //!<
133 //!< <BR>Releases the current dumb pointer, if any and assigns the dumb pointer
134 //!< managed by <EM>src</EM> to this Pointer, incrementing its reference count.
135
136 template <typename T1>
137 Pointer& operator=(const Pointer<T1>& src)
138 {
139 set(src.get());
140 return *this;
141 }
142 //!< Assignment operator.
143 //!< @param src - a Pointer to type T1 where T1 is derived from T.
144 //!<
145 //!< <BR>Releases the current dumb pointer, if any and assigns the dumb pointer
146 //!< of type T1 managed by <EM>src</EM> to this Pointer as a dumb pointer of type T,
147 //!< only if T1 is derived from T. The reference count is incremented.
148
149//! @}
150//! @name Accessors
151//! @{
152
153 T& operator*() const
154 {
155 return *get();
156 }
157 //!< Dereference operator.
158 //!< @return a reference to the object pointed to by the dumb pointer.
159
160 T* operator->() const
161 {
162 return get();
163 }
164 //!< Member selection operator.
165 //!< @return the dumb pointer.
166
167 operator T*() const
168 {
169 return get();
170 }
171 //!< Conversion operator.
172 //!< Converts a Pointer into its dumb pointer: the C pointer it manages.
173 //!< Normally it is considered pretty evil to mix smart and regular pointers.
174 //!< In scim you can safely if you just follow the reference counting rules
175 //!< for each of them. You can never call delete on Pointer either because
176 //!< you don't call delete on scim objects; you call unref().
177
178 T* get() const
179 {
180 return t;
181 }
182 //!< Returns the dumb pointer; the regular C pointer managed by the Pointer.
183 //!< @return the dumb pointer.
184
185 bool null() const
186 {
187 return t == 0;
188 }
189 //!< Returns true if the Pointer has no dumb pointer.
190
191//! @}
192//! @name Methods
193//! @{
194
195 T* release()
196 {
197 T *tmp = t;
198 if (tmp)
199 tmp->ref();
200 set(0);
201 return tmp;
202 }
203 //!< Releases the dumb pointer.
204 //!< @return the regular C pointer previously managed by the Pointer.
205 //!<
206 //!< <BR>Before releasing the dumb pointer its reference count is incremented
207 //!< to prevent it being destroyed. You must call unref() on the pointer to
208 //!< prevent a memory leak.
209
210 void reset(T *object = 0)
211 {
212 set(object);
213 }
214 //!< Sets a new dumb pointer for the Pointer to manage.
215 //!< @param object - the new dumb pointer.
216 //!<
217 //!< <BR>Releases the current dumb pointer, if any, and assigns <EM>object</EM>
218 //!< to the Pointer, incrementing its reference count.
219
220//! @}
221};
222
223//! @name Equality operators
224//! @{
225
226template<typename T1, typename T2>
227inline bool operator == (const Pointer<T1>& t1, const Pointer<T2>& t2)
228{
229 return t1.t == t2.t;
230}
231//!< Compares two Pointers.
232//!< @return <EM>true</EM> if both Pointers manage to same dumb pointer.
233
234template<typename T1, typename T2>
235inline bool operator != (const Pointer<T1>& t1, const Pointer<T2>& t2)
236{
237 return !(t1 == t2);
238}
239//!< Compares two Pointers.
240//!< @return <EM>true</EM> if both Pointers manage a different dumb pointer.
241
242//! @}
243//! @name C++-style casting functions
244//! @{
245
246template <typename To, typename From>
247inline Pointer<To>
248cast_const(const Pointer<From>& from)
249{
250 return Pointer<To>(from ? const_cast<To*>(from.get()) : 0);
251}
252//!< Removes the <EM>const</EM> qualifier from a managed const dumb pointer.
253//!< @param from - a Pointer that manages a const dumb pointer.
254//!< @return a new Pointer that manages the non-const dumb pointer.
255//!<
256//!< <BR>Calls <EM>const_cast</EM> on the dumb pointer and returns the non-const
257//!< pointer as a new Pointer.
258
259template <typename To, typename From>
260inline Pointer<To>
261cast_dynamic(const Pointer<From>& from)
262{
263 return Pointer<To>(dynamic_cast<To*>(from.get()));
264}
265//!< Casts a managed polymophic dumb pointer down or across its inheritance heirarchy.
266//!< @param from - a Pointer managing a polymophic dumb pointer of type From.
267//!< @return a new Pointer managing the dumb pointer as a base or sibling pointer of type <EM>To</EM>.
268//!<
269//!< <BR>Calls <EM>dynmaic_cast</EM> to safely cast a managed polymophic dumb pointer
270//!< of type <EM>From</EM> to a base, derived or sibling class pointer of type <EM>To</EM>.
271
272template <typename To, typename From>
273inline Pointer<To>
274cast_static(const Pointer<From>& from)
275{
276 return Pointer<To>(from ? static_cast<To*>(from.get()) : 0);
277}
278//!< Casts a managed dumb pointer to a pointer to a related type.
279//!< @param from - a Pointer managing a dumb pointer of type From.
280//!< @return a new Pointer managing the dumb pointer as a pointer of type <EM>To</EM>.
281//!<
282//!< <BR>Calls <EM>static_cast</EM> to cast a dumb pointer of type <EM>From</EM> to a
283//!< pointer of type <EM>To</EM>.
284
285//! @}
286
287/** @} */
288
289} // namespace scim
290
291#endif //__SCIM_POINTER_H
292
293/*
294vi:ts=4:nowrap:ai:expandtab
295*/
296