#pragma once #include namespace PortabilityLayer { struct MMHandleBlock; } class THandleBase { public: explicit THandleBase(PortabilityLayer::MMHandleBlock *hdl); THandleBase(const THandleBase &other); PortabilityLayer::MMHandleBlock *MMBlock() const; void Dispose() const; protected: PortabilityLayer::MMHandleBlock *m_hdl; }; template class THandle final : public THandleBase { public: THandle(); THandle(std::nullptr_t); THandle(T **hdl); explicit THandle(PortabilityLayer::MMHandleBlock *hdl); THandle(const THandle &other); operator T *const*() const; operator T **(); template THandle StaticCast() const; template THandle ReinterpretCast() const; template THandle ImplicitCast() const; bool operator==(const THandle &other) const; bool operator!=(const THandle &other) const; bool operator==(T** other) const; bool operator!=(T** other) const; bool operator==(std::nullptr_t) const; bool operator!=(std::nullptr_t) const; static THandle NullPtr(); }; typedef THandle Handle; #include "MMHandleBlock.h" inline THandleBase::THandleBase(PortabilityLayer::MMHandleBlock *hdl) : m_hdl(hdl) { } inline THandleBase::THandleBase(const THandleBase &other) : m_hdl(other.m_hdl) { } inline PortabilityLayer::MMHandleBlock *THandleBase::MMBlock() const { return m_hdl; } template inline THandle::THandle() : THandleBase(nullptr) { } template inline THandle::THandle(std::nullptr_t) : THandleBase(nullptr) { } template inline THandle::THandle(T **hdl) : THandleBase(reinterpret_cast(hdl)) { } template inline THandle::THandle(PortabilityLayer::MMHandleBlock *hdl) : THandleBase(hdl) { } template inline THandle::THandle(const THandle &other) : THandleBase(other.m_hdl) { } template inline bool THandle::operator==(const THandle &other) const { return m_hdl == other.m_hdl; } template inline bool THandle::operator!=(const THandle &other) const { return m_hdl != other.m_hdl; } template inline bool THandle::operator==(T** other) const { if (other == nullptr) return m_hdl == nullptr; return static_cast(&m_hdl->m_contents) == static_cast(other); } template inline bool THandle::operator!=(T** other) const { if (other == nullptr) return m_hdl != nullptr; return static_cast(&m_hdl->m_contents) != static_cast(other); } template inline bool THandle::operator==(std::nullptr_t) const { return m_hdl == nullptr; } template inline bool THandle::operator!=(std::nullptr_t) const { return m_hdl != nullptr; } template inline THandle THandle::NullPtr() { return THandle(static_cast(nullptr)); } template inline THandle::operator T*const*() const { // Should use const_cast here but then I'd have to strip qualifiers, blah, do the lazy thing return (T*const*)(&m_hdl->m_contents); } template inline THandle::operator T**() { // Should use const_cast here but then I'd have to strip qualifiers, blah, do the lazy thing return (T**)(&m_hdl->m_contents); } template template THandle THandle::StaticCast() const { (void)(static_cast(static_cast(nullptr))); return THandle(m_hdl); } template template THandle THandle::ReinterpretCast() const { (void)(reinterpret_cast(static_cast(nullptr))); return THandle(m_hdl); } template template THandle THandle::ImplicitCast() const { const TOther *target = static_cast(nullptr); (void)target; return THandle(m_hdl); }