memory/deleter: add deferred_delete and deferred_unique

This commit is contained in:
Danny Robson 2021-04-09 13:29:14 +10:00
parent d5139c2cc4
commit 8339c55baa

View File

@ -3,15 +3,59 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
* Copyright 2015-2021 Danny Robson <danny@nerdcruft.net>
*/
#ifndef __UTIL_MEMORY_DELETER_HPP
#define __UTIL_MEMORY_DELETER_HPP
#pragma once
#include <functional>
#include <memory>
namespace cruft::memory {
///////////////////////////////////////////////////////////////////////////
/// A deleter object that is deliberately left undefined.
///
/// This allows it to be used in places where the definition of `ValueT`
/// would otherwise be required (eg, std::unique_ptr). This requires that
/// the body be explicitly defined by the user; see `DEFERRED_DELETE`.
template <typename ValueT>
struct deferred_delete {
void operator() (ValueT*) const;
};
///------------------------------------------------------------------------
/// An implementation of deferred delete that just calls `delete` directly.
#define DEFERRED_DELETE(KLASS) \
template <> \
void \
::cruft::memory::deferred_delete<KLASS>::operator() (KLASS *ptr) const \
{ delete ptr; }
///////////////////////////////////////////////////////////////////////////
/// A convenience typedef for a unique_ptr that uses a deferred_delete
/// deleter object.
template <typename ValueT>
using deferred_unique = std::unique_ptr<ValueT, deferred_delete<ValueT>>;
///------------------------------------------------------------------------
/// A convenience function for creation of deferred_unique objects
/// analogous to std::make_unique
template <typename ValueT, typename ...ArgsT>
deferred_unique<ValueT>
make_deferred_unique (ArgsT &&...args)
{
return deferred_unique<ValueT> (
new ValueT (
std::forward<ArgsT> (args)...
)
);
}
///////////////////////////////////////////////////////////////////////////
template <typename T>
class func_deleter {
public:
@ -53,6 +97,4 @@ namespace cruft::memory {
private:
OwnerT& m_owner;
};
}
#endif
}