|  | /** | 
|  | * 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.Get()) { | 
|  | 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.Detach()) {} | 
|  |  | 
|  | ~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 |