1
0
forked from Alepha/Alepha

AutoRAII facility.

This commit is contained in:
2021-10-16 23:21:28 -04:00
parent 76c7eaf1b7
commit 6110f618d8
3 changed files with 137 additions and 0 deletions

91
AutoRAII.h Normal file
View File

@ -0,0 +1,91 @@
static_assert( __cplusplus > 201700, "C++17 Required" );
#pragma once
#include <Alepha/Alepha.h>
#include <functional>
#include <type_traits>
#include <boost/noncopyable.hpp>
namespace Alepha::Hydrogen
{
inline namespace exports { inline namespace auto_raii {} }
namespace detail::auto_raii
{
inline namespace exports
{
template< typename T, typename Dtor= std::function< void ( T ) > >
class AutoRAII : boost::noncopyable
{
private:
Dtor dtor;
T value;
public:
~AutoRAII()
{
if constexpr( std::is_same_v< Dtor, std::function< void ( T ) > > )
{
if( dtor == nullptr ) return;
}
dtor( value );
}
template
<
typename AutoRAII_= AutoRAII,
typename= std::enable_if_t< std::is_same_v< AutoRAII_, AutoRAII > >,
typename= std::enable_if_t< std::is_function_v< decltype( AutoRAII_::dtor ) > >
>
AutoRAII( AutoRAII &&move )
: value()
{
std::swap( move.dtor, this->dtor );
std::swap( move.value, this->value );
}
template< typename Ctor >
explicit AutoRAII( Ctor ctor, Dtor dtor ) : dtor( std::move( dtor ) ), value( ctor() ) {}
template
<
typename AutoRAII_= AutoRAII,
typename= std::enable_if_t< std::is_same_v< AutoRAII_, AutoRAII > >,
typename= std::enable_if_t< std::is_function_v< decltype( AutoRAII_::dtor ) > >
>
AutoRAII &operator= ( AutoRAII_ &&move )
{
std::swap( move.dtor, this->dtor );
std::swap( move.value, this->value );
}
operator const T &() const { return value; }
template
<
typename T_= T,
typename= std::enable_if_t< std::is_pointer_v< T_ > >
>
decltype( auto ) operator *() const { return *value; }
template
<
typename T_= T,
typename= std::enable_if_t< std::is_pointer_v< T_ > >
>
decltype( auto ) operator->() const { return value; }
};
template< typename Ctor, typename Dtor >
explicit AutoRAII( Ctor ctor, Dtor ) -> AutoRAII< decltype( ctor() ), Dtor >;
}
}
namespace exports::auto_raii
{
using namespace detail::auto_raii::exports;
}
}