/** * This file has no copyright assigned and is placed in the Public Domain. * This file is part of the mingw-w64 runtime package. * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ #ifndef _WRL_CLIENT_H_ #define _WRL_CLIENT_H_ #include <stddef.h> #include <unknwn.h> /* #include <weakreference.h> */ #include <roapi.h> /* #include <wrl/def.h> */ #include <wrl/internal.h> namespace Microsoft { namespace WRL { namespace Details { template <typename T> class ComPtrRefBase { protected: T* ptr_; public: typedef typename T::InterfaceType InterfaceType; #ifndef __WRL_CLASSIC_COM__ operator IInspectable**() const throw() { static_assert(__is_base_of(IInspectable, InterfaceType), "Invalid cast"); return reinterpret_cast<IInspectable**>(ptr_->ReleaseAndGetAddressOf()); } #endif operator IUnknown**() const throw() { static_assert(__is_base_of(IUnknown, InterfaceType), "Invalid cast"); return reinterpret_cast<IUnknown**>(ptr_->ReleaseAndGetAddressOf()); } }; template <typename T> class ComPtrRef : public Details::ComPtrRefBase<T> { public: ComPtrRef(T *ptr) throw() { ComPtrRefBase<T>::ptr_ = ptr; } operator void**() const throw() { return reinterpret_cast<void**>(ComPtrRefBase<T>::ptr_->ReleaseAndGetAddressOf()); } operator T*() throw() { *ComPtrRefBase<T>::ptr_ = nullptr; return ComPtrRefBase<T>::ptr_; } operator typename ComPtrRefBase<T>::InterfaceType**() throw() { return ComPtrRefBase<T>::ptr_->ReleaseAndGetAddressOf(); } typename ComPtrRefBase<T>::InterfaceType *operator*() throw() { return ComPtrRefBase<T>::ptr_->Get(); } typename ComPtrRefBase<T>::InterfaceType *const *GetAddressOf() const throw() { return ComPtrRefBase<T>::ptr_->GetAddressOf(); } typename ComPtrRefBase<T>::InterfaceType **ReleaseAndGetAddressOf() throw() { return ComPtrRefBase<T>::ptr_->ReleaseAndGetAddressOf(); } }; } template<typename T> class ComPtr { public: typedef T InterfaceType; ComPtr() throw() : ptr_(nullptr) {} ComPtr(decltype(nullptr)) throw() : ptr_(nullptr) {} template<class U> ComPtr(U *other) throw() : ptr_(other) { InternalAddRef(); } ComPtr(const ComPtr &other) throw() : ptr_(other.ptr_) { InternalAddRef(); } template<class U> ComPtr(const ComPtr<U> &other) throw() : ptr_(other.ptr_) { InternalAddRef(); } ComPtr(ComPtr &&other) throw() : ptr_(nullptr) { if(this != reinterpret_cast<ComPtr*>(&reinterpret_cast<unsigned char&>(other))) Swap(other); } template<class U> ComPtr(ComPtr<U>&& other) throw() : ptr_(other.ptr_) { other.ptr_ = nullptr; } ~ComPtr() throw() { InternalRelease(); } ComPtr &operator=(decltype(nullptr)) throw() { InternalRelease(); return *this; } ComPtr &operator=(InterfaceType *other) throw() { if (ptr_ != other) { InternalRelease(); ptr_ = other; InternalAddRef(); } return *this; } template<typename U> ComPtr &operator=(U *other) throw() { if (ptr_ != other) { InternalRelease(); ptr_ = other; InternalAddRef(); } return *this; } ComPtr& operator=(const ComPtr &other) throw() { if (ptr_ != other.ptr_) ComPtr(other).Swap(*this); return *this; } template<class U> ComPtr &operator=(const ComPtr<U> &other) throw() { ComPtr(other).Swap(*this); return *this; } ComPtr& operator=(ComPtr &&other) throw() { ComPtr(other).Swap(*this); return *this; } template<class U> ComPtr& operator=(ComPtr<U> &&other) throw() { ComPtr(other).Swap(*this); return *this; } void Swap(ComPtr &&r) throw() { InterfaceType *tmp = ptr_; ptr_ = r.ptr_; r.ptr_ = tmp; } void Swap(ComPtr &r) throw() { InterfaceType *tmp = ptr_; ptr_ = r.ptr_; r.ptr_ = tmp; } operator Details::BoolType() const throw() { return Get() != nullptr ? &Details::BoolStruct::Member : nullptr; } InterfaceType *Get() const throw() { return ptr_; } InterfaceType *operator->() const throw() { return ptr_; } Details::ComPtrRef<ComPtr<T>> operator&() throw() { return Details::ComPtrRef<ComPtr<T>>(this); } const Details::ComPtrRef<const ComPtr<T>> operator&() const throw() { return Details::ComPtrRef<const ComPtr<T>>(this); } InterfaceType *const *GetAddressOf() const throw() { return &ptr_; } InterfaceType **GetAddressOf() throw() { return &ptr_; } InterfaceType **ReleaseAndGetAddressOf() throw() { InternalRelease(); return &ptr_; } InterfaceType *Detach() throw() { T* ptr = ptr_; ptr_ = nullptr; return ptr; } void Attach(InterfaceType *other) throw() { if (ptr_ != other) { InternalRelease(); ptr_ = other; InternalAddRef(); } } unsigned long Reset() { return InternalRelease(); } HRESULT CopyTo(InterfaceType **ptr) const throw() { InternalAddRef(); *ptr = ptr_; return S_OK; } HRESULT CopyTo(REFIID riid, void **ptr) const throw() { return ptr_->QueryInterface(riid, ptr); } template<typename U> HRESULT CopyTo(U **ptr) const throw() { return ptr_->QueryInterface(__uuidof(U), reinterpret_cast<void**>(ptr)); } template<typename U> HRESULT As(Details::ComPtrRef<ComPtr<U>> p) const throw() { return ptr_->QueryInterface(__uuidof(U), p); } template<typename U> HRESULT As(ComPtr<U> *p) const throw() { return ptr_->QueryInterface(__uuidof(U), reinterpret_cast<void**>(p->ReleaseAndGetAddressOf())); } HRESULT AsIID(REFIID riid, ComPtr<IUnknown> *p) const throw() { return ptr_->QueryInterface(riid, reinterpret_cast<void**>(p->ReleaseAndGetAddressOf())); } /* HRESULT AsWeak(WeakRef *pWeakRef) const throw() { return ::Microsoft::WRL::AsWeak(ptr_, pWeakRef); } */ protected: InterfaceType *ptr_; void InternalAddRef() const throw() { if(ptr_) ptr_->AddRef(); } unsigned long InternalRelease() throw() { InterfaceType *tmp = ptr_; if(!tmp) return 0; ptr_ = nullptr; return tmp->Release(); } }; } } template<typename T> void **IID_PPV_ARGS_Helper(::Microsoft::WRL::Details::ComPtrRef<T> pp) throw() { static_assert(__is_base_of(IUnknown, typename T::InterfaceType), "Expected COM interface"); return pp; } namespace Windows { namespace Foundation { template<typename T> inline HRESULT ActivateInstance(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> instance) throw() { return ActivateInstance(classid, instance.ReleaseAndGetAddressOf()); } template<typename T> inline HRESULT GetActivationFactory(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> factory) throw() { return RoGetActivationFactory(classid, IID_INS_ARGS(factory.ReleaseAndGetAddressOf())); } } } namespace ABI { namespace Windows { namespace Foundation { template<typename T> inline HRESULT ActivateInstance(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> instance) throw() { return ActivateInstance(classid, instance.ReleaseAndGetAddressOf()); } template<typename T> inline HRESULT GetActivationFactory(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> factory) throw() { return RoGetActivationFactory(classid, IID_INS_ARGS(factory.ReleaseAndGetAddressOf())); } } } } #endif