322 lines
12 KiB
C++
322 lines
12 KiB
C++
//------------------------------------------------------------------------
|
|
// Project : SDK Base
|
|
// Version : 1.0
|
|
//
|
|
// Category : Helpers
|
|
// Filename : base/source/fcleanup.h
|
|
// Created by : Steinberg, 2008
|
|
// Description : Template classes for automatic resource cleanup
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// LICENSE
|
|
// (c) 2018, Steinberg Media Technologies GmbH, All Rights Reserved
|
|
//-----------------------------------------------------------------------------
|
|
// Redistribution and use in source and binary forms, with or without modification,
|
|
// are permitted provided that the following conditions are met:
|
|
//
|
|
// * Redistributions of source code must retain the above copyright notice,
|
|
// this list of conditions and the following disclaimer.
|
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
// and/or other materials provided with the distribution.
|
|
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
|
// contributors may be used to endorse or promote products derived from this
|
|
// software without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
#include <stdlib.h>
|
|
|
|
namespace Steinberg {
|
|
|
|
/** Template definition for classes that help guarding against memory leaks.
|
|
A stack allocated object of this type automatically deletes an at construction time passed
|
|
dynamically allocated single object when it reaches the end of its scope. \n\n
|
|
Intended usage:
|
|
\code
|
|
{
|
|
int* pointerToInt = new int;
|
|
Steinberg::FDeleter<int> deleter (pointerToInt);
|
|
|
|
// Do something with the variable behind pointerToInt.
|
|
|
|
} // No memory leak here, destructor of deleter cleans up the integer.
|
|
\endcode
|
|
*/
|
|
//------------------------------------------------------------------------
|
|
template <class T>
|
|
struct FDeleter
|
|
{
|
|
/// Constructor. _toDelete is a pointer to the dynamically allocated object that is to be
|
|
/// deleted when this FDeleter object's destructor is executed.
|
|
FDeleter (T* _toDelete) : toDelete (_toDelete) {}
|
|
/// Destructor. Calls delete on the at construction time passed pointer.
|
|
~FDeleter ()
|
|
{
|
|
if (toDelete)
|
|
delete toDelete;
|
|
}
|
|
T* toDelete; ///< Remembers the object that is to be deleted during destruction.
|
|
};
|
|
|
|
/** Template definition for classes that help guarding against memory leaks.
|
|
A stack allocated object of this type automatically deletes an at construction time passed
|
|
dynamically allocated array of objects when it reaches the end of its scope. \n\n
|
|
Intended usage:
|
|
\code
|
|
{
|
|
int* pointerToIntArray = new int[10];
|
|
Steinberg::FArrayDeleter<int> deleter (pointerToIntArray);
|
|
|
|
// Do something with the array behind pointerToIntArray.
|
|
|
|
} // No memory leak here, destructor of deleter cleans up the integer array.
|
|
\endcode
|
|
*/
|
|
//------------------------------------------------------------------------
|
|
template <class T>
|
|
struct FArrayDeleter
|
|
{
|
|
/// Constructor. _arrayToDelete is a pointer to the dynamically allocated array of objects that
|
|
/// is to be deleted when this FArrayDeleter object's destructor is executed.
|
|
FArrayDeleter (T* _arrayToDelete) : arrayToDelete (_arrayToDelete) {}
|
|
|
|
/// Destructor. Calls delete[] on the at construction time passed pointer.
|
|
~FArrayDeleter ()
|
|
{
|
|
if (arrayToDelete)
|
|
delete[] arrayToDelete;
|
|
}
|
|
|
|
T* arrayToDelete; ///< Remembers the array of objects that is to be deleted during destruction.
|
|
};
|
|
|
|
/** Template definition for classes that help guarding against dangling pointers.
|
|
A stack allocated object of this type automatically resets an at construction time passed
|
|
pointer to null when it reaches the end of its scope. \n\n
|
|
Intended usage:
|
|
\code
|
|
int* pointerToInt = 0;
|
|
{
|
|
int i = 1;
|
|
pointerToInt = &i;
|
|
Steinberg::FPtrNuller<int> ptrNuller (pointerToInt);
|
|
|
|
// Do something with pointerToInt.
|
|
|
|
} // No dangling pointer here, pointerToInt is reset to 0 by destructor of ptrNuller.
|
|
\endcode
|
|
*/
|
|
//------------------------------------------------------------------------
|
|
template <class T>
|
|
struct FPtrNuller
|
|
{
|
|
/// Constructor. _toNull is a reference to the pointer that is to be reset to NULL when this
|
|
/// FPtrNuller object's destructor is executed.
|
|
FPtrNuller (T*& _toNull) : toNull (_toNull) {}
|
|
/// Destructor. Calls delete[] on the at construction time passed pointer.
|
|
~FPtrNuller () { toNull = 0; }
|
|
|
|
T*& toNull; ///< Remembers the pointer that is to be set to NULL during destruction.
|
|
};
|
|
|
|
/** Template definition for classes that help resetting an object's value.
|
|
A stack allocated object of this type automatically resets the value of an at construction time
|
|
passed object to null when it reaches the end of its scope. \n\n Intended usage: \code int theObject
|
|
= 0;
|
|
{
|
|
Steinberg::FNuller<int> theNuller (theObject);
|
|
|
|
theObject = 1;
|
|
|
|
} // Here the destructor of theNuller resets the value of theObject to 0.
|
|
\endcode
|
|
*/
|
|
//------------------------------------------------------------------------
|
|
template <class T>
|
|
struct FNuller
|
|
{
|
|
/// Constructor. _toNull is a reference to the object that is to be assigned 0 when this FNuller
|
|
/// object's destructor is executed.
|
|
FNuller (T& _toNull) : toNull (_toNull) {}
|
|
/// Destructor. Assigns 0 to the at construction time passed object reference.
|
|
~FNuller () { toNull = 0; }
|
|
|
|
T& toNull; ///< Remembers the object that is to be assigned 0 during destruction.
|
|
};
|
|
|
|
/** Class definition for objects that help resetting boolean variables.
|
|
A stack allocated object of this type automatically sets an at construction time passed
|
|
boolean variable immediately to TRUE and resets the same variable to FALSE when it
|
|
reaches the end of its own scope. \n\n
|
|
Intended usage:
|
|
\code
|
|
bool theBoolean = false;
|
|
{
|
|
Steinberg::FBoolSetter theBoolSetter (theBoolean);
|
|
// Here the constructor of theBoolSetter sets theBoolean to TRUE.
|
|
|
|
// Do something.
|
|
|
|
} // Here the destructor of theBoolSetter resets theBoolean to FALSE.
|
|
\endcode
|
|
*/
|
|
//------------------------------------------------------------------------
|
|
template <class T>
|
|
struct FBooleanSetter
|
|
{
|
|
/// Constructor. _toSet is a reference to the boolean that is set to TRUE immediately in this
|
|
/// constructor call and gets reset to FALSE when this FBoolSetter object's destructor is
|
|
/// executed.
|
|
FBooleanSetter (T& _toSet) : toSet (_toSet) { toSet = true; }
|
|
/// Destructor. Resets the at construction time passed boolean to FALSE.
|
|
~FBooleanSetter () { toSet = false; }
|
|
|
|
T& toSet; ///< Remembers the boolean that is to be reset during destruction.
|
|
};
|
|
|
|
typedef FBooleanSetter<bool> FBoolSetter;
|
|
|
|
/** Class definition for objects that help setting boolean variables.
|
|
A stack allocated object of this type automatically sets an at construction time passed
|
|
boolean variable to TRUE if the given condition is met. At the end of its own scope the
|
|
stack object will reset the same boolean variable to FALSE, if it wasn't set so already. \n\n
|
|
Intended usage:
|
|
\code
|
|
bool theBoolean = false;
|
|
{
|
|
bool creativityFirst = true;
|
|
Steinberg::FConditionalBoolSetter theCBSetter (theBoolean, creativityFirst);
|
|
// Here the constructor of theCBSetter sets theBoolean to the value of creativityFirst.
|
|
|
|
// Do something.
|
|
|
|
} // Here the destructor of theCBSetter resets theBoolean to FALSE.
|
|
\endcode
|
|
*/
|
|
//------------------------------------------------------------------------
|
|
struct FConditionalBoolSetter
|
|
{
|
|
/// Constructor. _toSet is a reference to the boolean that is to be set. If the in the second
|
|
/// parameter given condition is TRUE then also _toSet is set to TRUE immediately.
|
|
FConditionalBoolSetter (bool& _toSet, bool condition) : toSet (_toSet)
|
|
{
|
|
if (condition)
|
|
toSet = true;
|
|
}
|
|
/// Destructor. Resets the at construction time passed boolean to FALSE.
|
|
~FConditionalBoolSetter () { toSet = false; }
|
|
|
|
bool& toSet; ///< Remembers the boolean that is to be reset during destruction.
|
|
};
|
|
|
|
/** Template definition for classes that help closing resources.
|
|
A stack allocated object of this type automatically calls the close method of an at
|
|
construction time passed object when it reaches the end of its scope.
|
|
It goes without saying that the given type needs to have a close method. \n\n
|
|
Intended usage:
|
|
\code
|
|
struct CloseableObject
|
|
{
|
|
void close() {};
|
|
};
|
|
|
|
{
|
|
CloseableObject theObject;
|
|
Steinberg::FCloser<CloseableObject> theCloser (&theObject);
|
|
|
|
// Do something.
|
|
|
|
} // Here the destructor of theCloser calls the close method of theObject.
|
|
\endcode
|
|
*/
|
|
template <class T>
|
|
struct FCloser
|
|
{
|
|
/// Constructor. _obj is the pointer on which close is to be called when this FCloser object's
|
|
/// destructor is executed.
|
|
FCloser (T* _obj) : obj (_obj) {}
|
|
/// Destructor. Calls the close function on the at construction time passed pointer.
|
|
~FCloser ()
|
|
{
|
|
if (obj)
|
|
obj->close ();
|
|
}
|
|
|
|
T* obj; ///< Remembers the pointer on which close is to be called during destruction.
|
|
};
|
|
|
|
/** Class definition for objects that help guarding against memory leaks.
|
|
A stack allocated object of this type automatically frees the "malloced" memory behind an at
|
|
construction time passed pointer when it reaches the end of its scope.
|
|
*/
|
|
//------------------------------------------------------------------------
|
|
/*! \class FMallocReleaser
|
|
*/
|
|
//------------------------------------------------------------------------
|
|
class FMallocReleaser
|
|
{
|
|
public:
|
|
/// Constructor. _data is the pointer to the memory on which free is to be called when this
|
|
/// FMallocReleaser object's destructor is executed.
|
|
FMallocReleaser (void* _data) : data (_data) {}
|
|
/// Destructor. Calls the free function on the at construction time passed pointer.
|
|
~FMallocReleaser ()
|
|
{
|
|
if (data)
|
|
free (data);
|
|
}
|
|
//------------------------------------------------------------------------
|
|
protected:
|
|
void* data; ///< Remembers the pointer on which free is to be called during destruction.
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
} // namespace Steinberg
|
|
|
|
|
|
#if SMTG_OS_MACOS
|
|
typedef const void* CFTypeRef;
|
|
extern "C" {
|
|
extern void CFRelease (CFTypeRef cf);
|
|
}
|
|
|
|
namespace Steinberg {
|
|
|
|
/** Class definition for objects that helps releasing CoreFoundation objects.
|
|
A stack allocated object of this type automatically releases an at construction time
|
|
passed CoreFoundation object when it reaches the end of its scope.
|
|
|
|
Only available on Macintosh platform.
|
|
*/
|
|
//------------------------------------------------------------------------
|
|
/*! \class CFReleaser
|
|
*/
|
|
//------------------------------------------------------------------------
|
|
class CFReleaser
|
|
{
|
|
public:
|
|
/// Constructor. _obj is the reference to an CoreFoundation object which is to be released when this CFReleaser object's destructor is executed.
|
|
CFReleaser (CFTypeRef _obj) : obj (_obj) {}
|
|
/// Destructor. Releases the at construction time passed object.
|
|
~CFReleaser () { if (obj) CFRelease (obj); }
|
|
protected:
|
|
CFTypeRef obj; ///< Remembers the object which is to be released during destruction.
|
|
};
|
|
|
|
//------------------------------------------------------------------------
|
|
} // namespace Steinberg
|
|
|
|
#endif // SMTG_OS_MACOS
|