12851dbadSAxel Dörfler /* 22851dbadSAxel Dörfler * Copyright 2001-2007, Ingo Weinhold, bonefish@users.sf.net. All rights reserved. 32851dbadSAxel Dörfler * Distributed under the terms of the MIT License. 42851dbadSAxel Dörfler */ 5ce8cfdb8SIngo Weinhold #ifndef _AUTO_DELETER_H 6ce8cfdb8SIngo Weinhold #define _AUTO_DELETER_H 7ce8cfdb8SIngo Weinhold 8d91215d3SAxel Dörfler 92851dbadSAxel Dörfler /*! Scope-based automatic deletion of objects/arrays. 102851dbadSAxel Dörfler ObjectDeleter - deletes an object 112851dbadSAxel Dörfler ArrayDeleter - deletes an array 122851dbadSAxel Dörfler MemoryDeleter - free()s malloc()ed memory 1334cbfd39SIngo Weinhold CObjectDeleter - calls an arbitrary specified destructor function 14cb7ce9a3SAxel Dörfler FileDescriptorCloser - closes a file descriptor 152851dbadSAxel Dörfler */ 162851dbadSAxel Dörfler 17d91215d3SAxel Dörfler 18ce8cfdb8SIngo Weinhold #include <stdlib.h> 19d91215d3SAxel Dörfler #include <unistd.h> 20d91215d3SAxel Dörfler 21ce8cfdb8SIngo Weinhold 22ce8cfdb8SIngo Weinhold namespace BPrivate { 23ce8cfdb8SIngo Weinhold 24d91215d3SAxel Dörfler 25ce8cfdb8SIngo Weinhold // AutoDeleter 26ce8cfdb8SIngo Weinhold 27f277fb63SIngo Weinhold template<typename C, typename DeleteFunc> 28ce8cfdb8SIngo Weinhold class AutoDeleter { 29ce8cfdb8SIngo Weinhold public: 30ce8cfdb8SIngo Weinhold inline AutoDeleter() 31ce8cfdb8SIngo Weinhold : fObject(NULL) 32ce8cfdb8SIngo Weinhold { 33ce8cfdb8SIngo Weinhold } 34ce8cfdb8SIngo Weinhold 35ce8cfdb8SIngo Weinhold inline AutoDeleter(C *object) 36ce8cfdb8SIngo Weinhold : fObject(object) 37ce8cfdb8SIngo Weinhold { 38ce8cfdb8SIngo Weinhold } 39ce8cfdb8SIngo Weinhold 40ce8cfdb8SIngo Weinhold inline ~AutoDeleter() 41ce8cfdb8SIngo Weinhold { 42ce8cfdb8SIngo Weinhold fDelete(fObject); 43ce8cfdb8SIngo Weinhold } 44ce8cfdb8SIngo Weinhold 45ce8cfdb8SIngo Weinhold inline void SetTo(C *object) 46ce8cfdb8SIngo Weinhold { 47f277fb63SIngo Weinhold if (object != fObject) { 48ce8cfdb8SIngo Weinhold fDelete(fObject); 49ce8cfdb8SIngo Weinhold fObject = object; 50ce8cfdb8SIngo Weinhold } 51f277fb63SIngo Weinhold } 52f277fb63SIngo Weinhold 53f277fb63SIngo Weinhold inline void Unset() 54f277fb63SIngo Weinhold { 55f277fb63SIngo Weinhold SetTo(NULL); 56f277fb63SIngo Weinhold } 57f277fb63SIngo Weinhold 58f277fb63SIngo Weinhold inline void Delete() 59f277fb63SIngo Weinhold { 60f277fb63SIngo Weinhold SetTo(NULL); 61f277fb63SIngo Weinhold } 62ce8cfdb8SIngo Weinhold 635519ed57SIngo Weinhold inline C *Get() const 645519ed57SIngo Weinhold { 655519ed57SIngo Weinhold return fObject; 665519ed57SIngo Weinhold } 675519ed57SIngo Weinhold 68ce8cfdb8SIngo Weinhold inline C *Detach() 69ce8cfdb8SIngo Weinhold { 70ce8cfdb8SIngo Weinhold C *object = fObject; 71ce8cfdb8SIngo Weinhold fObject = NULL; 72ce8cfdb8SIngo Weinhold return object; 73ce8cfdb8SIngo Weinhold } 74ce8cfdb8SIngo Weinhold 75b97e1292SOliver Tappe inline C *operator->() const 76b97e1292SOliver Tappe { 77b97e1292SOliver Tappe return fObject; 78b97e1292SOliver Tappe } 79b97e1292SOliver Tappe 8034cbfd39SIngo Weinhold protected: 81ce8cfdb8SIngo Weinhold C *fObject; 82f277fb63SIngo Weinhold DeleteFunc fDelete; 83ec43e4f4SX512 84ec43e4f4SX512 private: 85ec43e4f4SX512 AutoDeleter(const AutoDeleter&); 86ec43e4f4SX512 AutoDeleter& operator=(const AutoDeleter&); 87ce8cfdb8SIngo Weinhold }; 88ce8cfdb8SIngo Weinhold 89ce8cfdb8SIngo Weinhold 90ce8cfdb8SIngo Weinhold // ObjectDeleter 91ce8cfdb8SIngo Weinhold 92ce8cfdb8SIngo Weinhold template<typename C> 93ce8cfdb8SIngo Weinhold struct ObjectDelete 94ce8cfdb8SIngo Weinhold { 95ce8cfdb8SIngo Weinhold inline void operator()(C *object) 96ce8cfdb8SIngo Weinhold { 97ce8cfdb8SIngo Weinhold delete object; 98ce8cfdb8SIngo Weinhold } 99ce8cfdb8SIngo Weinhold }; 100ce8cfdb8SIngo Weinhold 101ce8cfdb8SIngo Weinhold template<typename C> 102ce8cfdb8SIngo Weinhold struct ObjectDeleter : AutoDeleter<C, ObjectDelete<C> > 103ce8cfdb8SIngo Weinhold { 104ce8cfdb8SIngo Weinhold ObjectDeleter() : AutoDeleter<C, ObjectDelete<C> >() {} 105ce8cfdb8SIngo Weinhold ObjectDeleter(C *object) : AutoDeleter<C, ObjectDelete<C> >(object) {} 106ce8cfdb8SIngo Weinhold }; 107ce8cfdb8SIngo Weinhold 108ce8cfdb8SIngo Weinhold 109ce8cfdb8SIngo Weinhold // ArrayDeleter 110ce8cfdb8SIngo Weinhold 111ce8cfdb8SIngo Weinhold template<typename C> 112ce8cfdb8SIngo Weinhold struct ArrayDelete 113ce8cfdb8SIngo Weinhold { 114ce8cfdb8SIngo Weinhold inline void operator()(C *array) 115ce8cfdb8SIngo Weinhold { 116ce8cfdb8SIngo Weinhold delete[] array; 117ce8cfdb8SIngo Weinhold } 118ce8cfdb8SIngo Weinhold }; 119ce8cfdb8SIngo Weinhold 120ce8cfdb8SIngo Weinhold template<typename C> 121ce8cfdb8SIngo Weinhold struct ArrayDeleter : AutoDeleter<C, ArrayDelete<C> > 122ce8cfdb8SIngo Weinhold { 123ce8cfdb8SIngo Weinhold ArrayDeleter() : AutoDeleter<C, ArrayDelete<C> >() {} 124ce8cfdb8SIngo Weinhold ArrayDeleter(C *array) : AutoDeleter<C, ArrayDelete<C> >(array) {} 1258301c498SX512 1268301c498SX512 inline C& operator[](size_t index) const 1278301c498SX512 { 1288301c498SX512 return this->Get()[index]; 1298301c498SX512 } 130ce8cfdb8SIngo Weinhold }; 131ce8cfdb8SIngo Weinhold 132ce8cfdb8SIngo Weinhold 133ce8cfdb8SIngo Weinhold // MemoryDeleter 134ce8cfdb8SIngo Weinhold 135ce8cfdb8SIngo Weinhold struct MemoryDelete 136ce8cfdb8SIngo Weinhold { 137ce8cfdb8SIngo Weinhold inline void operator()(void *memory) 138ce8cfdb8SIngo Weinhold { 139ce8cfdb8SIngo Weinhold free(memory); 140ce8cfdb8SIngo Weinhold } 141ce8cfdb8SIngo Weinhold }; 142ce8cfdb8SIngo Weinhold 143ce8cfdb8SIngo Weinhold struct MemoryDeleter : AutoDeleter<void, MemoryDelete > 144ce8cfdb8SIngo Weinhold { 145ce8cfdb8SIngo Weinhold MemoryDeleter() : AutoDeleter<void, MemoryDelete >() {} 146ce8cfdb8SIngo Weinhold MemoryDeleter(void *memory) : AutoDeleter<void, MemoryDelete >(memory) {} 147ce8cfdb8SIngo Weinhold }; 148ce8cfdb8SIngo Weinhold 14934cbfd39SIngo Weinhold 15034cbfd39SIngo Weinhold // CObjectDeleter 15134cbfd39SIngo Weinhold 1527d775e79SX512 template<typename Type, typename DestructorReturnType, 1537d775e79SX512 DestructorReturnType (*Destructor)(Type*)> 15434cbfd39SIngo Weinhold struct CObjectDelete 15534cbfd39SIngo Weinhold { 15634cbfd39SIngo Weinhold inline void operator()(Type *object) 15734cbfd39SIngo Weinhold { 1587d775e79SX512 if (object != NULL) 1597d775e79SX512 Destructor(object); 16034cbfd39SIngo Weinhold } 16134cbfd39SIngo Weinhold }; 16234cbfd39SIngo Weinhold 1637d775e79SX512 template<typename Type, typename DestructorReturnType, 1647d775e79SX512 DestructorReturnType (*Destructor)(Type*)> 16534cbfd39SIngo Weinhold struct CObjectDeleter 1667d775e79SX512 : AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType, Destructor> > 16734cbfd39SIngo Weinhold { 1687d775e79SX512 typedef AutoDeleter<Type, 1697d775e79SX512 CObjectDelete<Type, DestructorReturnType, Destructor> > Base; 17034cbfd39SIngo Weinhold 1717d775e79SX512 CObjectDeleter() : Base() 17234cbfd39SIngo Weinhold { 17334cbfd39SIngo Weinhold } 17434cbfd39SIngo Weinhold 1757d775e79SX512 CObjectDeleter(Type *object) : Base(object) 17634cbfd39SIngo Weinhold { 17734cbfd39SIngo Weinhold } 17834cbfd39SIngo Weinhold }; 17934cbfd39SIngo Weinhold 180e378ab1cSIngo Weinhold 181e378ab1cSIngo Weinhold // MethodDeleter 182e378ab1cSIngo Weinhold 183*aecba913SX512 template<typename Type, typename DestructorReturnType, 184*aecba913SX512 DestructorReturnType (Type::*Destructor)()> 185e378ab1cSIngo Weinhold struct MethodDelete 186e378ab1cSIngo Weinhold { 187e378ab1cSIngo Weinhold inline void operator()(Type *object) 188e378ab1cSIngo Weinhold { 189*aecba913SX512 if (object != NULL) 190*aecba913SX512 (object->*Destructor)(); 191e378ab1cSIngo Weinhold } 192e378ab1cSIngo Weinhold }; 193e378ab1cSIngo Weinhold 194e378ab1cSIngo Weinhold 195*aecba913SX512 template<typename Type, typename DestructorReturnType, 196*aecba913SX512 DestructorReturnType (Type::*Destructor)()> 197e378ab1cSIngo Weinhold struct MethodDeleter 198*aecba913SX512 : AutoDeleter<Type, MethodDelete<Type, DestructorReturnType, Destructor> > 199e378ab1cSIngo Weinhold { 200*aecba913SX512 typedef AutoDeleter<Type, 201*aecba913SX512 MethodDelete<Type, DestructorReturnType, Destructor> > Base; 202e378ab1cSIngo Weinhold 203*aecba913SX512 MethodDeleter() : Base() 204e378ab1cSIngo Weinhold { 205e378ab1cSIngo Weinhold } 206e378ab1cSIngo Weinhold 207*aecba913SX512 MethodDeleter(Type *object) : Base(object) 208e378ab1cSIngo Weinhold { 209e378ab1cSIngo Weinhold } 210e378ab1cSIngo Weinhold }; 211e378ab1cSIngo Weinhold 212d91215d3SAxel Dörfler 213cb7ce9a3SAxel Dörfler // FileDescriptorCloser 214d91215d3SAxel Dörfler 215cb7ce9a3SAxel Dörfler struct FileDescriptorCloser { 2165b486787SIngo Weinhold inline FileDescriptorCloser() 2175b486787SIngo Weinhold : 2185b486787SIngo Weinhold fDescriptor(-1) 2195b486787SIngo Weinhold { 2205b486787SIngo Weinhold } 2215b486787SIngo Weinhold 222cb7ce9a3SAxel Dörfler inline FileDescriptorCloser(int descriptor) 223d91215d3SAxel Dörfler : 224d91215d3SAxel Dörfler fDescriptor(descriptor) 225d91215d3SAxel Dörfler { 226d91215d3SAxel Dörfler } 227d91215d3SAxel Dörfler 228cb7ce9a3SAxel Dörfler inline ~FileDescriptorCloser() 229d91215d3SAxel Dörfler { 2305b486787SIngo Weinhold SetTo(-1); 231d91215d3SAxel Dörfler } 232d91215d3SAxel Dörfler 2335b486787SIngo Weinhold inline void SetTo(int descriptor) 234d91215d3SAxel Dörfler { 2355b486787SIngo Weinhold if (fDescriptor >= 0) 2365b486787SIngo Weinhold close(fDescriptor); 2375b486787SIngo Weinhold 2385b486787SIngo Weinhold fDescriptor = descriptor; 2395b486787SIngo Weinhold } 2405b486787SIngo Weinhold 2415b486787SIngo Weinhold inline void Unset() 2425b486787SIngo Weinhold { 2435b486787SIngo Weinhold SetTo(-1); 2445b486787SIngo Weinhold } 2455b486787SIngo Weinhold 246b29db8ebSX512 inline int Get() 247b29db8ebSX512 { 248b29db8ebSX512 return fDescriptor; 249b29db8ebSX512 } 250b29db8ebSX512 2515b486787SIngo Weinhold inline int Detach() 2525b486787SIngo Weinhold { 2535b486787SIngo Weinhold int descriptor = fDescriptor; 254d91215d3SAxel Dörfler fDescriptor = -1; 2555b486787SIngo Weinhold return descriptor; 256d91215d3SAxel Dörfler } 257d91215d3SAxel Dörfler 258d91215d3SAxel Dörfler private: 259d91215d3SAxel Dörfler int fDescriptor; 260d91215d3SAxel Dörfler }; 261d91215d3SAxel Dörfler 262d91215d3SAxel Dörfler 263ce8cfdb8SIngo Weinhold } // namespace BPrivate 264ce8cfdb8SIngo Weinhold 265d91215d3SAxel Dörfler 26618f5cd17SIngo Weinhold using ::BPrivate::ObjectDeleter; 26718f5cd17SIngo Weinhold using ::BPrivate::ArrayDeleter; 26818f5cd17SIngo Weinhold using ::BPrivate::MemoryDeleter; 26918f5cd17SIngo Weinhold using ::BPrivate::CObjectDeleter; 27018f5cd17SIngo Weinhold using ::BPrivate::MethodDeleter; 27118f5cd17SIngo Weinhold using ::BPrivate::FileDescriptorCloser; 272d91215d3SAxel Dörfler 273ce8cfdb8SIngo Weinhold 274ce8cfdb8SIngo Weinhold #endif // _AUTO_DELETER_H 275