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