00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00018 #ifndef LIBCWD_LOCKABLE_AUTO_PTR_H
00019 #define LIBCWD_LOCKABLE_AUTO_PTR_H
00020
00021
00022
00023 #ifndef CWDEBUG
00024 #ifndef LIBCWD_ASSERT
00025 #define LIBCWD_ASSERT(x)
00026 #endif
00027 #else // CWDEBUG
00028 #ifndef LIBCWD_PRIVATE_ASSERT_H
00029 #include <libcwd/private_assert.h>
00030 #endif
00031 #endif // CWDEBUG
00032
00033 namespace libcwd {
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 template<class X, bool array = false>
00051 class lockable_auto_ptr {
00052 typedef X element_type;
00053
00054 private:
00055 template<class Y, bool ARRAY> friend class lockable_auto_ptr;
00056 X* ptr;
00057 bool locked;
00058 mutable bool owner;
00059
00060
00061 public:
00062
00063
00064
00065
00066 explicit lockable_auto_ptr(X* p = 0) : ptr(p), locked(false), owner(p) { }
00067
00068
00069 lockable_auto_ptr(lockable_auto_ptr const& r) :
00070 ptr(r.ptr), locked(false), owner(r.owner && !r.locked)
00071 { if (!r.locked) r.owner = 0; }
00072
00073
00074 template<class Y>
00075 lockable_auto_ptr(lockable_auto_ptr<Y, array> const& r) :
00076 ptr(r.ptr), locked(false), owner(r.owner && !r.locked)
00077 { if (!r.locked) r.owner = 0; }
00078
00079
00080
00081
00082
00083
00084 template<class Y>
00085 lockable_auto_ptr& operator=(lockable_auto_ptr<Y, array> const& r);
00086
00087 lockable_auto_ptr& operator=(lockable_auto_ptr const& r) { return operator= <X> (r); }
00088
00089
00090
00091
00092
00093
00094 ~lockable_auto_ptr() { if (owner) { if (array) delete [] ptr; else delete ptr; } }
00095
00096
00097
00098
00099
00100 X& operator*() const { return *ptr; }
00101
00102
00103 X* operator->() const { return ptr; }
00104
00105
00106 X* get() const { return ptr; }
00107
00108
00109 bool strict_owner() const { LIBCWD_ASSERT(is_owner()); return locked; }
00110
00111
00112
00113 #ifdef CWDEBUG
00114 bool is_owner(void) const { return owner; }
00115
00116 #endif
00117
00118
00119
00120
00121
00122 void reset()
00123 {
00124 bool owns = owner;
00125 owner = 0;
00126 if (owns)
00127 {
00128 if (array)
00129 delete [] ptr;
00130 else
00131 delete ptr;
00132 }
00133 ptr = NULL;
00134 }
00135
00136
00137 X* release() const { LIBCWD_ASSERT(is_owner()); owner = 0; return ptr; }
00138
00139
00140
00141 void lock() { LIBCWD_ASSERT(is_owner()); locked = true; }
00142
00143
00144
00145 void unlock() { locked = false; }
00146
00147 };
00148
00149 template<class X, bool array>
00150 template<class Y>
00151 lockable_auto_ptr<X, array>&
00152 lockable_auto_ptr<X, array>::operator=(lockable_auto_ptr<Y, array> const& r)
00153 {
00154 if ((void*)&r != (void*)this)
00155 {
00156 if (owner)
00157 {
00158 if (array)
00159 delete [] ptr;
00160 else
00161 delete ptr;
00162 }
00163 ptr = r.ptr;
00164 if (r.locked)
00165 owner = 0;
00166 else
00167 {
00168 owner = r.owner;
00169 r.owner = 0;
00170 }
00171 }
00172 return *this;
00173 }
00174
00175 }
00176
00177 #endif // LIBCWD_LOCKABLE_AUTO_PTR_H