1*2851dbadSAxel Dörfler /* 2*2851dbadSAxel Dörfler * Copyright 2001-2007, Ingo Weinhold, bonefish@users.sf.net. All rights reserved. 3*2851dbadSAxel Dörfler * Distributed under the terms of the MIT License. 4*2851dbadSAxel Dörfler */ 5ce8cfdb8SIngo Weinhold #ifndef _AUTO_DELETER_H 6ce8cfdb8SIngo Weinhold #define _AUTO_DELETER_H 7ce8cfdb8SIngo Weinhold 8*2851dbadSAxel Dörfler /*! Scope-based automatic deletion of objects/arrays. 9*2851dbadSAxel Dörfler ObjectDeleter - deletes an object 10*2851dbadSAxel Dörfler ArrayDeleter - deletes an array 11*2851dbadSAxel Dörfler MemoryDeleter - free()s malloc()ed memory 12*2851dbadSAxel Dörfler */ 13*2851dbadSAxel Dörfler 14ce8cfdb8SIngo Weinhold #include <stdlib.h> 15ce8cfdb8SIngo Weinhold 16ce8cfdb8SIngo Weinhold namespace BPrivate { 17ce8cfdb8SIngo Weinhold 18ce8cfdb8SIngo Weinhold // AutoDeleter 19ce8cfdb8SIngo Weinhold 20f277fb63SIngo Weinhold template<typename C, typename DeleteFunc> 21ce8cfdb8SIngo Weinhold class AutoDeleter { 22ce8cfdb8SIngo Weinhold public: 23ce8cfdb8SIngo Weinhold inline AutoDeleter() 24ce8cfdb8SIngo Weinhold : fObject(NULL) 25ce8cfdb8SIngo Weinhold { 26ce8cfdb8SIngo Weinhold } 27ce8cfdb8SIngo Weinhold 28ce8cfdb8SIngo Weinhold inline AutoDeleter(C *object) 29ce8cfdb8SIngo Weinhold : fObject(object) 30ce8cfdb8SIngo Weinhold { 31ce8cfdb8SIngo Weinhold } 32ce8cfdb8SIngo Weinhold 33ce8cfdb8SIngo Weinhold inline ~AutoDeleter() 34ce8cfdb8SIngo Weinhold { 35ce8cfdb8SIngo Weinhold fDelete(fObject); 36ce8cfdb8SIngo Weinhold } 37ce8cfdb8SIngo Weinhold 38ce8cfdb8SIngo Weinhold inline void SetTo(C *object) 39ce8cfdb8SIngo Weinhold { 40f277fb63SIngo Weinhold if (object != fObject) { 41ce8cfdb8SIngo Weinhold fDelete(fObject); 42ce8cfdb8SIngo Weinhold fObject = object; 43ce8cfdb8SIngo Weinhold } 44f277fb63SIngo Weinhold } 45f277fb63SIngo Weinhold 46f277fb63SIngo Weinhold inline void Unset() 47f277fb63SIngo Weinhold { 48f277fb63SIngo Weinhold SetTo(NULL); 49f277fb63SIngo Weinhold } 50f277fb63SIngo Weinhold 51f277fb63SIngo Weinhold inline void Delete() 52f277fb63SIngo Weinhold { 53f277fb63SIngo Weinhold SetTo(NULL); 54f277fb63SIngo Weinhold } 55ce8cfdb8SIngo Weinhold 565519ed57SIngo Weinhold inline C *Get() const 575519ed57SIngo Weinhold { 585519ed57SIngo Weinhold return fObject; 595519ed57SIngo Weinhold } 605519ed57SIngo Weinhold 61ce8cfdb8SIngo Weinhold inline C *Detach() 62ce8cfdb8SIngo Weinhold { 63ce8cfdb8SIngo Weinhold C *object = fObject; 64ce8cfdb8SIngo Weinhold fObject = NULL; 65ce8cfdb8SIngo Weinhold return object; 66ce8cfdb8SIngo Weinhold } 67ce8cfdb8SIngo Weinhold 68ce8cfdb8SIngo Weinhold private: 69ce8cfdb8SIngo Weinhold C *fObject; 70f277fb63SIngo Weinhold DeleteFunc fDelete; 71ce8cfdb8SIngo Weinhold }; 72ce8cfdb8SIngo Weinhold 73ce8cfdb8SIngo Weinhold 74ce8cfdb8SIngo Weinhold // ObjectDeleter 75ce8cfdb8SIngo Weinhold 76ce8cfdb8SIngo Weinhold template<typename C> 77ce8cfdb8SIngo Weinhold struct ObjectDelete 78ce8cfdb8SIngo Weinhold { 79ce8cfdb8SIngo Weinhold inline void operator()(C *object) 80ce8cfdb8SIngo Weinhold { 81ce8cfdb8SIngo Weinhold delete object; 82ce8cfdb8SIngo Weinhold } 83ce8cfdb8SIngo Weinhold }; 84ce8cfdb8SIngo Weinhold 85ce8cfdb8SIngo Weinhold template<typename C> 86ce8cfdb8SIngo Weinhold struct ObjectDeleter : AutoDeleter<C, ObjectDelete<C> > 87ce8cfdb8SIngo Weinhold { 88ce8cfdb8SIngo Weinhold ObjectDeleter() : AutoDeleter<C, ObjectDelete<C> >() {} 89ce8cfdb8SIngo Weinhold ObjectDeleter(C *object) : AutoDeleter<C, ObjectDelete<C> >(object) {} 90ce8cfdb8SIngo Weinhold }; 91ce8cfdb8SIngo Weinhold 92ce8cfdb8SIngo Weinhold 93ce8cfdb8SIngo Weinhold // ArrayDeleter 94ce8cfdb8SIngo Weinhold 95ce8cfdb8SIngo Weinhold template<typename C> 96ce8cfdb8SIngo Weinhold struct ArrayDelete 97ce8cfdb8SIngo Weinhold { 98ce8cfdb8SIngo Weinhold inline void operator()(C *array) 99ce8cfdb8SIngo Weinhold { 100ce8cfdb8SIngo Weinhold delete[] array; 101ce8cfdb8SIngo Weinhold } 102ce8cfdb8SIngo Weinhold }; 103ce8cfdb8SIngo Weinhold 104ce8cfdb8SIngo Weinhold template<typename C> 105ce8cfdb8SIngo Weinhold struct ArrayDeleter : AutoDeleter<C, ArrayDelete<C> > 106ce8cfdb8SIngo Weinhold { 107ce8cfdb8SIngo Weinhold ArrayDeleter() : AutoDeleter<C, ArrayDelete<C> >() {} 108ce8cfdb8SIngo Weinhold ArrayDeleter(C *array) : AutoDeleter<C, ArrayDelete<C> >(array) {} 109ce8cfdb8SIngo Weinhold }; 110ce8cfdb8SIngo Weinhold 111ce8cfdb8SIngo Weinhold 112ce8cfdb8SIngo Weinhold // MemoryDeleter 113ce8cfdb8SIngo Weinhold 114ce8cfdb8SIngo Weinhold struct MemoryDelete 115ce8cfdb8SIngo Weinhold { 116ce8cfdb8SIngo Weinhold inline void operator()(void *memory) 117ce8cfdb8SIngo Weinhold { 118ce8cfdb8SIngo Weinhold free(memory); 119ce8cfdb8SIngo Weinhold } 120ce8cfdb8SIngo Weinhold }; 121ce8cfdb8SIngo Weinhold 122ce8cfdb8SIngo Weinhold struct MemoryDeleter : AutoDeleter<void, MemoryDelete > 123ce8cfdb8SIngo Weinhold { 124ce8cfdb8SIngo Weinhold MemoryDeleter() : AutoDeleter<void, MemoryDelete >() {} 125ce8cfdb8SIngo Weinhold MemoryDeleter(void *memory) : AutoDeleter<void, MemoryDelete >(memory) {} 126ce8cfdb8SIngo Weinhold }; 127ce8cfdb8SIngo Weinhold 128ce8cfdb8SIngo Weinhold } // namespace BPrivate 129ce8cfdb8SIngo Weinhold 130ce8cfdb8SIngo Weinhold using BPrivate::ObjectDeleter; 131ce8cfdb8SIngo Weinhold using BPrivate::ArrayDeleter; 132ce8cfdb8SIngo Weinhold using BPrivate::MemoryDeleter; 133ce8cfdb8SIngo Weinhold 134ce8cfdb8SIngo Weinhold #endif // _AUTO_DELETER_H 135