client.h 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /**
  2. * This file has no copyright assigned and is placed in the Public Domain.
  3. * This file is part of the mingw-w64 runtime package.
  4. * No warranty is given; refer to the file DISCLAIMER.PD within this package.
  5. */
  6. #ifndef _WRL_CLIENT_H_
  7. #define _WRL_CLIENT_H_
  8. #include <stddef.h>
  9. #include <unknwn.h>
  10. /* #include <weakreference.h> */
  11. #include <roapi.h>
  12. /* #include <wrl/def.h> */
  13. #include <wrl/internal.h>
  14. namespace Microsoft {
  15. namespace WRL {
  16. namespace Details {
  17. template <typename T> class ComPtrRefBase {
  18. protected:
  19. T* ptr_;
  20. public:
  21. typedef typename T::InterfaceType InterfaceType;
  22. #ifndef __WRL_CLASSIC_COM__
  23. operator IInspectable**() const throw() {
  24. static_assert(__is_base_of(IInspectable, InterfaceType), "Invalid cast");
  25. return reinterpret_cast<IInspectable**>(ptr_->ReleaseAndGetAddressOf());
  26. }
  27. #endif
  28. operator IUnknown**() const throw() {
  29. static_assert(__is_base_of(IUnknown, InterfaceType), "Invalid cast");
  30. return reinterpret_cast<IUnknown**>(ptr_->ReleaseAndGetAddressOf());
  31. }
  32. };
  33. template <typename T> class ComPtrRef : public Details::ComPtrRefBase<T> {
  34. public:
  35. ComPtrRef(T *ptr) throw() {
  36. ComPtrRefBase<T>::ptr_ = ptr;
  37. }
  38. operator void**() const throw() {
  39. return reinterpret_cast<void**>(ComPtrRefBase<T>::ptr_->ReleaseAndGetAddressOf());
  40. }
  41. operator T*() throw() {
  42. *ComPtrRefBase<T>::ptr_ = nullptr;
  43. return ComPtrRefBase<T>::ptr_;
  44. }
  45. operator typename ComPtrRefBase<T>::InterfaceType**() throw() {
  46. return ComPtrRefBase<T>::ptr_->ReleaseAndGetAddressOf();
  47. }
  48. typename ComPtrRefBase<T>::InterfaceType *operator*() throw() {
  49. return ComPtrRefBase<T>::ptr_->Get();
  50. }
  51. typename ComPtrRefBase<T>::InterfaceType *const *GetAddressOf() const throw() {
  52. return ComPtrRefBase<T>::ptr_->GetAddressOf();
  53. }
  54. typename ComPtrRefBase<T>::InterfaceType **ReleaseAndGetAddressOf() throw() {
  55. return ComPtrRefBase<T>::ptr_->ReleaseAndGetAddressOf();
  56. }
  57. };
  58. }
  59. template<typename T> class ComPtr {
  60. public:
  61. typedef T InterfaceType;
  62. ComPtr() throw() : ptr_(nullptr) {}
  63. ComPtr(decltype(nullptr)) throw() : ptr_(nullptr) {}
  64. template<class U> ComPtr(U *other) throw() : ptr_(other) {
  65. InternalAddRef();
  66. }
  67. ComPtr(const ComPtr &other) throw() : ptr_(other.ptr_) {
  68. InternalAddRef();
  69. }
  70. template<class U>
  71. ComPtr(const ComPtr<U> &other) throw() : ptr_(other.Get()) {
  72. InternalAddRef();
  73. }
  74. ComPtr(ComPtr &&other) throw() : ptr_(nullptr) {
  75. if(this != reinterpret_cast<ComPtr*>(&reinterpret_cast<unsigned char&>(other)))
  76. Swap(other);
  77. }
  78. template<class U>
  79. ComPtr(ComPtr<U>&& other) throw() : ptr_(other.Detach()) {}
  80. ~ComPtr() throw() {
  81. InternalRelease();
  82. }
  83. ComPtr &operator=(decltype(nullptr)) throw() {
  84. InternalRelease();
  85. return *this;
  86. }
  87. ComPtr &operator=(InterfaceType *other) throw() {
  88. if (ptr_ != other) {
  89. InternalRelease();
  90. ptr_ = other;
  91. InternalAddRef();
  92. }
  93. return *this;
  94. }
  95. template<typename U>
  96. ComPtr &operator=(U *other) throw() {
  97. if (ptr_ != other) {
  98. InternalRelease();
  99. ptr_ = other;
  100. InternalAddRef();
  101. }
  102. return *this;
  103. }
  104. ComPtr& operator=(const ComPtr &other) throw() {
  105. if (ptr_ != other.ptr_)
  106. ComPtr(other).Swap(*this);
  107. return *this;
  108. }
  109. template<class U>
  110. ComPtr &operator=(const ComPtr<U> &other) throw() {
  111. ComPtr(other).Swap(*this);
  112. return *this;
  113. }
  114. ComPtr& operator=(ComPtr &&other) throw() {
  115. ComPtr(other).Swap(*this);
  116. return *this;
  117. }
  118. template<class U>
  119. ComPtr& operator=(ComPtr<U> &&other) throw() {
  120. ComPtr(other).Swap(*this);
  121. return *this;
  122. }
  123. void Swap(ComPtr &&r) throw() {
  124. InterfaceType *tmp = ptr_;
  125. ptr_ = r.ptr_;
  126. r.ptr_ = tmp;
  127. }
  128. void Swap(ComPtr &r) throw() {
  129. InterfaceType *tmp = ptr_;
  130. ptr_ = r.ptr_;
  131. r.ptr_ = tmp;
  132. }
  133. operator Details::BoolType() const throw() {
  134. return Get() != nullptr ? &Details::BoolStruct::Member : nullptr;
  135. }
  136. InterfaceType *Get() const throw() {
  137. return ptr_;
  138. }
  139. InterfaceType *operator->() const throw() {
  140. return ptr_;
  141. }
  142. Details::ComPtrRef<ComPtr<T>> operator&() throw() {
  143. return Details::ComPtrRef<ComPtr<T>>(this);
  144. }
  145. const Details::ComPtrRef<const ComPtr<T>> operator&() const throw() {
  146. return Details::ComPtrRef<const ComPtr<T>>(this);
  147. }
  148. InterfaceType *const *GetAddressOf() const throw() {
  149. return &ptr_;
  150. }
  151. InterfaceType **GetAddressOf() throw() {
  152. return &ptr_;
  153. }
  154. InterfaceType **ReleaseAndGetAddressOf() throw() {
  155. InternalRelease();
  156. return &ptr_;
  157. }
  158. InterfaceType *Detach() throw() {
  159. T* ptr = ptr_;
  160. ptr_ = nullptr;
  161. return ptr;
  162. }
  163. void Attach(InterfaceType *other) throw() {
  164. if (ptr_ != other) {
  165. InternalRelease();
  166. ptr_ = other;
  167. InternalAddRef();
  168. }
  169. }
  170. unsigned long Reset() {
  171. return InternalRelease();
  172. }
  173. HRESULT CopyTo(InterfaceType **ptr) const throw() {
  174. InternalAddRef();
  175. *ptr = ptr_;
  176. return S_OK;
  177. }
  178. HRESULT CopyTo(REFIID riid, void **ptr) const throw() {
  179. return ptr_->QueryInterface(riid, ptr);
  180. }
  181. template<typename U>
  182. HRESULT CopyTo(U **ptr) const throw() {
  183. return ptr_->QueryInterface(__uuidof(U), reinterpret_cast<void**>(ptr));
  184. }
  185. template<typename U>
  186. HRESULT As(Details::ComPtrRef<ComPtr<U>> p) const throw() {
  187. return ptr_->QueryInterface(__uuidof(U), p);
  188. }
  189. template<typename U>
  190. HRESULT As(ComPtr<U> *p) const throw() {
  191. return ptr_->QueryInterface(__uuidof(U), reinterpret_cast<void**>(p->ReleaseAndGetAddressOf()));
  192. }
  193. HRESULT AsIID(REFIID riid, ComPtr<IUnknown> *p) const throw() {
  194. return ptr_->QueryInterface(riid, reinterpret_cast<void**>(p->ReleaseAndGetAddressOf()));
  195. }
  196. /*
  197. HRESULT AsWeak(WeakRef *pWeakRef) const throw() {
  198. return ::Microsoft::WRL::AsWeak(ptr_, pWeakRef);
  199. }
  200. */
  201. protected:
  202. InterfaceType *ptr_;
  203. void InternalAddRef() const throw() {
  204. if(ptr_)
  205. ptr_->AddRef();
  206. }
  207. unsigned long InternalRelease() throw() {
  208. InterfaceType *tmp = ptr_;
  209. if(!tmp)
  210. return 0;
  211. ptr_ = nullptr;
  212. return tmp->Release();
  213. }
  214. };
  215. }
  216. }
  217. template<typename T>
  218. void **IID_PPV_ARGS_Helper(::Microsoft::WRL::Details::ComPtrRef<T> pp) throw() {
  219. static_assert(__is_base_of(IUnknown, typename T::InterfaceType), "Expected COM interface");
  220. return pp;
  221. }
  222. namespace Windows {
  223. namespace Foundation {
  224. template<typename T>
  225. inline HRESULT ActivateInstance(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> instance) throw() {
  226. return ActivateInstance(classid, instance.ReleaseAndGetAddressOf());
  227. }
  228. template<typename T>
  229. inline HRESULT GetActivationFactory(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> factory) throw() {
  230. return RoGetActivationFactory(classid, IID_INS_ARGS(factory.ReleaseAndGetAddressOf()));
  231. }
  232. }
  233. }
  234. namespace ABI {
  235. namespace Windows {
  236. namespace Foundation {
  237. template<typename T>
  238. inline HRESULT ActivateInstance(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> instance) throw() {
  239. return ActivateInstance(classid, instance.ReleaseAndGetAddressOf());
  240. }
  241. template<typename T>
  242. inline HRESULT GetActivationFactory(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> factory) throw() {
  243. return RoGetActivationFactory(classid, IID_INS_ARGS(factory.ReleaseAndGetAddressOf()));
  244. }
  245. }
  246. }
  247. }
  248. #endif