core/vbl/vbl_scoped_ptr.h
Go to the documentation of this file.
00001 #ifndef vbl_scoped_ptr_h_
00002 #define vbl_scoped_ptr_h_
00003 //:
00004 // \file
00005 // \author Amitha Perera
00006 // \brief Scoped pointer lifted from BOOST.
00007 //
00008 //  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
00009 //  Copyright (c) 2001, 2002 Peter Dimov
00010 //
00011 //  Permission to copy, use, modify, sell and distribute this software
00012 //  is granted provided this copyright notice appears in all copies.
00013 //  This software is provided "as is" without express or implied
00014 //  warranty, and with no claim as to its suitability for any purpose.
00015 //
00016 //  http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
00017 //
00018 //  Modified from the original boost sources to fit the VXL restrictions.
00019 
00020 #include <vcl_compiler.h>
00021 #include <vbl/vbl_checked_delete.h>
00022 
00023 //:
00024 //  vbl_scoped_ptr mimics a built-in pointer except that it guarantees
00025 //  deletion of the object pointed to, either on destruction of the
00026 //  vbl_scoped_ptr or via an explicit reset(). vbl_scoped_ptr is a
00027 //  simple solution for simple needs; use vbl_shared_ptr or
00028 //  std::auto_ptr if your needs are more complex.
00029 //
00030 //  To use this to manage pointer member variables using forward
00031 //  declaration, explicitly define a destructor in your .cxx so that
00032 //  the vbl_scoped_ptr destructor is called there rather than being
00033 //  inlined. For example, Y.h:
00034 //  \code
00035 //    struct X;
00036 //    struct Y {
00037 //      vbl_scoped_ptr<X> member;
00038 //
00039 //      ~Y() { } // NO: causes ~vbl_scoped_ptr<X> to be instantiated, which means X must be complete.
00040 //      ~Y();    // YES: destructor not yet generated
00041 //    };
00042 //  \endcode
00043 //  Y.cxx:
00044 //  \code
00045 //    #include "X.h"
00046 //    Y::~Y()
00047 //    { } // causes ~vbl_scoped_ptr<X> to be instantiated and inlined, but X is complete here, so all is well.
00048 //  \endcode
00049 
00050 template <class T>
00051 class vbl_scoped_ptr
00052 {
00053  private:
00054   T* ptr_;
00055 
00056   // not copyable, not assignable.
00057   vbl_scoped_ptr( vbl_scoped_ptr const& );
00058   vbl_scoped_ptr& operator=( vbl_scoped_ptr const& );
00059 
00060   typedef vbl_scoped_ptr<T> this_type;
00061 
00062   VCL_SAFE_BOOL_DEFINE;
00063 
00064  public:
00065   typedef T element_type;
00066 
00067   //:
00068   explicit vbl_scoped_ptr( T* p = 0 )
00069     : ptr_(p) // never throws
00070   {
00071   }
00072 
00073   //:
00074   // T must be complete when this destructor is instantiated.
00075   ~vbl_scoped_ptr() // never throws
00076   {
00077     vbl_checked_delete(ptr_);
00078   }
00079 
00080   //: Make this own \p p, releasing any existing pointer.
00081   void reset( T* p = 0 ) // never throws
00082   {
00083     this_type(p).swap(*this);
00084   }
00085 
00086   //:
00087   T& operator*() const // never throws
00088   {
00089     return *ptr_;
00090   }
00091 
00092   //:
00093   T* operator->() const // never throws
00094   {
00095     return ptr_;
00096   }
00097 
00098   //:
00099   T* get_pointer() const // never throws
00100   {
00101     return ptr_;
00102   }
00103 
00104     // implicit conversion to "bool"
00105 
00106   //: Safe implicit conversion to bool.
00107   //
00108   // This allows for if (sp) type of usage.
00109   operator safe_bool () const
00110   {
00111     return ptr_ ? VCL_SAFE_BOOL_TRUE : 0;
00112   }
00113 
00114   //:
00115   bool operator! () const // never throws
00116   {
00117     return ptr_ == 0;
00118   }
00119 
00120   //:
00121   void swap( vbl_scoped_ptr& b ) // never throws
00122   {
00123     T* tmp = b.ptr_;
00124     b.ptr_ = ptr_;
00125     ptr_ = tmp;
00126   }
00127 };
00128 
00129 #endif // vbl_scoped_ptr_h_