Changeset 10974 in vbox for trunk/include/iprt/autores
- Timestamp:
- Jul 30, 2008 11:49:30 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/autores
r10927 r10974 22 22 # define ___iprt_autores___ 23 23 24 #include <iprt/types.h> 24 25 #include <iprt/mem.h> 26 #include <iprt/assert.h> 27 #include <iprt/cpputils.h> 25 28 26 29 /** 27 * Wrapper class around RTAutoRes to provide reference semantics. This is 28 * needed to construct AutoRes objects from constant references to other 29 * AutoRes objects (such as temporary objects returned from functions) which 30 * can not be modified due to their const modifier, but are not actually 31 * constant objects. See a discussion of auto_ptr and auto_ptr_ref for more 32 * details. 30 * A callable class template which returns the correct value against which an 31 * IPRT type must be compared to see if it is invalid. 32 * @note this template must be specialised for the types it is to work with. 33 33 */ 34 template <class T, void Destruct(T)> 35 struct RTAutoResRef 36 { 37 T mValue; 34 template <class T> 35 inline T RTResNul(void) 36 { AssertLogRelMsgFailedReturn (("Unspecialized template!\n"), (T) 0); } 38 37 39 explicit RTAutoResRef(T aValue) { mValue = aValue; } 40 }; 38 /** 39 * A function template which calls the correct destructor for an IPRT type. 40 * @note this template must be specialised for the types it is to work with. 41 */ 42 template <class T> inline void RTResDestruct(T aHandle) 43 { AssertLogRelMsgFailedReturn (("Unspecialized template!\n"), (T) 0); } 41 44 42 45 /** 43 46 * An auto pointer-type class for resources which take a C-style destructor 44 * destructor (free() or equivalent). 47 * (RTMemFree() or equivalent). 48 * 49 * The idea of this class is to manage resources which the current code is 50 * responsible for freeing. By wrapping the resource in an RTAutoRes, you 51 * ensure that the resource will be freed when you leave the scope in which 52 * the RTAutoRes is defined, unless you explicitly release the resource again. 53 * 54 * A typical use case is when a function is allocating a number of resources. 55 * If any single allocation fails then all other resources must be freed. If 56 * all allocations succeed, then the resources should be returned to the 57 * caller. By placing all allocated resources in RTAutoRes containers, you 58 * ensure that they will be freed on failure, and only have to take care of 59 * releasing them when you return them. 60 * @param T the type of the resource 61 * @param Destruct the function to be used to free the resource 62 * @note The class can not be initialised directly using assignment, due to 63 * the lack of a copy constructor. 45 64 */ 46 template <class T, void Destruct(T) >47 class RTAutoRes 65 template <class T, void Destruct(T) = RTResDestruct<T>, T NulRes(void) = RTResNul<T> > 66 class RTAutoRes : public stdx::non_copyable 48 67 { 49 68 private: … … 52 71 public: 53 72 /** Constructor */ 54 RTAutoRes(T aValue = 0) { mValue = aValue; }73 RTAutoRes(T aValue = NulRes()) { mValue = aValue; } 55 74 56 75 /** Destructor */ 57 ~RTAutoRes() { if (mValue != 0) Destruct(mValue); } 58 59 /** Copy constructor */ 60 RTAutoRes(RTAutoRes &orig) { mValue = orig.release(); } 61 62 /** Copy from equivalent class */ 63 template <class T1> 64 RTAutoRes(RTAutoRes<T1, Destruct> &orig) 65 { mValue = orig.release(); } 66 67 /** Convert a reference structure into an AutoRes pointer. */ 68 RTAutoRes(RTAutoResRef<T, Destruct> ref) { mValue = ref.mValue; } 69 70 /** Assignment operator. */ 71 RTAutoRes& operator=(RTAutoRes &orig) 72 { 73 reset(orig.release()); 74 return *this; 75 } 76 77 /** Assignment from equivalent class. */ 78 template <class T1> 79 RTAutoRes& operator=(RTAutoRes<T1, Destruct> &orig) 80 { 81 reset(orig.release); 82 return *this; 83 } 76 ~RTAutoRes() { if (mValue != NulRes()) Destruct(mValue); } 84 77 85 78 /** Assignment from a value. */ 86 79 RTAutoRes& operator=(T aValue) 87 80 { 88 if (mValue != 0)81 if (mValue != NulRes()) 89 82 { 90 83 Destruct(mValue); … … 94 87 } 95 88 96 /** Assign from a reference structure into an AutoRes pointer. */97 RTAutoRes& operator=(RTAutoResRef<T, Destruct> ref)98 {99 if (ref.mValue != mValue)100 {101 Destruct(mValue);102 mValue = ref.mValue;103 }104 return *this;105 }106 107 /** Typecast an AutoRes pointer to an AutoRes pointer of a different type. */108 template <class T1>109 operator RTAutoRes<T1, Destruct>()110 { return RTAutoRes<T1, Destruct>(release()); }111 112 /** Typecast an AutoRes pointer to a reference structure. */113 template <class T1>114 operator RTAutoResRef<T1, Destruct>()115 { return RTAutoResRef<T1, Destruct>(release()); }116 117 89 /** release method to get the pointer's value and "reset" the pointer. */ 118 T release(void) { T aTmp = mValue; mValue = 0; return aTmp; }90 T release(void) { T aTmp = mValue; mValue = NulRes(); return aTmp; } 119 91 120 92 /** reset the pointer value to zero or to another pointer. */ 121 void reset(T aValue = 0) { if (aValue != mValue) { Destruct(mValue); mValue = aValue; } } 93 void reset(T aValue = NulRes()) { if (aValue != mValue) 94 { Destruct(mValue); mValue = aValue; } } 122 95 123 96 /** Accessing the value inside. */ … … 129 102 inline void RTAutoResRecastVoid(T *aValue) { fn(aValue); } 130 103 104 template <class T> 105 T *RTMemAutoNul(void) { return (T *)(NULL); } 106 107 /** 108 * An auto pointer-type class for structures allocated using C-like APIs. 109 * 110 * The idea of this class is to manage resources which the current code is 111 * responsible for freeing. By wrapping the resource in an RTAutoRes, you 112 * ensure that the resource will be freed when you leave the scope in which 113 * the RTAutoRes is defined, unless you explicitly release the resource again. 114 * 115 * A typical use case is when a function is allocating a number of resources. 116 * If any single allocation fails then all other resources must be freed. If 117 * all allocations succeed, then the resources should be returned to the 118 * caller. By placing all allocated resources in RTAutoRes containers, you 119 * ensure that they will be freed on failure, and only have to take care of 120 * releasing them when you return them. 121 * @param T the type of the resource 122 * @param Destruct the function to be used to free the resource 123 */ 131 124 template <class T, void Destruct(T *) = RTAutoResRecastVoid <T, RTMemFree> > 132 class RTMemAutoPtr : public RTAutoRes <T *, Destruct >125 class RTMemAutoPtr : public RTAutoRes <T *, Destruct, RTMemAutoNul<T> > 133 126 { 134 127 public: 135 128 /** Constructor */ 136 RTMemAutoPtr(T *aValue = NULL) : RTAutoRes <T *, Destruct >(aValue) {}129 RTMemAutoPtr(T *aValue = NULL) : RTAutoRes <T *, Destruct, RTMemAutoNul<T> >(aValue) {} 137 130 138 /** Copy constructors */139 RTMemAutoPtr(RTMemAutoPtr &orig) : RTAutoRes <T *, Destruct>(orig) {}140 template <class T1>141 RTMemAutoPtr(RTMemAutoPtr<T1, Destruct> &orig) : RTAutoRes<T1 *, Destruct>(orig) {}142 143 /** Assignment operators */144 RTMemAutoPtr& operator=(RTMemAutoPtr &orig)145 { this->RTAutoRes <T *, Destruct>::operator=(orig); }146 template <class T1>147 RTMemAutoPtr& operator=(RTMemAutoPtr<T1, Destruct> &orig)148 { this->RTAutoRes<T1 *, Destruct>::operator=(orig); return *this; }149 131 RTMemAutoPtr& operator=(T *aValue) 150 { this->RTAutoRes <T *, Destruct>::operator=(aValue); return *this; } 151 RTMemAutoPtr& operator=(RTAutoResRef<T *, Destruct> ref) 152 { this->RTAutoRes <T *, Destruct>::operator=(ref); return *this; } 132 { this->RTAutoRes <T *, Destruct, RTMemAutoNul<T> >::operator=(aValue); return *this; } 153 133 154 134 /** Dereference with * operator. */
Note:
See TracChangeset
for help on using the changeset viewer.