I\'m a C++ amateur. I\'m writing some Win32 API code and there are handles and weirdly compositely allocated objects aplenty. So I was wondering - is there some wrapper clas
template
class unique_handle
{
using pointer = typename Traits::pointer;
pointer m_value;
auto close() throw() -> void
{
if (*this)
{
Traits::close(m_value);
}
}
public:
unique_handle(unique_handle const &) = delete;
auto operator=(unique_handle const &)->unique_handle & = delete;
explicit unique_handle(pointer value = Traits::invalid()) throw() :
m_value{ value }
{
}
unique_handle(unique_handle && other) throw() :
m_value{ other.release() }
{
}
auto operator=(unique_handle && other) throw() -> unique_handle &
{
if (this != &other)
{
reset(other.release());
}
return *this;
}
~unique_handle() throw()
{
close();
}
explicit operator bool() const throw()
{
return m_value != Traits::invalid();
}
auto get() const throw() -> pointer
{
return m_value;
}
auto get_address_of() throw() -> pointer *
{
ASSERT(!*this);
return &m_value;
}
auto release() throw() -> pointer
{
auto value = m_value;
m_value = Traits::invalid();
return value;
}
auto reset(pointer value = Traits::invalid()) throw() -> bool
{
if (m_value != value)
{
close();
m_value = value;
}
return static_cast(*this);
}
auto swap(unique_handle & other) throw() -> void
{
std::swap(m_value, other.m_value);
}
};
template
auto swap(unique_handle & left,
unique_handle & right) throw() -> void
{
left.swap(right);
}
template
auto operator==(unique_handle const & left,
unique_handle const & right) throw() -> bool
{
return left.get() == right.get();
}
template
auto operator!=(unique_handle const & left,
unique_handle const & right) throw() -> bool
{
return left.get() != right.get();
}
template
auto operator<(unique_handle const & left,
unique_handle const & right) throw() -> bool
{
return left.get() < right.get();
}
template
auto operator>=(unique_handle const & left,
unique_handle const & right) throw() -> bool
{
return left.get() >= right.get();
}
template
auto operator>(unique_handle const & left,
unique_handle const & right) throw() -> bool
{
return left.get() > right.get();
}
template
auto operator<=(unique_handle const & left,
unique_handle const & right) throw() -> bool
{
return left.get() <= right.get();
}
struct null_handle_traits
{
using pointer = HANDLE;
static auto invalid() throw() -> pointer
{
return nullptr;
}
static auto close(pointer value) throw() -> void
{
VERIFY(CloseHandle(value));
}
};
struct invalid_handle_traits
{
using pointer = HANDLE;
static auto invalid() throw() -> pointer
{
return INVALID_HANDLE_VALUE;
}
static auto close(pointer value) throw() -> void
{
VERIFY(CloseHandle(value));
}
};
using null_handle = unique_handle;
using invalid_handle = unique_handle;