/* * 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 FileDescriptorCloser - closes a file descriptor */ #include #include namespace BPrivate { // 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; } inline C *operator->() const { return fObject; } protected: C *fObject; DeleteFunc fDelete; private: AutoDeleter(const AutoDeleter&); AutoDeleter& operator=(const AutoDeleter&); }; // 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) {} inline C& operator[](size_t index) const { return this->Get()[index]; } }; // 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; } }; // FileDescriptorCloser struct FileDescriptorCloser { inline FileDescriptorCloser() : fDescriptor(-1) { } inline FileDescriptorCloser(int descriptor) : fDescriptor(descriptor) { } inline ~FileDescriptorCloser() { SetTo(-1); } inline void SetTo(int descriptor) { if (fDescriptor >= 0) close(fDescriptor); fDescriptor = descriptor; } inline void Unset() { SetTo(-1); } inline int Get() { return fDescriptor; } inline int Detach() { int descriptor = fDescriptor; fDescriptor = -1; return descriptor; } private: int fDescriptor; }; } // namespace BPrivate using ::BPrivate::ObjectDeleter; using ::BPrivate::ArrayDeleter; using ::BPrivate::MemoryDeleter; using ::BPrivate::CObjectDeleter; using ::BPrivate::MethodDeleter; using ::BPrivate::FileDescriptorCloser; #endif // _AUTO_DELETER_H