Skip to content

Instantly share code, notes, and snippets.

@markhc
Last active June 18, 2019 20:33
Show Gist options
  • Save markhc/55afb0e3ea42869a65cebb50d4bc8c28 to your computer and use it in GitHub Desktop.
Save markhc/55afb0e3ea42869a65cebb50d4bc8c28 to your computer and use it in GitHub Desktop.
#include "SafeHandles/SafeHandle.hpp"
#include "windows.hpp"
class SafeFileHandle //
: public SafeHandle<INVALID_HANDLE_VALUE> //
{
public:
SafeFileHandle(void* handle)
: SafeHandle(handle, &SafeFileHandle::deleter)
{
}
private:
static void deleter(void* handle){
if(handle != INVALID_HANDLE_VALUE)
CloseHandle(handle);
}
};
#pragma once
#include <cstddef> // std::nullptr_t
#include <memory> // std::shared_ptr
template <std::uintptr_t INVALID_VALUE>
class SafeHandle
{
public:
SafeHandle() = default;
~SafeHandle() = default;
SafeHandle(std::nullptr_t);
template <typename Dx>
SafeHandle(void* handle, Dx dtor);
SafeHandle(SafeHandle const&) = default;
SafeHandle(SafeHandle&&) = default;
SafeHandle& operator=(SafeHandle const&) = default;
SafeHandle& operator=(SafeHandle&&) = default;
operator bool() const noexcept
{
return reinterpret_cast<std::uintptr_t>(m_handle.get()) != INVALID_VALUE;
}
bool operator==(const SafeHandle& other) const noexcept
{
return m_handle == other.m_handle;
}
bool operator!=(const SafeHandle& other) const noexcept
{
return m_handle != other.m_handle;
}
bool operator==(void const* handle) const noexcept
{
return m_handle.get() == handle;
}
bool operator!=(void const* handle) const noexcept
{
return m_handle.get() != handle;
}
void* unsafeGetHandle() const noexcept
{
return m_handle.get();
}
void reset()
{
m_handle.reset();
}
void close()
{
m_handle.reset();
}
protected:
std::shared_ptr<void> m_handle{};
};
// ------------------------------------------------------------------------------------------------
template <std::uintptr_t INVALID_VALUE>
inline SafeHandle<INVALID_VALUE>::SafeHandle(std::nullptr_t)
{
}
// ------------------------------------------------------------------------------------------------
template <std::uintptr_t INVALID_VALUE>
template <typename Dx>
SafeHandle<INVALID_VALUE>::SafeHandle(void* handle, Dx dtor) : m_handle(handle, dtor)
{
}
// ------------------------------------------------------------------------------------------------
template <std::uintptr_t INVALID_VALUE>
inline bool operator==(const SafeHandle<INVALID_VALUE>& h, std::nullptr_t) noexcept
{
return h.unsafeGetHandle() == nullptr;
}
// ------------------------------------------------------------------------------------------------
template <std::uintptr_t INVALID_VALUE>
inline bool operator!=(const SafeHandle<INVALID_VALUE>& h, std::nullptr_t) noexcept
{
return h.unsafeGetHandle() != nullptr;
}
// ------------------------------------------------------------------------------------------------
template <std::uintptr_t INVALID_VALUE>
inline bool operator==(std::nullptr_t, const SafeHandle<INVALID_VALUE>& h) noexcept
{
return h.unsafeGetHandle() == nullptr;
}
// ------------------------------------------------------------------------------------------------
template <std::uintptr_t INVALID_VALUE>
inline bool operator!=(std::nullptr_t, const SafeHandle<INVALID_VALUE>& h) noexcept
{
return h.unsafeGetHandle() != nullptr;
}
// ------------------------------------------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment