enhance shared dptr: allow decoupling
authorKonrad Rosenbaum <konrad@silmor.de>
Sat, 24 Mar 2012 19:23:12 +0000 (20:23 +0100)
committerKonrad Rosenbaum <konrad@silmor.de>
Sat, 24 Mar 2012 19:23:12 +0000 (20:23 +0100)
dptr/dptr_base.h
dptr/dptr_shared.h

index 85f2e52..0342909 100644 (file)
@@ -94,7 +94,19 @@ The d-pointer class Private is only forward declared, you have to fully declare
 Warning: shared d-pointers are not thread safe and they are only re-entrant if instances sharing the same d-pointer are only located in one thread, while instances with different d-pointers may be spread over different threads.
 
 \param dp name of the d-pointer*/
-#define DECLARE_SHARED_DPTR(dp) DECLARE_DPTR(dp)
+#define DECLARE_SHARED_DPTR(dp) \
+ private:\
+ class Private; \
+ class DPrivate{\
+  public:DPrivate();DPrivate(const DPrivate&);~DPrivate();\
+  DPrivate&operator=(const DPrivate&);\
+  const Private*operator->()const{return d;}\
+  Private*operator->(){return d;}\
+  DPrivate clone()const;\
+  void decouple();\
+  private:Private*d;\
+ }; \
+ DPrivate dp;
 
 
 #ifdef DECLARE_NONCOPY_DPTR
index 88dc7a4..e7c49bf 100644 (file)
@@ -32,6 +32,8 @@ class SharedDPtr
                virtual void attach(){cnt++;}
                ///called by the wrapper to detach from an instance
                virtual void detach(){cnt--;if(cnt==0)delete this;}
+               ///called by the wrapper to enable copy-on-write logic
+               int currentRefCount()const{return cnt;}
 };
 
 //hide the namespace
@@ -58,5 +60,7 @@ To be used in implementation where the actual d-pointer class is implemented.
  Class::DPrivate::~DPrivate(){d->detach();}\
  Class::DPrivate Class::DPrivate::clone()const{DPrivate r;*(r.d)=*d;return r;}\
  Class::DPrivate& Class::DPrivate::operator=(const DPrivate&dp)\
- {if(d!=dp.d){d->detach();d=dp.d;d->attach();}return *this;}
+ {if(d!=dp.d){d->detach();d=dp.d;d->attach();}return *this;}\
+ void Class::DPrivate::decouple()\
+ {if(d->currentRefCount()>1){Private *p=new Class::Private(*d);d->detach();d=p;}}