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