contrib/mul/mbl/mbl_cloneable_ptr.h
Go to the documentation of this file.
00001 // This is mul/mbl/mbl_cloneable_ptr.h
00002 #ifndef mbl_cloneable_ptr_h
00003 #define mbl_cloneable_ptr_h
00004 //:
00005 // \file
00006 
00007 #include <vsl/vsl_binary_loader.h>
00008 #include <vcl_cassert.h>
00009 
00010 //=======================================================================
00011 //: Cunning pointer for objects that can be cloned.
00012 //  Used to record base class pointers to objects
00013 //  When copied, the object pointed to gets cloned.
00014 //  When written or read to/from binary streams,
00015 //  suitable polymorphic I/O is invoked.
00016 //
00017 // \code
00018 // vcl_auto_ptr<T> inst = get_from_some_factory_function();
00019 // mbl_cloneable_ptr<T> long_term_store;
00020 // long_term_store = inst.release();
00021 // \endcode
00022 template <class BaseClass>
00023 class mbl_cloneable_ptr
00024 {
00025   BaseClass* ptr_;
00026  public:
00027   //: Default constructor (zeros pointer)
00028   mbl_cloneable_ptr() : ptr_(0) {}
00029 
00030   //: Delete object pointed to and set pointer to zero
00031   void deleteObject() { delete ptr_; ptr_=0; }
00032 
00033   //: Destructor
00034   ~mbl_cloneable_ptr() { deleteObject(); }
00035 
00036   //: Copy constructor
00037   mbl_cloneable_ptr(const mbl_cloneable_ptr<BaseClass>& p) : ptr_(0) { *this = p; }
00038 
00039   //: Construct from pointer, making a clone of r.
00040   mbl_cloneable_ptr(const BaseClass& r) : ptr_(r.clone()) { assert(ptr_); }
00041 
00042   //: Constructor from pointer, taking ownership of *p.
00043   mbl_cloneable_ptr(BaseClass* p) : ptr_(p) { assert(ptr_); }
00044 
00045   //: Copy operator
00046   mbl_cloneable_ptr<BaseClass>& operator=(const mbl_cloneable_ptr<BaseClass>& p)
00047   {
00048     if (this==&p) return *this;
00049     deleteObject(); if (p.ptr_!=0) ptr_=p.ptr_->clone();
00050     return *this;
00051   }
00052 
00053   //: Copy operator - takes clone of p
00054   mbl_cloneable_ptr<BaseClass>& operator=(const BaseClass& p)
00055   {
00056     if (ptr_==&p) return *this;
00057     deleteObject();
00058     ptr_= p.clone();
00059     return *this;
00060   }
00061 
00062   //: Copy operator - takes responsibility for *p
00063   //  Sets internal pointer to p, and takes responsibility
00064   //  for deleting *p
00065   mbl_cloneable_ptr<BaseClass>& operator=(BaseClass* p)
00066   {
00067     if (ptr_==p) return *this;
00068     deleteObject();
00069     ptr_= p;
00070     return *this;
00071   }
00072 
00073   //: Return true if pointer defined
00074   bool isDefined() const { return ptr_!=0; }
00075 
00076   //: Make object behave like pointer to BaseClass
00077   const BaseClass* operator->() const { return ptr_; }
00078 
00079   //: Make object behave like pointer to BaseClass
00080   BaseClass* operator->() { return ptr_; }
00081 
00082   //: Return actual pointer
00083   const BaseClass* ptr() const { return ptr_; }
00084 
00085   //: Return actual pointer
00086   BaseClass* ptr() { return ptr_; }
00087 
00088   //: Return wrapped pointer and give up ownership
00089   BaseClass* release()
00090   { BaseClass* p = ptr_; ptr_=0; return p; }
00091 
00092   //: Cast to allow object to look like thing pointed to
00093   operator BaseClass&() { assert(ptr_!=0); return *ptr_; }
00094 
00095   //: Dereferencing the pointer
00096   BaseClass &operator * () { return *ptr_; }
00097 
00098   //: Dereferencing the pointer
00099   const BaseClass &operator * () const { return *ptr_; }
00100 
00101   //: Cast to allow object to look like thing pointed to
00102   operator const BaseClass&() const { assert(ptr_!=0); return *ptr_; }
00103 
00104   //: Save to binary stream
00105   void b_write(vsl_b_ostream& bfs) const
00106   {
00107     vsl_b_write(bfs,ptr_);
00108   }
00109 
00110   //: Load from binary stream
00111   void b_read(vsl_b_istream& bfs)
00112   {
00113     deleteObject();
00114     vsl_b_read(bfs,ptr_);
00115   }
00116 };
00117 
00118 template <class BaseClass>
00119 void vsl_b_write(vsl_b_ostream& bfs, const mbl_cloneable_ptr<BaseClass>& p)
00120 { p.b_write(bfs); }
00121 
00122 template <class BaseClass>
00123 void vsl_b_read(vsl_b_istream& bfs, mbl_cloneable_ptr<BaseClass>& p)
00124 { p.b_read(bfs); }
00125 
00126 
00127 //=======================================================================
00128 //: Cunning non-zero pointer for objects that can be cloned.
00129 //  The pointer is guaranteed to always point to something.
00130 //  Used to record base class pointers to objects
00131 //  When copied, the object pointed to gets cloned.
00132 //  When written or read to/from binary streams,
00133 //  suitable polymorphic I/O is invoked.
00134 //
00135 // To take ownership of the contents of a vcl_auto_ptr<T> use
00136 // \code
00137 // vcl_auto_ptr<T> inst = get_from_some_factory_function();
00138 // mbl_cloneable_nzptr<T> long_term_store(inst.release());
00139 // \endcode
00140 template <class BaseClass>
00141 class mbl_cloneable_nzptr
00142 {
00143   BaseClass* ptr_;
00144  public:
00145 
00146   //: Destructor
00147   ~mbl_cloneable_nzptr() { delete ptr_; }
00148 
00149   //: Copy constructor
00150   // There is no default constructor.
00151   mbl_cloneable_nzptr(const mbl_cloneable_nzptr<BaseClass>& cp):
00152     ptr_(cp.ptr_->clone()) { assert(ptr_); }
00153 
00154   //: Construct from pointer, making a clone of r.
00155   // There is no default constructor.
00156   mbl_cloneable_nzptr(const BaseClass& r) : ptr_(r.clone()) { assert(ptr_); }
00157 
00158   //: Constructor from pointer, taking ownership of *p.
00159   // There is no default constructor.
00160   mbl_cloneable_nzptr(BaseClass* p) : ptr_(p) { assert(ptr_); }
00161 
00162   //: Copy operator
00163   mbl_cloneable_nzptr<BaseClass>& operator=(const mbl_cloneable_nzptr<BaseClass>& cp)
00164   {
00165     if (this==&cp) return *this;
00166     BaseClass * tmp=cp.ptr_->clone();
00167     assert(tmp);
00168     delete ptr_;
00169     ptr_ = tmp;
00170     return *this;
00171   }
00172 
00173   //: Copy operator - takes clone of r
00174   mbl_cloneable_nzptr<BaseClass>& operator=(const BaseClass& r)
00175   {
00176     if (ptr_==&r) return *this;
00177     BaseClass * tmp=r.clone();  // Do it in this order, in case clone throws an exception.
00178     assert(tmp);
00179     delete ptr_;
00180     ptr_= tmp;
00181     return *this;
00182   }
00183 
00184   //: Copy operator - takes responsibility for *p
00185   //  Sets internal pointer to p, and takes responsibility
00186   //  for deleting *p
00187   mbl_cloneable_nzptr<BaseClass>& operator=(BaseClass* p)
00188   {
00189     assert(p);
00190     if (ptr_==p) return *this;
00191     delete ptr_;
00192     ptr_= p;
00193     return *this;
00194   }
00195 
00196   //: Return true.
00197   bool isDefined() const { return true; }
00198 
00199   //: Make object behave like pointer to BaseClass
00200   const BaseClass* operator->() const { return ptr_; }
00201 
00202   //: Make object behave like pointer to BaseClass
00203   BaseClass* operator->() { return ptr_; }
00204 
00205   //: Return actual pointer
00206   const BaseClass* ptr() const { return ptr_; }
00207 
00208   //: Return actual pointer
00209   BaseClass* ptr() { return ptr_; }
00210 
00211   //: Return and give up ownership of wrapped pointer, while taking ownership a new pointer.
00212   BaseClass* replace(BaseClass* p)
00213   { BaseClass* old = ptr_; ptr_=p; return old; }
00214 
00215   //: Cast to allow object to look like thing pointed to
00216   operator BaseClass&() { return *ptr_; }
00217 
00218   //: Cast to allow object to look like thing pointed to
00219   operator const BaseClass&() const { return *ptr_; }
00220 
00221   //: Dereferencing the pointer
00222   BaseClass &operator * () { return *ptr_; }
00223 
00224   //: Dereferencing the pointer
00225   const BaseClass &operator * () const { return *ptr_; }
00226 
00227   //: Save to binary stream
00228   void b_write(vsl_b_ostream& bfs) const
00229   {
00230     vsl_b_write(bfs,ptr_);
00231   }
00232 
00233   //: Load from binary stream
00234   void b_read(vsl_b_istream& bfs)
00235   {
00236     delete ptr_;
00237     ptr_ = 0;
00238     vsl_b_read(bfs,ptr_);
00239   }
00240 };
00241 
00242 template <class BaseClass>
00243 void vsl_b_write(vsl_b_ostream& bfs, const mbl_cloneable_nzptr<BaseClass>& p)
00244 { p.b_write(bfs); }
00245 
00246 template <class BaseClass>
00247 void vsl_b_read(vsl_b_istream& bfs, mbl_cloneable_nzptr<BaseClass>& p)
00248 { p.b_read(bfs); }
00249 
00250 #define MBL_CLONEABLE_PTR_INSTANTIATE(T) /* nothing */
00251 #if 0 // was:
00252 VCL_DEFINE_SPECIALIZATION class mbl_cloneable_ptr<T >; \
00253 VCL_DEFINE_SPECIALIZATION void vsl_b_write(vsl_b_ostream& bfs, const mbl_cloneable_ptr<T >& p);\
00254 VCL_DEFINE_SPECIALIZATION void vsl_b_read(vsl_b_istream& bfs, mbl_cloneable_ptr<T >& p);\
00255 VCL_DEFINE_SPECIALIZATION class mbl_cloneable_nzptr<T >; \
00256 VCL_DEFINE_SPECIALIZATION void vsl_b_write(vsl_b_ostream& bfs, const mbl_cloneable_nzptr<T >& p);\
00257 VCL_DEFINE_SPECIALIZATION void vsl_b_read(vsl_b_istream& bfs, mbl_cloneable_nzptr<T >& p)
00258 #endif // 0
00259 
00260 #endif  // mbl_cloneable_ptr_h