aboutsummaryrefslogtreecommitdiff
path: root/contrib/DirectX-Headers/include/wsl/wrladapter.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/DirectX-Headers/include/wsl/wrladapter.h')
-rw-r--r--contrib/DirectX-Headers/include/wsl/wrladapter.h801
1 files changed, 801 insertions, 0 deletions
diff --git a/contrib/DirectX-Headers/include/wsl/wrladapter.h b/contrib/DirectX-Headers/include/wsl/wrladapter.h
new file mode 100644
index 0000000..883ecab
--- /dev/null
+++ b/contrib/DirectX-Headers/include/wsl/wrladapter.h
@@ -0,0 +1,801 @@
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#pragma once
5
6#include "winadapter.h"
7
8// defined by winadapter.h and needed by some windows headers, but conflicts
9// with some libc++ implementation headers
10#ifdef __in
11#undef __in
12#endif
13#ifdef __out
14#undef __out
15#endif
16
17#include <type_traits>
18#include <atomic>
19#include <memory>
20#include <climits>
21#include <cassert>
22
23namespace Microsoft
24{
25namespace WRL
26{
27 namespace Details
28 {
29 struct BoolStruct { int Member; };
30 typedef int BoolStruct::* BoolType;
31
32 template <typename T> // T should be the ComPtr<T> or a derived type of it, not just the interface
33 class ComPtrRefBase
34 {
35 public:
36 typedef typename T::InterfaceType InterfaceType;
37
38 operator IUnknown**() const throw()
39 {
40 static_assert(__is_base_of(IUnknown, InterfaceType), "Invalid cast: InterfaceType does not derive from IUnknown");
41 return reinterpret_cast<IUnknown**>(ptr_->ReleaseAndGetAddressOf());
42 }
43
44 protected:
45 T* ptr_;
46 };
47
48 template <typename T>
49 class ComPtrRef : public Details::ComPtrRefBase<T> // T should be the ComPtr<T> or a derived type of it, not just the interface
50 {
51 using Super = Details::ComPtrRefBase<T>;
52 using InterfaceType = typename Super::InterfaceType;
53 public:
54 ComPtrRef(_In_opt_ T* ptr) throw()
55 {
56 this->ptr_ = ptr;
57 }
58
59 // Conversion operators
60 operator void**() const throw()
61 {
62 return reinterpret_cast<void**>(this->ptr_->ReleaseAndGetAddressOf());
63 }
64
65 // This is our operator ComPtr<U> (or the latest derived class from ComPtr (e.g. WeakRef))
66 operator T*() throw()
67 {
68 *this->ptr_ = nullptr;
69 return this->ptr_;
70 }
71
72 // We define operator InterfaceType**() here instead of on ComPtrRefBase<T>, since
73 // if InterfaceType is IUnknown or IInspectable, having it on the base will collide.
74 operator InterfaceType**() throw()
75 {
76 return this->ptr_->ReleaseAndGetAddressOf();
77 }
78
79 // This is used for IID_PPV_ARGS in order to do __uuidof(**(ppType)).
80 // It does not need to clear ptr_ at this point, it is done at IID_PPV_ARGS_Helper(ComPtrRef&) later in this file.
81 InterfaceType* operator *() throw()
82 {
83 return this->ptr_->Get();
84 }
85
86 // Explicit functions
87 InterfaceType* const * GetAddressOf() const throw()
88 {
89 return this->ptr_->GetAddressOf();
90 }
91
92 InterfaceType** ReleaseAndGetAddressOf() throw()
93 {
94 return this->ptr_->ReleaseAndGetAddressOf();
95 }
96 };
97 }
98
99 template <typename T>
100 class ComPtr
101 {
102 public:
103 typedef T InterfaceType;
104
105 protected:
106 InterfaceType *ptr_;
107 template<class U> friend class ComPtr;
108
109 void InternalAddRef() const throw()
110 {
111 if (ptr_ != nullptr)
112 {
113 ptr_->AddRef();
114 }
115 }
116
117 unsigned long InternalRelease() throw()
118 {
119 unsigned long ref = 0;
120 T* temp = ptr_;
121
122 if (temp != nullptr)
123 {
124 ptr_ = nullptr;
125 ref = temp->Release();
126 }
127
128 return ref;
129 }
130
131 public:
132 ComPtr() throw() : ptr_(nullptr)
133 {
134 }
135
136 ComPtr(decltype(nullptr)) throw() : ptr_(nullptr)
137 {
138 }
139
140 template<class U>
141 ComPtr(_In_opt_ U *other) throw() : ptr_(other)
142 {
143 InternalAddRef();
144 }
145
146 ComPtr(const ComPtr& other) throw() : ptr_(other.ptr_)
147 {
148 InternalAddRef();
149 }
150
151 // copy constructor that allows to instantiate class when U* is convertible to T*
152 template<class U>
153 ComPtr(const ComPtr<U> &other, typename std::enable_if<std::is_convertible<U*, T*>::value, void *>::type * = 0) throw() :
154 ptr_(other.ptr_)
155 {
156 InternalAddRef();
157 }
158
159 ComPtr(_Inout_ ComPtr &&other) throw() : ptr_(nullptr)
160 {
161 if (this != reinterpret_cast<ComPtr*>(&reinterpret_cast<unsigned char&>(other)))
162 {
163 Swap(other);
164 }
165 }
166
167 // Move constructor that allows instantiation of a class when U* is convertible to T*
168 template<class U>
169 ComPtr(_Inout_ ComPtr<U>&& other, typename std::enable_if<std::is_convertible<U*, T*>::value, void *>::type * = 0) throw() :
170 ptr_(other.ptr_)
171 {
172 other.ptr_ = nullptr;
173 }
174
175 ~ComPtr() throw()
176 {
177 InternalRelease();
178 }
179
180 ComPtr& operator=(decltype(nullptr)) throw()
181 {
182 InternalRelease();
183 return *this;
184 }
185
186 ComPtr& operator=(_In_opt_ T *other) throw()
187 {
188 if (ptr_ != other)
189 {
190 ComPtr(other).Swap(*this);
191 }
192 return *this;
193 }
194
195 template <typename U>
196 ComPtr& operator=(_In_opt_ U *other) throw()
197 {
198 ComPtr(other).Swap(*this);
199 return *this;
200 }
201
202 ComPtr& operator=(const ComPtr &other) throw()
203 {
204 if (ptr_ != other.ptr_)
205 {
206 ComPtr(other).Swap(*this);
207 }
208 return *this;
209 }
210
211 template<class U>
212 ComPtr& operator=(const ComPtr<U>& other) throw()
213 {
214 ComPtr(other).Swap(*this);
215 return *this;
216 }
217
218 ComPtr& operator=(_Inout_ ComPtr &&other) throw()
219 {
220 ComPtr(static_cast<ComPtr&&>(other)).Swap(*this);
221 return *this;
222 }
223
224 template<class U>
225 ComPtr& operator=(_Inout_ ComPtr<U>&& other) throw()
226 {
227 ComPtr(static_cast<ComPtr<U>&&>(other)).Swap(*this);
228 return *this;
229 }
230
231 void Swap(_Inout_ ComPtr&& r) throw()
232 {
233 T* tmp = ptr_;
234 ptr_ = r.ptr_;
235 r.ptr_ = tmp;
236 }
237
238 void Swap(_Inout_ ComPtr& r) throw()
239 {
240 T* tmp = ptr_;
241 ptr_ = r.ptr_;
242 r.ptr_ = tmp;
243 }
244
245 operator Details::BoolType() const throw()
246 {
247 return Get() != nullptr ? &Details::BoolStruct::Member : nullptr;
248 }
249
250 T* Get() const throw()
251 {
252 return ptr_;
253 }
254
255 InterfaceType* operator->() const throw()
256 {
257 return ptr_;
258 }
259
260 Details::ComPtrRef<ComPtr<T>> operator&() throw()
261 {
262 return Details::ComPtrRef<ComPtr<T>>(this);
263 }
264
265 const Details::ComPtrRef<const ComPtr<T>> operator&() const throw()
266 {
267 return Details::ComPtrRef<const ComPtr<T>>(this);
268 }
269
270 T* const* GetAddressOf() const throw()
271 {
272 return &ptr_;
273 }
274
275 T** GetAddressOf() throw()
276 {
277 return &ptr_;
278 }
279
280 T** ReleaseAndGetAddressOf() throw()
281 {
282 InternalRelease();
283 return &ptr_;
284 }
285
286 T* Detach() throw()
287 {
288 T* ptr = ptr_;
289 ptr_ = nullptr;
290 return ptr;
291 }
292
293 void Attach(_In_opt_ InterfaceType* other) throw()
294 {
295 if (ptr_ != nullptr)
296 {
297 auto ref = ptr_->Release();
298 // DBG_UNREFERENCED_LOCAL_VARIABLE(ref);
299 // Attaching to the same object only works if duplicate references are being coalesced. Otherwise
300 // re-attaching will cause the pointer to be released and may cause a crash on a subsequent dereference.
301 assert(ref != 0 || ptr_ != other);
302 }
303
304 ptr_ = other;
305 }
306
307 unsigned long Reset()
308 {
309 return InternalRelease();
310 }
311
312 // Previously, unsafe behavior could be triggered when 'this' is ComPtr<IInspectable> or ComPtr<IUnknown> and CopyTo is used to copy to another type U.
313 // The user will use operator& to convert the destination into a ComPtrRef, which can then implicit cast to IInspectable** and IUnknown**.
314 // If this overload of CopyTo is not present, it will implicitly cast to IInspectable or IUnknown and match CopyTo(InterfaceType**) instead.
315 // A valid polymoprhic downcast requires run-time type checking via QueryInterface, so CopyTo(InterfaceType**) will break type safety.
316 // This overload matches ComPtrRef before the implicit cast takes place, preventing the unsafe downcast.
317 template <typename U>
318 HRESULT CopyTo(Details::ComPtrRef<ComPtr<U>> ptr, typename std::enable_if<
319 (std::is_same<T, IUnknown>::value)
320 && !std::is_same<U*, T*>::value, void *>::type * = 0) const throw()
321 {
322 return ptr_->QueryInterface(uuidof<U>(), ptr);
323 }
324
325 HRESULT CopyTo(_Outptr_result_maybenull_ InterfaceType** ptr) const throw()
326 {
327 InternalAddRef();
328 *ptr = ptr_;
329 return S_OK;
330 }
331
332 HRESULT CopyTo(REFIID riid, _Outptr_result_nullonfailure_ void** ptr) const throw()
333 {
334 return ptr_->QueryInterface(riid, ptr);
335 }
336
337 template<typename U>
338 HRESULT CopyTo(_Outptr_result_nullonfailure_ U** ptr) const throw()
339 {
340 return ptr_->QueryInterface(uuidof<U>(), reinterpret_cast<void**>(ptr));
341 }
342
343 // query for U interface
344 template<typename U>
345 HRESULT As(_Inout_ Details::ComPtrRef<ComPtr<U>> p) const throw()
346 {
347 return ptr_->QueryInterface(uuidof<U>(), p);
348 }
349
350 // query for U interface
351 template<typename U>
352 HRESULT As(_Out_ ComPtr<U>* p) const throw()
353 {
354 return ptr_->QueryInterface(uuidof<U>(), reinterpret_cast<void**>(p->ReleaseAndGetAddressOf()));
355 }
356
357 // query for riid interface and return as IUnknown
358 HRESULT AsIID(REFIID riid, _Out_ ComPtr<IUnknown>* p) const throw()
359 {
360 return ptr_->QueryInterface(riid, reinterpret_cast<void**>(p->ReleaseAndGetAddressOf()));
361 }
362
363 }; // ComPtr
364
365
366 namespace Details
367 {
368 // Empty struct used as default template parameter
369 class Nil
370 {
371 };
372
373 // Empty struct used for validating template parameter types in Implements
374 struct ImplementsBase
375 {
376 };
377
378 class RuntimeClassBase
379 {
380 protected:
381 template<typename T>
382 static HRESULT AsIID(_In_ T* implements, REFIID riid, _Outptr_result_nullonfailure_ void **ppvObject) noexcept
383 {
384 *ppvObject = nullptr;
385 bool isRefDelegated = false;
386 // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is almost always the case.
387 if (InlineIsEqualGUID(riid, uuidof<IUnknown>()))
388 {
389 *ppvObject = implements->CastToUnknown();
390 static_cast<IUnknown*>(*ppvObject)->AddRef();
391 return S_OK;
392 }
393
394 HRESULT hr = implements->CanCastTo(riid, ppvObject, &isRefDelegated);
395 if (SUCCEEDED(hr) && !isRefDelegated)
396 {
397 static_cast<IUnknown*>(*ppvObject)->AddRef();
398 }
399
400#ifdef _MSC_VER
401#pragma warning(push)
402#pragma warning(disable: 6102) // '*ppvObject' is used but may not be initialized
403#endif
404 _Analysis_assume_(SUCCEEDED(hr) || (*ppvObject == nullptr));
405#ifdef _MSC_VER
406#pragma warning(pop)
407#endif
408 return hr;
409 }
410
411 public:
412 HRESULT RuntimeClassInitialize() noexcept
413 {
414 return S_OK;
415 }
416 };
417
418 // Interface traits provides casting and filling iids methods helpers
419 template<typename I0>
420 struct InterfaceTraits
421 {
422 typedef I0 Base;
423
424 template<typename T>
425 static Base* CastToBase(_In_ T* ptr) noexcept
426 {
427 return static_cast<Base*>(ptr);
428 }
429
430 template<typename T>
431 static IUnknown* CastToUnknown(_In_ T* ptr) noexcept
432 {
433 return static_cast<IUnknown*>(static_cast<Base*>(ptr));
434 }
435
436 template <typename T>
437 _Success_(return == true)
438 static bool CanCastTo(_In_ T* ptr, REFIID riid, _Outptr_ void **ppv) noexcept
439 {
440 // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is almost always the case.
441 if (InlineIsEqualGUID(riid, uuidof<Base>()))
442 {
443 *ppv = static_cast<Base*>(ptr);
444 return true;
445 }
446
447 return false;
448 }
449 };
450
451 // Specialization for Nil parameter
452 template<>
453 struct InterfaceTraits<Nil>
454 {
455 typedef Nil Base;
456
457 template <typename T>
458 _Success_(return == true)
459 static bool CanCastTo(_In_ T*, REFIID, _Outptr_ void **) noexcept
460 {
461 return false;
462 }
463 };
464
465 // ChainInterfaces - template allows specifying a derived COM interface along with its class hierarchy to allow QI for the base interfaces
466 template <typename I0, typename I1, typename I2 = Nil, typename I3 = Nil,
467 typename I4 = Nil, typename I5 = Nil, typename I6 = Nil,
468 typename I7 = Nil, typename I8 = Nil, typename I9 = Nil>
469 struct ChainInterfaces : I0
470 {
471 protected:
472 HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv) throw()
473 {
474 typename InterfaceTraits<I0>::Base* ptr = InterfaceTraits<I0>::CastToBase(this);
475
476 return (InterfaceTraits<I0>::CanCastTo(this, riid, ppv) ||
477 InterfaceTraits<I1>::CanCastTo(ptr, riid, ppv) ||
478 InterfaceTraits<I2>::CanCastTo(ptr, riid, ppv) ||
479 InterfaceTraits<I3>::CanCastTo(ptr, riid, ppv) ||
480 InterfaceTraits<I4>::CanCastTo(ptr, riid, ppv) ||
481 InterfaceTraits<I5>::CanCastTo(ptr, riid, ppv) ||
482 InterfaceTraits<I6>::CanCastTo(ptr, riid, ppv) ||
483 InterfaceTraits<I7>::CanCastTo(ptr, riid, ppv) ||
484 InterfaceTraits<I8>::CanCastTo(ptr, riid, ppv) ||
485 InterfaceTraits<I9>::CanCastTo(ptr, riid, ppv)) ? S_OK : E_NOINTERFACE;
486 }
487
488 IUnknown* CastToUnknown() throw()
489 {
490 return InterfaceTraits<I0>::CastToUnknown(this);
491 }
492 };
493
494 // Helper template used by Implements. This template traverses a list of interfaces and adds them as base class and information
495 // to enable QI.
496 template <typename ...TInterfaces>
497 struct ImplementsHelper;
498
499 template <typename T>
500 struct ImplementsMarker
501 {};
502
503 template <typename I0, bool isImplements>
504 struct MarkImplements;
505
506 template <typename I0>
507 struct MarkImplements<I0, false>
508 {
509 typedef I0 Type;
510 };
511
512 template <typename I0>
513 struct MarkImplements<I0, true>
514 {
515 typedef ImplementsMarker<I0> Type;
516 };
517
518 // AdjustImplements pre-processes the type list for more efficient builds.
519 template <typename ...Bases>
520 struct AdjustImplements;
521
522 template <typename I0, typename ...Bases>
523 struct AdjustImplements<I0, Bases...>
524 {
525 typedef ImplementsHelper<typename MarkImplements<I0, std::is_base_of<ImplementsBase, I0>::value>::Type, Bases...> Type;
526 };
527
528 // Use AdjustImplements to remove instances of "Nil" from the type list.
529 template <typename ...Bases>
530 struct AdjustImplements<Nil, Bases...>
531 {
532 typedef typename AdjustImplements<Bases...>::Type Type;
533 };
534
535 template <>
536 struct AdjustImplements<>
537 {
538 typedef ImplementsHelper<> Type;
539 };
540
541 // Specialization handles unadorned interfaces
542 template <typename I0, typename ...TInterfaces>
543 struct ImplementsHelper<I0, TInterfaces...> :
544 I0,
545 AdjustImplements<TInterfaces...>::Type
546 {
547 template <typename ...> friend struct ImplementsHelper;
548 friend class RuntimeClassBase;
549
550 protected:
551
552 HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) noexcept
553 {
554 // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is almost always the case.
555 if (InlineIsEqualGUID(riid, uuidof<I0>()))
556 {
557 *ppv = reinterpret_cast<I0*>(reinterpret_cast<void*>(this));
558 return S_OK;
559 }
560 return AdjustImplements<TInterfaces...>::Type::CanCastTo(riid, ppv, pRefDelegated);
561 }
562
563 IUnknown* CastToUnknown() noexcept
564 {
565 return reinterpret_cast<I0*>(reinterpret_cast<void*>(this));
566 }
567 };
568
569
570 // Selector is used to "tag" base interfaces to be used in casting, since a runtime class may indirectly derive from
571 // the same interface or Implements<> template multiple times
572 template <typename base, typename disciminator>
573 struct Selector : public base
574 {
575 };
576
577 // Specialization handles types that derive from ImplementsHelper (e.g. nested Implements).
578 template <typename I0, typename ...TInterfaces>
579 struct ImplementsHelper<ImplementsMarker<I0>, TInterfaces...> :
580 Selector<I0, ImplementsHelper<ImplementsMarker<I0>, TInterfaces...>>,
581 Selector<typename AdjustImplements<TInterfaces...>::Type, ImplementsHelper<ImplementsMarker<I0>, TInterfaces...>>
582 {
583 template <typename ...> friend struct ImplementsHelper;
584 friend class RuntimeClassBase;
585
586 protected:
587 typedef Selector<I0, ImplementsHelper<ImplementsMarker<I0>, TInterfaces...>> CurrentType;
588 typedef Selector<typename AdjustImplements<TInterfaces...>::Type, ImplementsHelper<ImplementsMarker<I0>, TInterfaces...>> BaseType;
589
590 HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) noexcept
591 {
592 HRESULT hr = CurrentType::CanCastTo(riid, ppv);
593 if (hr == E_NOINTERFACE)
594 {
595 hr = BaseType::CanCastTo(riid, ppv, pRefDelegated);
596 }
597 return hr;
598 }
599
600 IUnknown* CastToUnknown() noexcept
601 {
602 // First in list wins.
603 return CurrentType::CastToUnknown();
604 }
605 };
606
607 // terminal case specialization.
608 template <>
609 struct ImplementsHelper<>
610 {
611 template <typename ...> friend struct ImplementsHelper;
612 friend class RuntimeClassBase;
613
614 protected:
615 HRESULT CanCastTo(_In_ REFIID /*riid*/, _Outptr_ void ** /*ppv*/, bool * /*pRefDelegated*/ = nullptr) noexcept
616 {
617 return E_NOINTERFACE;
618 }
619
620 // IUnknown* CastToUnknown() noexcept; // not defined for terminal case.
621 };
622
623 // Specialization handles chaining interfaces
624 template <typename C0, typename C1, typename C2, typename C3, typename C4, typename C5, typename C6, typename C7, typename C8, typename C9, typename ...TInterfaces>
625 struct ImplementsHelper<ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>, TInterfaces...> :
626 ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>,
627 AdjustImplements<TInterfaces...>::Type
628 {
629 template <typename ...> friend struct ImplementsHelper;
630 friend class RuntimeClassBase;
631
632 protected:
633 typedef typename AdjustImplements<TInterfaces...>::Type BaseType;
634
635 HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) noexcept
636 {
637 HRESULT hr = ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>::CanCastTo(riid, ppv);
638 if (FAILED(hr))
639 {
640 hr = BaseType::CanCastTo(riid, ppv, pRefDelegated);
641 }
642
643 return hr;
644 }
645
646 IUnknown* CastToUnknown() noexcept
647 {
648 return ChainInterfaces<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>::CastToUnknown();
649 }
650 };
651
652 // Implements - template implementing QI using the information provided through its template parameters
653 // Each template parameter has to be one of the following:
654 // * COM Interface
655 // * A class that implements one or more COM interfaces
656 // * ChainInterfaces template
657 template <typename I0, typename ...TInterfaces>
658 struct Implements :
659 AdjustImplements<I0, TInterfaces...>::Type,
660 ImplementsBase
661 {
662 public:
663 typedef I0 FirstInterface;
664 protected:
665 typedef typename AdjustImplements<I0, TInterfaces...>::Type BaseType;
666 template <typename ...> friend struct ImplementsHelper;
667 friend class RuntimeClassBase;
668
669 HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv) noexcept
670 {
671 return BaseType::CanCastTo(riid, ppv);
672 }
673
674 IUnknown* CastToUnknown() noexcept
675 {
676 return BaseType::CastToUnknown();
677 }
678 };
679
680 // Used on RuntimeClass to protect it from being constructed with new
681 class DontUseNewUseMake
682 {
683 private:
684 void* operator new(size_t) noexcept
685 {
686 assert(false);
687 return 0;
688 }
689
690 public:
691 void* operator new(size_t, _In_ void* placement) noexcept
692 {
693 return placement;
694 }
695 };
696
697 template <typename ...TInterfaces>
698 class RuntimeClassImpl :
699 public AdjustImplements<TInterfaces...>::Type,
700 public RuntimeClassBase,
701 public DontUseNewUseMake
702 {
703 public:
704 STDMETHOD(QueryInterface)(REFIID riid, _Outptr_result_nullonfailure_ void **ppvObject)
705 {
706 return Super::AsIID(this, riid, ppvObject);
707 }
708
709 STDMETHOD_(ULONG, AddRef)()
710 {
711 return InternalAddRef();
712 }
713
714 STDMETHOD_(ULONG, Release)()
715 {
716 ULONG ref = InternalRelease();
717 if (ref == 0)
718 {
719 delete this;
720 }
721
722 return ref;
723 }
724
725 protected:
726 using Super = RuntimeClassBase;
727 static const LONG c_lProtectDestruction = -(LONG_MAX / 2);
728
729 RuntimeClassImpl() noexcept = default;
730
731 virtual ~RuntimeClassImpl() noexcept
732 {
733 // Set refcount_ to -(LONG_MAX/2) to protect destruction and
734 // also catch mismatched Release in debug builds
735 refcount_ = static_cast<ULONG>(c_lProtectDestruction);
736 }
737
738 ULONG InternalAddRef() noexcept
739 {
740 return ++refcount_;
741 }
742
743 ULONG InternalRelease() noexcept
744 {
745 return --refcount_;
746 }
747
748 unsigned long GetRefCount() const noexcept
749 {
750 return refcount_;
751 }
752
753 std::atomic<ULONG> refcount_{1};
754 };
755 }
756
757 template <typename ...TInterfaces>
758 class Base : public Details::RuntimeClassImpl<TInterfaces...>
759 {
760 Base(const Base&) = delete;
761 Base& operator=(const Base&) = delete;
762
763 protected:
764 HRESULT CustomQueryInterface(REFIID /*riid*/, _Outptr_result_nullonfailure_ void** /*ppvObject*/, _Out_ bool *handled)
765 {
766 *handled = false;
767 return S_OK;
768 }
769
770 public:
771 Base() throw() = default;
772 typedef Base RuntimeClassT;
773 };
774
775 // Creates a Nano-COM object wrapped in a smart pointer.
776 template <typename T, typename ...TArgs>
777 ComPtr<T> Make(TArgs&&... args)
778 {
779 ComPtr<T> object;
780
781 std::unique_ptr<unsigned char[]> buffer(new unsigned char[sizeof(T)]);
782 if (buffer)
783 {
784 T* ptr = new (buffer.get())T(std::forward<TArgs>(args)...);
785 object.Attach(ptr);
786 buffer.release();
787 }
788
789 return object;
790 }
791
792 using Details::ChainInterfaces;
793}
794}
795
796// Overloaded global function to provide to IID_PPV_ARGS that support Details::ComPtrRef
797template<typename T>
798void** IID_PPV_ARGS_Helper(Microsoft::WRL::Details::ComPtrRef<T> pp) throw()
799{
800 return pp;
801} \ No newline at end of file