/* * 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 MethodObjectDeleter - calls an arbitrary object function in given struct ptr HandleDeleter - use arbitrary handle type and destructor function FileDescriptorCloser - closes a file descriptor, based on HandleDeleter */ #include #include #include namespace BPrivate { // AutoDeleter template class AutoDeleter { public: inline AutoDeleter() : fObject(NULL) { } inline AutoDeleter(C *object) : fObject(object) { } inline ~AutoDeleter() { DeleteFunc destructor; destructor(fObject); } inline void SetTo(C *object) { if (object != fObject) { DeleteFunc destructor; destructor(fObject); fObject = object; } } inline void Unset() { SetTo(NULL); } inline void Delete() { SetTo(NULL); } inline bool IsSet() const { return fObject != 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; 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 (object != NULL) Destructor(object); } }; template struct CObjectDeleter : AutoDeleter > { typedef AutoDeleter > Base; CObjectDeleter() : Base() { } CObjectDeleter(Type *object) : Base(object) { } }; // MethodDeleter template struct MethodDelete { inline void operator()(Type *object) { if (object != NULL) (object->*Destructor)(); } }; template struct MethodDeleter : AutoDeleter > { typedef AutoDeleter > Base; MethodDeleter() : Base() { } MethodDeleter(Type *object) : Base(object) { } }; // MethodObjectDeleter template struct MethodObjectDelete { inline void operator()(Type *object) { if (object != NULL) ((**table).*Deleter)(object); } }; template struct MethodObjectDeleter : AutoDeleter > { typedef AutoDeleter > Base; MethodObjectDeleter() : Base() {} MethodObjectDeleter(Type *object) : Base(object) {} }; // HandleDeleter struct StatusHandleChecker { inline bool operator()(status_t handle) { return handle >= B_OK; } }; template class HandleDeleter { public: inline HandleDeleter() : fHandle(nullValue) { } inline HandleDeleter(C handle) : fHandle(handle) { } inline ~HandleDeleter() { if (IsSet()) Destructor(fHandle); } inline void SetTo(C handle) { if (handle != fHandle) { if (IsSet()) Destructor(fHandle); fHandle = handle; } } inline void Unset() { SetTo(nullValue); } inline void Delete() { SetTo(nullValue); } inline bool IsSet() const { Checker isHandleSet; return isHandleSet(fHandle); } inline C Get() const { return fHandle; } inline C Detach() { C handle = fHandle; fHandle = nullValue; return handle; } protected: C fHandle; private: HandleDeleter(const HandleDeleter&); HandleDeleter& operator=(const HandleDeleter&); }; // FileDescriptorCloser typedef HandleDeleter FileDescriptorCloser; } // namespace BPrivate using ::BPrivate::ObjectDeleter; using ::BPrivate::ArrayDeleter; using ::BPrivate::MemoryDeleter; using ::BPrivate::CObjectDeleter; using ::BPrivate::MethodDeleter; using ::BPrivate::MethodObjectDeleter; using ::BPrivate::HandleDeleter; using ::BPrivate::FileDescriptorCloser; #endif // _AUTO_DELETER_H