#pragma once
#include "Winheaders.h"
namespace blackbone
{
///
/// Strong exception guarantee
///
template
class HandleGuard
{
public:
explicit HandleGuard( handle_t handle = zero_handle ) noexcept
: _handle( handle )
{
}
HandleGuard( HandleGuard&& rhs ) noexcept
: _handle( rhs._handle )
{
rhs._handle = zero_handle;
}
~HandleGuard()
{
if (_handle != zero_handle)
close_fn( _handle );
}
HandleGuard( const HandleGuard& ) = delete;
HandleGuard& operator =( const HandleGuard& ) = delete;
HandleGuard& operator =( HandleGuard&& rhs ) noexcept
{
if (std::addressof( rhs ) == this)
return *this;
reset( rhs._handle );
rhs._handle = zero_handle;
return *this;
}
HandleGuard& operator =( handle_t handle ) noexcept
{
reset( handle );
return *this;
}
void reset( handle_t handle = zero_handle ) noexcept
{
if (handle == _handle)
return;
if (_handle != zero_handle)
close_fn( _handle );
_handle = handle;
}
handle_t release() noexcept
{
auto tmp = _handle;
_handle = zero_handle;
return tmp;
}
inline handle_t get() const noexcept { return _handle; }
inline operator handle_t() const noexcept { return _handle; }
inline explicit operator bool() const noexcept { return _handle != zero_handle; }
inline handle_t* operator &() noexcept { return &_handle; }
inline bool operator ==( const HandleGuard& rhs ) const noexcept { return _handle == rhs._handle; }
inline bool operator <( const HandleGuard& rhs ) const noexcept { return _handle < rhs._handle; }
private:
handle_t _handle;
};
using Handle = HandleGuard;
using FileHandle = HandleGuard;
using ACtxHandle = HandleGuard;
using FileMapHandle = HandleGuard;
using SnapHandle = FileHandle;
using RegHandle = HandleGuard;
}