Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members  

alloc_smart_pointer.hh

00001 /*
00002 *  Name:      alloc_smart_pointer.hh
00003 *  Author:    Rafael Jesus Alcantara Perez
00004 *  Summary:   Smart pointer with allocator support
00005 *  Date:      $Date: 2003/04/14 00:18:31 $
00006 *  Revision:  $Revision: 1.1 $
00007 *
00008 *  Copyright (C) 2000-2002  Rafael Jesus Alcantara Perez <rafa@dedalo-ing.com>
00009 *
00010 *  This program is free software; you can redistribute it and/or modify
00011 *  it under the terms of the GNU General Public License as published by
00012 *  the Free Software Foundation; either version 2 of the License, or
00013 *  (at your option) any later version.
00014 *
00015 *  This program is distributed in the hope that it will be useful,
00016 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 *  GNU General Public License for more details.
00019 *
00020 *  You should have received a copy of the GNU General Public License
00021 *  along with this program; if not, write to the Free Software
00022 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00023 *  MA 02111-1307, USA.
00024 */
00025 
00026 #ifndef _MPCL_MEMORY_ALLOC_SMART_POINTER__
00027 #define _MPCL_MEMORY_ALLOC_SMART_POINTER__
00028 
00029 #include <memory>
00030 #include "base_smart_pointer.hh"
00031 
00032 
00034 namespace mpcl
00035 {
00036 
00038   namespace memory
00039   {
00040 
00045     template < typename TItem                                               ,
00046                template <typename TItemA> class TAllocator = std::allocator >
00047     class TAllocSmartPointer                                     :
00048       public            TBaseSmartPointer                        ,
00049       protected virtual TAllocator<TBaseSmartPointer::cell_type> ,
00050       protected virtual TAllocator<TItem>
00051     {
00052 
00053       public:
00054 
00059         typedef
00060           const TItem*
00061           const_pointer;
00062 
00067         typedef
00068           const TItem&
00069           const_reference;
00070 
00072         typedef
00073           TAllocator<TItem>
00074           item_allocator;
00075 
00080         typedef
00081           TItem*
00082           pointer;
00083 
00088         typedef
00089           TItem&
00090           reference;
00091 
00096         typedef
00097           size_t
00098           size_type;
00099 
00104         typedef
00105           TItem
00106           value_type;
00107 
00108 
00109       protected:
00110 
00111         //
00112         //  C O N S T R U C T O R S
00113         //
00114 
00120         void freeCell (void)
00121         {
00122           TAllocator<TItem>::destroy        ((pointer) ptSharedCell->pvItem);
00123           TAllocator<TItem>::deallocate     ((pointer) ptSharedCell->pvItem, 1);
00124           TAllocator<cell_type>::destroy    (ptSharedCell);
00125           TAllocator<cell_type>::deallocate (ptSharedCell, 1);
00126         }
00127 
00132         void reserveCell (const_pointer pktITEM)
00133         {
00134           if ( pktITEM )
00135           {
00136             ptSharedCell = TAllocator<cell_type>::allocate (1);
00137             TAllocator<cell_type>::construct (ptSharedCell, (const void*) pktITEM);
00138           }
00139         }
00140 
00141 
00142       public:
00143 
00144         //
00145         //  C O N S T R U C T O R S
00146         //
00147 
00149         TAllocSmartPointer (void)  :
00150           TBaseSmartPointer     () ,
00151           TAllocator<cell_type> () ,
00152           TAllocator<TItem>     () {}
00153 
00158         TAllocSmartPointer (const TAllocSmartPointer& rkqtITEM) :
00159           TBaseSmartPointer     ()                              ,
00160           TAllocator<cell_type> ()                              ,
00161           TAllocator<TItem>     ()
00162         {
00163           attachTo (rkqtITEM);
00164         }
00165 
00166   // <FIXME id="smart-pointers" comment="this method can assign other type of objects">
00171         template <typename TDerivedItem>
00172         explicit TAllocSmartPointer ( const TAllocSmartPointer<TDerivedItem, TAllocator>& rkqtITEM_DERIVED) :
00173           TBaseSmartPointer     ()                                                                          ,
00174           TAllocator<cell_type> ()                                                                          ,
00175           TAllocator<TItem>     ()
00176         {
00177 
00178           //
00179           //  Declares two variables for checking assign ability.
00180           //
00181           register pointer         ptItem;
00182           register TDerivedItem*   ptDerivedItem (NULL);
00183 
00184           //
00185           //  Checks for possible syntax errors about using classes with no relation with
00186           //  this  instance to assign  to this  instance.  At  last,  it attaches to the
00187           //  derived pointer.
00188           //
00189           ptItem = ptDerivedItem;
00190           attachTo (rkqtITEM_DERIVED);
00191 
00192         }  // TAllocSmartPointer()
00193   // </FIXME>
00194 
00200         explicit TAllocSmartPointer (const_pointer pktITEM) :
00201           TBaseSmartPointer     ()                          ,
00202           TAllocator<cell_type> ()                          ,
00203           TAllocator<TItem>     ()
00204         {
00205           reserveCell (pktITEM);
00206         }
00207 
00209         ~TAllocSmartPointer (void)
00210         {
00211           release();
00212         }
00213 
00219         TAllocSmartPointer& operator = (const_pointer pktITEM)
00220         {
00221           release();
00222           reserveCell (pktITEM);
00223           return *this;
00224         }
00225 
00226         TAllocSmartPointer& operator = (const TAllocSmartPointer& rkqtITEM)
00227         {
00228           if ( rkqtITEM.ptSharedCell != ptSharedCell )
00229           {
00230             release();
00231             attachTo (rkqtITEM);
00232           }
00233           return *this;
00234         }
00235 
00240         void release (void)
00241         {
00242 
00243           if ( ptSharedCell )
00244           {
00245             //
00246             //  ptSharedCell->pvItem must be different from NULL.
00247             //  Decrements the reference counter.
00248             //
00249             --(ptSharedCell->luiReferenceCount);
00250             if ( !ptSharedCell->luiReferenceCount )
00251             {
00252               //
00253               //  Warning:  There is no check when  deleting  ptSharedCell->pvItem (for
00254               //            NULL value) cause  there is no way to assign a NULL pointer
00255               //            value.
00256               //
00257               freeCell();
00258             }
00259 
00260             //
00261             //  Anyway, clears the pointer to the shared cell.
00262             //
00263             ptSharedCell = NULL;
00264           }
00265 
00266         }  // release()
00267 
00268 
00269       public:
00270 
00271         //
00272         //  S E L E C T O R S
00273         //
00274 
00279         template <typename TPointer>
00280         TPointer constCast (void) const throw()
00281         {
00282           TPointer   tPointer = NULL;
00283 
00284           if ( ptSharedCell )
00285           {
00286             tPointer = const_cast<TPointer> ((pointer) ptSharedCell->pvItem);
00287           }
00288           return tPointer;
00289         }
00290 
00291         template <typename TPointer>
00292         TPointer dynamicCast (void) const
00293           throw (TConstraintException)
00294         {
00295           TPointer   tPointer = NULL;
00296 
00297           if ( !ptSharedCell )
00298           {
00299   // <FIXME id="smart-pointers" comment="this exception must not be thrown">
00300             throw TConstraintException ("null pointer", __FILE__, __LINE__);
00301   // </FIXME>
00302           }
00303           else
00304           {
00305             tPointer = dynamic_cast<TPointer> ((pointer) ptSharedCell->pvItem);
00306             if ( !tPointer )
00307             {
00308               throw TConstraintException ("can not dynamic-cast pointer", __FILE__, __LINE__);
00309             }
00310           }
00311           return tPointer;
00312         }
00313 
00318         pointer get (void) const throw()
00319         {
00320           register pointer   ptResultItem = NULL;
00321 
00322           if ( ptSharedCell )
00323           {
00324             ptResultItem = (pointer) ptSharedCell->pvItem;
00325           }
00326           return ptResultItem;
00327         }
00328 
00334         bool operator == (const TAllocSmartPointer& rkqtITEM) const throw()
00335         {
00336           return equal (rkqtITEM);
00337         }
00338 
00344         bool operator != (const TAllocSmartPointer& rkqtITEM) const throw()
00345         {
00346           return !operator == (rkqtITEM);
00347         }
00348 
00353         bool operator ! (void) const throw()
00354         {
00355           return ( !ptSharedCell );
00356         }
00357 
00362         pointer operator -> (void) const
00363           throw (TConstraintException)
00364         {
00365           if ( !ptSharedCell )
00366           {
00367             throw TConstraintException ("null pointer", __FILE__, __LINE__);
00368           }
00369           return (pointer) ptSharedCell->pvItem;
00370         }
00371 
00376         reference operator * (void) const
00377           throw (TConstraintException)
00378         {
00379           if ( !ptSharedCell )
00380           {
00381             throw TConstraintException ("null pointer", __FILE__, __LINE__);
00382           }
00383           return *((pointer) ptSharedCell->pvItem);
00384         }
00385 
00386     };  // class TAllocSmartPointer
00387 
00388   }  // namespace memory
00389 
00390 }  // namespace mpcl
00391 
00392 
00393 #endif  // not _MPCL_MEMORY_ALLOC_SMART_POINTER__

Generated on Mon Oct 13 02:35:22 2003 for MPCL by doxygen1.2.18