mirror of
https://github.com/opnsense/src.git
synced 2026-04-26 16:47:30 -04:00
This corresponds with the branchpoint for the 3.6 release. A number of files not required for the FreeBSD build have been removed. Sponsored by: DARPA, AFRL
323 lines
12 KiB
C++
323 lines
12 KiB
C++
//===-- CleanUp.h -----------------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef liblldb_CleanUp_h_
|
|
#define liblldb_CleanUp_h_
|
|
|
|
#include "lldb/lldb-public.h"
|
|
#include <functional>
|
|
|
|
namespace lldb_utility {
|
|
|
|
//----------------------------------------------------------------------
|
|
// Templated class that guarantees that a cleanup callback function will
|
|
// be called. The cleanup function will be called once under the
|
|
// following conditions:
|
|
// - when the object goes out of scope
|
|
// - when the user explicitly calls clean.
|
|
// - the current value will be cleaned up when a new value is set using
|
|
// set(T value) as long as the current value hasn't already been cleaned.
|
|
//
|
|
// This class is designed to be used with simple types for type T (like
|
|
// file descriptors, opaque handles, pointers, etc). If more complex
|
|
// type T objects are desired, we need to probably specialize this class
|
|
// to take "const T&" for all input T parameters. Yet if a type T is
|
|
// complex already it might be better to build the cleanup functionality
|
|
// into T.
|
|
//
|
|
// The cleanup function must take one argument that is of type T.
|
|
// The calback function return type is R. The return value is currently
|
|
// needed for "CallbackType". If there is an easy way to get around the
|
|
// need for the return value we can change this class.
|
|
//
|
|
// The two template parameters are:
|
|
// T - The variable type of value that will be stored and used as the
|
|
// sole argument for the cleanup callback.
|
|
// R - The return type for the cleanup function.
|
|
//
|
|
// EXAMPLES
|
|
// // Use with file handles that get opened where you want to close
|
|
// // them. Below we use "int open(const char *path, int oflag, ...)"
|
|
// // which returns an integer file descriptor. -1 is the invalid file
|
|
// // descriptor so to make an object that will call "int close(int fd)"
|
|
// // automatically we can use:
|
|
//
|
|
// CleanUp <int, int> fd(open("/tmp/a.txt", O_RDONLY, 0), -1, close);
|
|
//
|
|
// // malloc/free example
|
|
// CleanUp <void *, void> malloced_bytes(malloc(32), NULL, free);
|
|
//----------------------------------------------------------------------
|
|
template <typename T, typename R = void>
|
|
class CleanUp
|
|
{
|
|
public:
|
|
typedef T value_type;
|
|
typedef std::function<R(value_type)> CallbackType;
|
|
|
|
//----------------------------------------------------------------------
|
|
// Constructor that sets the current value only. No values are
|
|
// considered to be invalid and the cleanup function will be called
|
|
// regardless of the value of m_current_value.
|
|
//----------------------------------------------------------------------
|
|
CleanUp (value_type value, CallbackType callback) :
|
|
m_current_value (value),
|
|
m_invalid_value (),
|
|
m_callback (callback),
|
|
m_callback_called (false),
|
|
m_invalid_value_is_valid (false)
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Constructor that sets the current value and also the invalid value.
|
|
// The cleanup function will be called on "m_value" as long as it isn't
|
|
// equal to "m_invalid_value".
|
|
//----------------------------------------------------------------------
|
|
CleanUp (value_type value, value_type invalid, CallbackType callback) :
|
|
m_current_value (value),
|
|
m_invalid_value (invalid),
|
|
m_callback (callback),
|
|
m_callback_called (false),
|
|
m_invalid_value_is_valid (true)
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Automatically cleanup when this object goes out of scope.
|
|
//----------------------------------------------------------------------
|
|
~CleanUp ()
|
|
{
|
|
clean();
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Access the value stored in this class
|
|
//----------------------------------------------------------------------
|
|
value_type get()
|
|
{
|
|
return m_current_value;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Access the value stored in this class
|
|
//----------------------------------------------------------------------
|
|
const value_type
|
|
get() const
|
|
{
|
|
return m_current_value;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Reset the owned value to "value". If a current value is valid and
|
|
// the cleanup callback hasn't been called, the previous value will
|
|
// be cleaned up (see void CleanUp::clean()).
|
|
//----------------------------------------------------------------------
|
|
void
|
|
set (const value_type value)
|
|
{
|
|
// Cleanup the current value if needed
|
|
clean ();
|
|
// Now set the new value and mark our callback as not called
|
|
m_callback_called = false;
|
|
m_current_value = value;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Checks is "m_current_value" is valid. The value is considered valid
|
|
// no invalid value was supplied during construction of this object or
|
|
// if an invalid value was supplied and "m_current_value" is not equal
|
|
// to "m_invalid_value".
|
|
//
|
|
// Returns true if "m_current_value" is valid, false otherwise.
|
|
//----------------------------------------------------------------------
|
|
bool
|
|
is_valid() const
|
|
{
|
|
if (m_invalid_value_is_valid)
|
|
return m_current_value != m_invalid_value;
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// This function will call the cleanup callback provided in the
|
|
// constructor one time if the value is considered valid (See is_valid()).
|
|
// This function sets m_callback_called to true so we don't call the
|
|
// cleanup callback multiple times on the same value.
|
|
//----------------------------------------------------------------------
|
|
void
|
|
clean()
|
|
{
|
|
if (m_callback && !m_callback_called)
|
|
{
|
|
m_callback_called = true;
|
|
if (is_valid())
|
|
m_callback(m_current_value);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Cancels the cleanup that would have been called on "m_current_value"
|
|
// if it was valid. This function can be used to release the value
|
|
// contained in this object so ownership can be transferred to the caller.
|
|
//----------------------------------------------------------------------
|
|
value_type
|
|
release ()
|
|
{
|
|
m_callback_called = true;
|
|
return m_current_value;
|
|
}
|
|
|
|
private:
|
|
value_type m_current_value;
|
|
const value_type m_invalid_value;
|
|
CallbackType m_callback;
|
|
bool m_callback_called;
|
|
bool m_invalid_value_is_valid;
|
|
|
|
// Outlaw default constructor, copy constructor and the assignment operator
|
|
DISALLOW_COPY_AND_ASSIGN (CleanUp);
|
|
};
|
|
|
|
template <typename T, typename R, typename A0>
|
|
class CleanUp2
|
|
{
|
|
public:
|
|
typedef T value_type;
|
|
typedef std::function<R(value_type,A0)> CallbackType;
|
|
|
|
//----------------------------------------------------------------------
|
|
// Constructor that sets the current value only. No values are
|
|
// considered to be invalid and the cleanup function will be called
|
|
// regardless of the value of m_current_value.
|
|
//----------------------------------------------------------------------
|
|
CleanUp2 (value_type value, CallbackType callback, A0 arg) :
|
|
m_current_value (value),
|
|
m_invalid_value (),
|
|
m_callback (callback),
|
|
m_callback_called (false),
|
|
m_invalid_value_is_valid (false),
|
|
m_argument(arg)
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Constructor that sets the current value and also the invalid value.
|
|
// The cleanup function will be called on "m_value" as long as it isn't
|
|
// equal to "m_invalid_value".
|
|
//----------------------------------------------------------------------
|
|
CleanUp2 (value_type value, value_type invalid, CallbackType callback, A0 arg) :
|
|
m_current_value (value),
|
|
m_invalid_value (invalid),
|
|
m_callback (callback),
|
|
m_callback_called (false),
|
|
m_invalid_value_is_valid (true),
|
|
m_argument(arg)
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Automatically cleanup when this object goes out of scope.
|
|
//----------------------------------------------------------------------
|
|
~CleanUp2 ()
|
|
{
|
|
clean();
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Access the value stored in this class
|
|
//----------------------------------------------------------------------
|
|
value_type get()
|
|
{
|
|
return m_current_value;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Access the value stored in this class
|
|
//----------------------------------------------------------------------
|
|
const value_type
|
|
get() const
|
|
{
|
|
return m_current_value;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Reset the owned value to "value". If a current value is valid and
|
|
// the cleanup callback hasn't been called, the previous value will
|
|
// be cleaned up (see void CleanUp::clean()).
|
|
//----------------------------------------------------------------------
|
|
void
|
|
set (const value_type value)
|
|
{
|
|
// Cleanup the current value if needed
|
|
clean ();
|
|
// Now set the new value and mark our callback as not called
|
|
m_callback_called = false;
|
|
m_current_value = value;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Checks is "m_current_value" is valid. The value is considered valid
|
|
// no invalid value was supplied during construction of this object or
|
|
// if an invalid value was supplied and "m_current_value" is not equal
|
|
// to "m_invalid_value".
|
|
//
|
|
// Returns true if "m_current_value" is valid, false otherwise.
|
|
//----------------------------------------------------------------------
|
|
bool
|
|
is_valid() const
|
|
{
|
|
if (m_invalid_value_is_valid)
|
|
return m_current_value != m_invalid_value;
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// This function will call the cleanup callback provided in the
|
|
// constructor one time if the value is considered valid (See is_valid()).
|
|
// This function sets m_callback_called to true so we don't call the
|
|
// cleanup callback multiple times on the same value.
|
|
//----------------------------------------------------------------------
|
|
void
|
|
clean()
|
|
{
|
|
if (m_callback && !m_callback_called)
|
|
{
|
|
m_callback_called = true;
|
|
if (is_valid())
|
|
m_callback(m_current_value, m_argument);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Cancels the cleanup that would have been called on "m_current_value"
|
|
// if it was valid. This function can be used to release the value
|
|
// contained in this object so ownership can be transferred to the caller.
|
|
//----------------------------------------------------------------------
|
|
value_type
|
|
release ()
|
|
{
|
|
m_callback_called = true;
|
|
return m_current_value;
|
|
}
|
|
|
|
private:
|
|
value_type m_current_value;
|
|
const value_type m_invalid_value;
|
|
CallbackType m_callback;
|
|
bool m_callback_called;
|
|
bool m_invalid_value_is_valid;
|
|
A0 m_argument;
|
|
|
|
// Outlaw default constructor, copy constructor and the assignment operator
|
|
DISALLOW_COPY_AND_ASSIGN (CleanUp2);
|
|
};
|
|
|
|
} // namespace lldb_utility
|
|
|
|
#endif // #ifndef liblldb_CleanUp_h_
|