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_