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