/* * Copyright 2001-2007, Ingo Weinhold, bonefish@users.sf.net. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _AUTO_DELETER_H #define _AUTO_DELETER_H /*! Scope-based automatic deletion of objects/arrays. ObjectDeleter - deletes an object ArrayDeleter - deletes an array MemoryDeleter - free()s malloc()ed memory CObjectDeleter - calls an arbitrary specified destructor function */ #include namespace FSShell { // AutoDeleter template class AutoDeleter { public: inline AutoDeleter() : fObject(NULL) { } inline AutoDeleter(C *object) : fObject(object) { } inline ~AutoDeleter() { fDelete(fObject); } inline void SetTo(C *object) { if (object != fObject) { fDelete(fObject); fObject = object; } } inline void Unset() { SetTo(NULL); } inline void Delete() { SetTo(NULL); } inline C *Get() const { return fObject; } inline C *Detach() { C *object = fObject; fObject = NULL; return object; } protected: C *fObject; DeleteFunc fDelete; }; // ObjectDeleter template struct ObjectDelete { inline void operator()(C *object) { delete object; } }; template struct ObjectDeleter : AutoDeleter > { ObjectDeleter() : AutoDeleter >() {} ObjectDeleter(C *object) : AutoDeleter >(object) {} }; // ArrayDeleter template struct ArrayDelete { inline void operator()(C *array) { delete[] array; } }; template struct ArrayDeleter : AutoDeleter > { ArrayDeleter() : AutoDeleter >() {} ArrayDeleter(C *array) : AutoDeleter >(array) {} }; // MemoryDeleter struct MemoryDelete { inline void operator()(void *memory) { free(memory); } }; struct MemoryDeleter : AutoDeleter { MemoryDeleter() : AutoDeleter() {} MemoryDeleter(void *memory) : AutoDeleter(memory) {} }; // CObjectDeleter template struct CObjectDelete { inline void operator()(Type *object) { if (fDestructor != NULL && object != NULL) fDestructor(object); } template inline void operator=(Destructor destructor) { fDestructor = destructor; } private: DestructorReturnType (*fDestructor)(Type*); }; template struct CObjectDeleter : AutoDeleter > { typedef AutoDeleter > Base; template CObjectDeleter(Destructor destructor) : Base() { Base::fDelete = destructor; } template CObjectDeleter(Type *object, Destructor destructor) : Base(object) { Base::fDelete = destructor; } }; // MethodDeleter template struct MethodDelete { inline void operator()(Type *object) { if (fDestructor && object != NULL) (object->*fDestructor)(); } template inline void operator=(Destructor destructor) { fDestructor = destructor; } private: DestructorReturnType (Type::*fDestructor)(); }; template struct MethodDeleter : AutoDeleter > { typedef AutoDeleter > Base; template MethodDeleter(Destructor destructor) : Base() { Base::fDelete = destructor; } template MethodDeleter(Type *object, Destructor destructor) : Base(object) { Base::fDelete = destructor; } }; } // namespace FSShell using FSShell::ObjectDeleter; using FSShell::ArrayDeleter; using FSShell::MemoryDeleter; using FSShell::CObjectDeleter; using FSShell::MethodDeleter; #endif // _AUTO_DELETER_H