Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

scim_pointer.h

Go to the documentation of this file.
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 */

Generated on Tue Apr 19 00:10:59 2005 for scim by  doxygen 1.4.1