00001 /** @file scim_pointer.h 00002 * @brief Smart pointer class interface. 00003 * 00004 * Provides a reference-counted-object aware smart pointer class. 00005 * 00006 * Most code of this file are came from Inti project. 00007 */ 00008 00009 /* 00010 * Smart Common Input Method 00011 * 00012 * Copyright (c) 2004 James Su <suzhe@turbolinux.com.cn> 00013 * Copyright (c) 2003 James Su <suzhe@turbolinux.com.cn> 00014 * Copyright (c) 2002 James Su <suzhe@turbolinux.com.cn> 00015 * Copyright (c) 2002 The Inti Development Team. 00016 * 00017 * 00018 * This library is free software; you can redistribute it and/or 00019 * modify it under the terms of the GNU Lesser General Public 00020 * License as published by the Free Software Foundation; either 00021 * version 2 of the License, or (at your option) any later version. 00022 * 00023 * This library is distributed in the hope that it will be useful, 00024 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00025 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00026 * GNU Lesser General Public License for more details. 00027 * 00028 * You should have received a copy of the GNU Lesser General Public 00029 * License along with this program; if not, write to the 00030 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 00031 * Boston, MA 02111-1307 USA 00032 * 00033 * $Id: scim_pointer.h,v 1.8 2004/02/06 07:53:15 suzhe Exp $ 00034 */ 00035 00036 #ifndef __SCIM_POINTER_H 00037 #define __SCIM_POINTER_H 00038 00039 namespace scim { 00040 00041 /** 00042 * @addtogroup Helper 00043 * @{ 00044 */ 00045 00046 /** 00047 * @class Pointer 00048 * @brief Smart pointer template class. 00049 * 00050 * Pointer is a standard auto_ptr-like smart pointer for managing heap 00051 * allocated reference counted objects. T must be a class derived from 00052 * scim::ReferencedObject. 00053 */ 00054 00055 template <typename T> 00056 class Pointer 00057 { 00058 T *t; 00059 00060 void set(T *object) 00061 { 00062 if (object) 00063 { 00064 if (!object->is_referenced()) 00065 object->ref(); 00066 object->set_referenced(false); 00067 } 00068 if (t) 00069 t->unref(); 00070 t = object; 00071 } 00072 00073 template<typename T1, typename T2> 00074 friend bool operator == (const Pointer<T1>& t1, const Pointer<T2>& t2); 00075 00076 public: 00077 //! @name Constructors 00078 //! @{ 00079 00080 Pointer(T *object = 0) : t(0) 00081 { 00082 set(object); 00083 } 00084 //!< Construct a new smart pointer. 00085 //!< @param object - a pointer to an object allocated on the heap. 00086 //!< 00087 //!< <BR>Initialize a new Pointer with any dumb pointer. 00088 00089 Pointer(Pointer& src) : t(0) 00090 { 00091 set(src.get()); 00092 } 00093 //!< Copy constructor. 00094 //!< @param src - a reference to a smart pointer. 00095 //!< 00096 //!< <BR>Initialize a new Pointer with any compatible Pointer. 00097 00098 template <typename T1> 00099 Pointer(const Pointer<T1>& src) : t(0) 00100 { 00101 set(src.get()); 00102 } 00103 //!< Copy constructor. 00104 //!< @param src - a Pointer to type T1 where T1 is derived from T. 00105 //!< 00106 //!< <BR>Initialize a new Pointer of type T from a Pointer of type T1, 00107 //!< only if T1 is derived from T. 00108 00109 ~Pointer() 00110 { 00111 set(0); 00112 } 00113 //!< Destructor. 00114 //!< Decreases the object reference count. 00115 00116 Pointer& operator=(T *object) 00117 { 00118 set(object); 00119 return *this; 00120 } 00121 //!< Assignment operator. 00122 //!< @param object - a pointer to an object allocated on the heap. 00123 //!< 00124 //!< <BR>Releases the current dumb pointer, if any and assigns <EM>object</EM> 00125 //!< to this Pointer, incrementing its reference count. 00126 00127 Pointer& operator=(const Pointer& src) 00128 { 00129 set(src.get()); 00130 return *this; 00131 } 00132 //!< Assignment operator. 00133 //!< @param src - a reference to a smart pointer. 00134 //!< 00135 //!< <BR>Releases the current dumb pointer, if any and assigns the dumb pointer 00136 //!< managed by <EM>src</EM> to this Pointer, incrementing its reference count. 00137 00138 template <typename T1> 00139 Pointer& operator=(const Pointer<T1>& src) 00140 { 00141 set(src.get()); 00142 return *this; 00143 } 00144 //!< Assignment operator. 00145 //!< @param src - a Pointer to type T1 where T1 is derived from T. 00146 //!< 00147 //!< <BR>Releases the current dumb pointer, if any and assigns the dumb pointer 00148 //!< of type T1 managed by <EM>src</EM> to this Pointer as a dumb pointer of type T, 00149 //!< only if T1 is derived from T. The reference count is incremented. 00150 00151 //! @} 00152 //! @name Accessors 00153 //! @{ 00154 00155 T& operator*() const 00156 { 00157 return *get(); 00158 } 00159 //!< Dereference operator. 00160 //!< @return a reference to the object pointed to by the dumb pointer. 00161 00162 T* operator->() const 00163 { 00164 return get(); 00165 } 00166 //!< Member selection operator. 00167 //!< @return the dumb pointer. 00168 00169 operator T*() const 00170 { 00171 return get(); 00172 } 00173 //!< Conversion operator. 00174 //!< Converts a Pointer into its dumb pointer: the C pointer it manages. 00175 //!< Normally it is considered pretty evil to mix smart and regular pointers. 00176 //!< In scim you can safely if you just follow the reference counting rules 00177 //!< for each of them. You can never call delete on Pointer either because 00178 //!< you don't call delete on scim objects; you call unref(). 00179 00180 T* get() const 00181 { 00182 return t; 00183 } 00184 //!< Returns the dumb pointer; the regular C pointer managed by the Pointer. 00185 //!< @return the dumb pointer. 00186 00187 bool null() const 00188 { 00189 return t == 0; 00190 } 00191 //!< Returns true if the Pointer has no dumb pointer. 00192 00193 //! @} 00194 //! @name Methods 00195 //! @{ 00196 00197 T* release() 00198 { 00199 T *tmp = t; 00200 if (tmp) 00201 tmp->ref(); 00202 set(0); 00203 return tmp; 00204 } 00205 //!< Releases the dumb pointer. 00206 //!< @return the regular C pointer previously managed by the Pointer. 00207 //!< 00208 //!< <BR>Before releasing the dumb pointer its reference count is incremented 00209 //!< to prevent it being destroyed. You must call unref() on the pointer to 00210 //!< prevent a memory leak. 00211 00212 void reset(T *object = 0) 00213 { 00214 set(object); 00215 } 00216 //!< Sets a new dumb pointer for the Pointer to manage. 00217 //!< @param object - the new dumb pointer. 00218 //!< 00219 //!< <BR>Releases the current dumb pointer, if any, and assigns <EM>object</EM> 00220 //!< to the Pointer, incrementing its reference count. 00221 00222 //! @} 00223 }; 00224 00225 //! @name Equality operators 00226 //! @{ 00227 00228 template<typename T1, typename T2> 00229 inline bool operator == (const Pointer<T1>& t1, const Pointer<T2>& t2) 00230 { 00231 return t1.t == t2.t; 00232 } 00233 //!< Compares two Pointers. 00234 //!< @return <EM>true</EM> if both Pointers manage to same dumb pointer. 00235 00236 template<typename T1, typename T2> 00237 inline bool operator != (const Pointer<T1>& t1, const Pointer<T2>& t2) 00238 { 00239 return !(t1 == t2); 00240 } 00241 //!< Compares two Pointers. 00242 //!< @return <EM>true</EM> if both Pointers manage a different dumb pointer. 00243 00244 //! @} 00245 //! @name C++-style casting functions 00246 //! @{ 00247 00248 template <typename To, typename From> 00249 inline Pointer<To> 00250 cast_const(const Pointer<From>& from) 00251 { 00252 return Pointer<To>(from ? const_cast<To*>(from.get()) : 0); 00253 } 00254 //!< Removes the <EM>const</EM> qualifier from a managed const dumb pointer. 00255 //!< @param from - a Pointer that manages a const dumb pointer. 00256 //!< @return a new Pointer that manages the non-const dumb pointer. 00257 //!< 00258 //!< <BR>Calls <EM>const_cast</EM> on the dumb pointer and returns the non-const 00259 //!< pointer as a new Pointer. 00260 00261 template <typename To, typename From> 00262 inline Pointer<To> 00263 cast_dynamic(const Pointer<From>& from) 00264 { 00265 return Pointer<To>(dynamic_cast<To*>(from.get())); 00266 } 00267 //!< Casts a managed polymophic dumb pointer down or across its inheritance heirarchy. 00268 //!< @param from - a Pointer managing a polymophic dumb pointer of type From. 00269 //!< @return a new Pointer managing the dumb pointer as a base or sibling pointer of type <EM>To</EM>. 00270 //!< 00271 //!< <BR>Calls <EM>dynmaic_cast</EM> to safely cast a managed polymophic dumb pointer 00272 //!< of type <EM>From</EM> to a base, derived or sibling class pointer of type <EM>To</EM>. 00273 00274 template <typename To, typename From> 00275 inline Pointer<To> 00276 cast_static(const Pointer<From>& from) 00277 { 00278 return Pointer<To>(from ? static_cast<To*>(from.get()) : 0); 00279 } 00280 //!< Casts a managed dumb pointer to a pointer to a related type. 00281 //!< @param from - a Pointer managing a dumb pointer of type From. 00282 //!< @return a new Pointer managing the dumb pointer as a pointer of type <EM>To</EM>. 00283 //!< 00284 //!< <BR>Calls <EM>static_cast</EM> to cast a dumb pointer of type <EM>From</EM> to a 00285 //!< pointer of type <EM>To</EM>. 00286 00287 //! @} 00288 00289 /** @} */ 00290 00291 } // namespace scim 00292 00293 #endif //__SCIM_POINTER_H 00294 00295 /* 00296 vi:ts=4:nowrap:ai:expandtab 00297 */