forked from Alepha/Alepha
AutoRAII facility.
This commit is contained in:
91
AutoRAII.h
Normal file
91
AutoRAII.h
Normal 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;
|
||||
}
|
||||
}
|
43
AutoRAII.test/0.cc
Normal file
43
AutoRAII.test/0.cc
Normal file
@ -0,0 +1,43 @@
|
||||
static_assert( __cplusplus > 201700, "C++17 Required" );
|
||||
|
||||
#include <Alepha/AutoRAII.h>
|
||||
|
||||
#include <Alepha/Testing/test.h>
|
||||
#include <Alepha/Utility/evaluation.h>
|
||||
|
||||
int
|
||||
main( const int argcnt, const char *const argvec[] )
|
||||
{
|
||||
return Alepha::Testing::runAllTests( argcnt, argvec );
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace Alepha::exports::auto_raii;
|
||||
|
||||
using namespace Alepha::Utility::exports::evaluation;
|
||||
using namespace Alepha::Testing::exports::literals;
|
||||
using Alepha::Testing::exports::TestState;
|
||||
|
||||
auto tests= enroll <=[]
|
||||
{
|
||||
"basic.syntax"_test <=[]( TestState test )
|
||||
{
|
||||
AutoRAII managed{ []{ return 42; }, []( auto ){} };
|
||||
test.expect( managed == 42 );
|
||||
};
|
||||
|
||||
"basic.functionality"_test <=[]( TestState test )
|
||||
{
|
||||
bool initialized= false;
|
||||
bool destroyed= false;
|
||||
{
|
||||
AutoRAII managed{ [&]{ initialized= true; return 0; }, [&]( auto ) { initialized= false; destroyed= true; } };
|
||||
test.expect( initialized );
|
||||
test.expect( not destroyed );
|
||||
}
|
||||
test.expect( not initialized );
|
||||
test.expect( destroyed );
|
||||
};
|
||||
};
|
||||
}
|
3
AutoRAII.test/Makefile
Normal file
3
AutoRAII.test/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
CXXFLAGS+= -std=c++17 -I ../
|
||||
|
||||
all: 0
|
Reference in New Issue
Block a user