00001
00007 #ifndef __ALLOCATING_POINTER_H__
00008 #define __ALLOCATING_POINTER_H__
00009
00010 #include <functional>
00011
00012
00018 template<class T>
00019 struct CopyAsNominalType : public std::unary_function<T,T*>
00020 { T* operator() (const T& value) { return new T(value); } };
00021
00022
00023
00032 template<class T>
00033 struct CopyUsingClone : public std::unary_function<T,T*>
00034 { T* operator() (const T& value) { return value.clone(); } };
00035
00036
00037
00062 template<class T, class Cloner=CopyAsNominalType<T>, bool default_own=false >
00063 class OwningPointer {
00064 typedef OwningPointer<T,Cloner> self;
00065
00066 public:
00068 OwningPointer(const T& value)
00069 : vp(allocate(value)), allocated(vp) { }
00070
00072 OwningPointer(T* value_pointer, bool owns_object=default_own)
00073 : vp(value_pointer), allocated(owns_object? value_pointer : 0) { }
00074
00077 OwningPointer(const self& other)
00078 : vp (other.externalpointer()? other.vp : allocate(*(other.vp))),
00079 allocated(other.externalpointer()? 0 : vp ) { }
00080
00081 ~OwningPointer()
00082 { delete allocated; }
00083
00085 void operator= (const T& new_value) { *vp=new_value; }
00086
00088 self& operator= (const self& o) {
00089 if (this == &o) return *this;
00090 if (allocated) {
00091 delete allocated; allocated=0;
00092 }
00093
00094 if (o.externalpointer()) vp=o.vp;
00095 else allocated=vp=allocate(*(o.vp));
00096
00097 return *this;
00098 }
00099
00101 inline operator bool() const { return bool(vp); }
00102
00104 inline const T& operator*() const { return *vp; }
00105
00107 inline const T* operator->() const { return vp; }
00108
00110 inline T* operator->() { return vp; }
00111
00113 inline T* valueptr() const { return vp; }
00114
00118 inline T*& valueptrref() { return vp; }
00119
00120
00121
00122
00131 void relink(T* ptr) { if (externalpointer()) vp = ptr; }
00133
00134 private:
00136 T* vp;
00137
00140 T* allocated;
00141
00144 inline bool externalpointer() const { return (allocated!=vp); }
00145
00146 protected:
00148 inline T* allocate(const T& value) const
00149 { return Cloner()(value); }
00150 };
00151
00152
00153
00159 template<class T, class Cloner=CopyAsNominalType<T>, bool default_own=false >
00160 class AllocatingPointer : public OwningPointer<T,Cloner,default_own> {
00161 public:
00163 AllocatingPointer(const T& value=T())
00164 : OwningPointer<T,Cloner,default_own>(allocate(value),true) { }
00165
00167 AllocatingPointer(T* value_pointer, bool owns_object=default_own)
00168 : OwningPointer<T,Cloner,default_own>(value_pointer,owns_object) { }
00169
00171 void operator= (const T& new_value) { *valueptr()=new_value; }
00172 };
00173
00174
00175
00186 template<class T>
00187 class MemoryReference {
00188 typedef MemoryReference<T> self;
00189
00190 public:
00192 MemoryReference(T* pointer=0)
00193 : allocated(pointer) { }
00194
00196 MemoryReference(const MemoryReference&) : allocated(0) { }
00197
00198 ~MemoryReference() { delete allocated; }
00199
00201 self& operator= (const MemoryReference&) { }
00202
00203 private:
00206 T* allocated;
00207 };
00208
00209
00210 #endif