From 6c8ae19be66cee247980a48e736a4e05d14de179 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Tue, 2 Dec 2025 16:39:36 -0800 Subject: Immediate-mode renderer, triangle demo, shader compilation in cmake, Agility SDK --- contrib/DirectX-Headers/include/wsl/stubs/OAIdl.h | 5 - contrib/DirectX-Headers/include/wsl/stubs/OCIdl.h | 5 - contrib/DirectX-Headers/include/wsl/stubs/rpc.h | 5 - contrib/DirectX-Headers/include/wsl/stubs/rpcndr.h | 6 - .../include/wsl/stubs/winapifamily.h | 6 - .../DirectX-Headers/include/wsl/stubs/wrl/client.h | 6 - .../include/wsl/stubs/wrl/implements.h | 6 - contrib/DirectX-Headers/include/wsl/winadapter.h | 340 --------- contrib/DirectX-Headers/include/wsl/wrladapter.h | 801 --------------------- 9 files changed, 1180 deletions(-) delete mode 100644 contrib/DirectX-Headers/include/wsl/stubs/OAIdl.h delete mode 100644 contrib/DirectX-Headers/include/wsl/stubs/OCIdl.h delete mode 100644 contrib/DirectX-Headers/include/wsl/stubs/rpc.h delete mode 100644 contrib/DirectX-Headers/include/wsl/stubs/rpcndr.h delete mode 100644 contrib/DirectX-Headers/include/wsl/stubs/winapifamily.h delete mode 100644 contrib/DirectX-Headers/include/wsl/stubs/wrl/client.h delete mode 100644 contrib/DirectX-Headers/include/wsl/stubs/wrl/implements.h delete mode 100644 contrib/DirectX-Headers/include/wsl/winadapter.h delete mode 100644 contrib/DirectX-Headers/include/wsl/wrladapter.h (limited to 'contrib/DirectX-Headers/include/wsl') diff --git a/contrib/DirectX-Headers/include/wsl/stubs/OAIdl.h b/contrib/DirectX-Headers/include/wsl/stubs/OAIdl.h deleted file mode 100644 index 76f5b5f..0000000 --- a/contrib/DirectX-Headers/include/wsl/stubs/OAIdl.h +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -// Stub header to satisfy d3d12.h include -#pragma once \ No newline at end of file diff --git a/contrib/DirectX-Headers/include/wsl/stubs/OCIdl.h b/contrib/DirectX-Headers/include/wsl/stubs/OCIdl.h deleted file mode 100644 index 76f5b5f..0000000 --- a/contrib/DirectX-Headers/include/wsl/stubs/OCIdl.h +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -// Stub header to satisfy d3d12.h include -#pragma once \ No newline at end of file diff --git a/contrib/DirectX-Headers/include/wsl/stubs/rpc.h b/contrib/DirectX-Headers/include/wsl/stubs/rpc.h deleted file mode 100644 index 76f5b5f..0000000 --- a/contrib/DirectX-Headers/include/wsl/stubs/rpc.h +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -// Stub header to satisfy d3d12.h include -#pragma once \ No newline at end of file diff --git a/contrib/DirectX-Headers/include/wsl/stubs/rpcndr.h b/contrib/DirectX-Headers/include/wsl/stubs/rpcndr.h deleted file mode 100644 index 5b5f2e8..0000000 --- a/contrib/DirectX-Headers/include/wsl/stubs/rpcndr.h +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -// Stub header to satisfy d3d12.h include -#pragma once -#define __RPCNDR_H_VERSION__ \ No newline at end of file diff --git a/contrib/DirectX-Headers/include/wsl/stubs/winapifamily.h b/contrib/DirectX-Headers/include/wsl/stubs/winapifamily.h deleted file mode 100644 index 064c4c2..0000000 --- a/contrib/DirectX-Headers/include/wsl/stubs/winapifamily.h +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -// Stub header to satisfy d3d12.h include. Unconditionally light up all APIs. -#pragma once -#define WINAPI_FAMILY_PARTITION(Partitions) 1 \ No newline at end of file diff --git a/contrib/DirectX-Headers/include/wsl/stubs/wrl/client.h b/contrib/DirectX-Headers/include/wsl/stubs/wrl/client.h deleted file mode 100644 index 43e7d0b..0000000 --- a/contrib/DirectX-Headers/include/wsl/stubs/wrl/client.h +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -// Stub to satisfy d3dx12.h include -#pragma once -#include "../wrladapter.h" \ No newline at end of file diff --git a/contrib/DirectX-Headers/include/wsl/stubs/wrl/implements.h b/contrib/DirectX-Headers/include/wsl/stubs/wrl/implements.h deleted file mode 100644 index fb2bebc..0000000 --- a/contrib/DirectX-Headers/include/wsl/stubs/wrl/implements.h +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -// Stub to satisfy DML TF runtime includes -#pragma once -#include "wrladapter.h" \ No newline at end of file diff --git a/contrib/DirectX-Headers/include/wsl/winadapter.h b/contrib/DirectX-Headers/include/wsl/winadapter.h deleted file mode 100644 index 8400f4a..0000000 --- a/contrib/DirectX-Headers/include/wsl/winadapter.h +++ /dev/null @@ -1,340 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#pragma once - -// These #defines prevent the idl-generated headers from trying to include -// Windows.h from the SDK rather than this one. -#define RPC_NO_WINDOWS_H -#define COM_NO_WINDOWS_H - -// Allcaps type definitions -#include -#include -#include -#include - -// Note: using fixed-width here to match Windows widths -// Specifically this is different for 'long' vs 'LONG' -typedef uint8_t UINT8; -typedef int8_t INT8; -typedef uint16_t UINT16; -typedef int16_t INT16; -typedef uint32_t UINT32, UINT, ULONG, DWORD, BOOL; -typedef int32_t INT32, INT, LONG; -typedef uint64_t UINT64, ULONG_PTR; -typedef int64_t INT64, LONG_PTR; -typedef void VOID, *HANDLE, *RPC_IF_HANDLE, *LPVOID; -typedef const void *LPCVOID; -typedef size_t SIZE_T; -typedef float FLOAT; -typedef double DOUBLE; -typedef unsigned char BYTE; -typedef int HWND; - -// Note: WCHAR is not the same between Windows and Linux, to enable -// string manipulation APIs to work with resulting strings. -// APIs to D3D/DXCore will work on Linux wchars, but beware with -// interactions directly with the Windows kernel. -typedef char CHAR, *PSTR, *LPSTR, TCHAR, *PTSTR; -typedef const char *LPCSTR, *PCSTR, *LPCTSTR, *PCTSTR; -typedef wchar_t WCHAR, *PWSTR, *LPWSTR, *PWCHAR; -typedef const wchar_t *LPCWSTR, *PCWSTR; - -#undef LONG_MAX -#define LONG_MAX INT_MAX -#undef ULONG_MAX -#define ULONG_MAX UINT_MAX - -// Misc defines -#define interface struct -#define MIDL_INTERFACE(x) interface -#define __analysis_assume(x) -#define TRUE 1u -#define FALSE 0u -#define DECLARE_INTERFACE(iface) interface iface -#define PURE = 0 -#define THIS_ -#define DECLSPEC_UUID(x) -#define DECLSPEC_NOVTABLE -#define DECLSPEC_SELECTANY -#define EXTERN_C extern "C" - -typedef struct _GUID { - uint32_t Data1; - uint16_t Data2; - uint16_t Data3; - uint8_t Data4[ 8 ]; -} GUID; - -#ifdef __cplusplus -#ifdef INITGUID -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) extern "C" const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } -#else -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) extern "C" const GUID name -#endif - -template GUID uuidof() = delete; -template GUID uuidof(T*) { return uuidof(); } -template GUID uuidof(T**) { return uuidof(); } -template GUID uuidof(T&) { return uuidof(); } -#define __uuidof(x) uuidof(x) -#else -#ifdef INITGUID -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } -#else -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) extern const GUID name -#endif -#endif - -typedef GUID IID; -typedef GUID UUID; -typedef GUID CLSID; -#ifdef __cplusplus -#define REFGUID const GUID & -#define REFIID const IID & -#define REFCLSID const IID & - -__inline int InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2) -{ - return ( - ((uint32_t *)&rguid1)[0] == ((uint32_t *)&rguid2)[0] && - ((uint32_t *)&rguid1)[1] == ((uint32_t *)&rguid2)[1] && - ((uint32_t *)&rguid1)[2] == ((uint32_t *)&rguid2)[2] && - ((uint32_t *)&rguid1)[3] == ((uint32_t *)&rguid2)[3]); -} -#else -#define REFGUID const GUID * -#define REFIID const IID * -#define REFCLSID const IID * -#endif - -// SAL annotations -#define _In_ -#define _In_z_ -#define _In_opt_ -#define _In_opt_z_ -#define _In_reads_(x) -#define _In_reads_opt_(x) -#define _In_reads_bytes_(x) -#define _In_reads_bytes_opt_(x) -#define _In_range_(x, y) -#define _In_bytecount_(x) -#define _Out_ -#define _Out_opt_ -#define _Outptr_ -#define _Outptr_opt_result_z_ -#define _Outptr_opt_result_bytebuffer_(x) -#define _COM_Outptr_ -#define _COM_Outptr_result_maybenull_ -#define _COM_Outptr_opt_ -#define _COM_Outptr_opt_result_maybenull_ -#define _Out_writes_(x) -#define _Out_writes_z_(x) -#define _Out_writes_opt_(x) -#define _Out_writes_all_(x) -#define _Out_writes_all_opt_(x) -#define _Out_writes_to_opt_(x, y) -#define _Out_writes_bytes_(x) -#define _Out_writes_bytes_all_(x) -#define _Out_writes_bytes_all_opt_(x) -#define _Out_writes_bytes_opt_(x) -#define _Inout_ -#define _Inout_opt_ -#define _Inout_updates_(x) -#define _Inout_updates_bytes_(x) -#define _Field_size_(x) -#define _Field_size_opt_(x) -#define _Field_size_bytes_(x) -#define _Field_size_full_(x) -#define _Field_size_bytes_full_(x) -#define _Field_size_bytes_full_opt_(x) -#define _Field_size_bytes_part_(x, y) -#define _Field_range_(x, y) -#define _Field_z_ -#define _Check_return_ -#define _IRQL_requires_(x) -#define _IRQL_requires_min_(x) -#define _IRQL_requires_max_(x) -#define _At_(x, y) -#define _Always_(x) -#define _Return_type_success_(x) -#define _Translates_Win32_to_HRESULT_(x) -#define _Maybenull_ -#define _Outptr_result_maybenull_ -#define _Outptr_result_nullonfailure_ -#define _Analysis_assume_(x) -#define _Success_(x) -#define _In_count_(x) -#define _In_opt_count_(x) -#define _Use_decl_annotations_ - -// Calling conventions -#define __cdecl -#define __stdcall -#define STDMETHODCALLTYPE -#define STDAPICALLTYPE -#define STDAPI extern "C" HRESULT STDAPICALLTYPE -#define WINAPI -#define STDMETHOD(name) virtual HRESULT name -#define STDMETHOD_(type,name) virtual type name -#define IFACEMETHOD(method) /*__override*/ STDMETHOD(method) -#define IFACEMETHOD_(type, method) /*__override*/ STDMETHOD_(type, method) - -// Error codes -typedef LONG HRESULT; -#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) -#define FAILED(hr) (((HRESULT)(hr)) < 0) -#define S_OK ((HRESULT)0L) -#define S_FALSE ((HRESULT)1L) -#define E_NOTIMPL ((HRESULT)0x80000001L) -#define E_OUTOFMEMORY ((HRESULT)0x80000002L) -#define E_INVALIDARG ((HRESULT)0x80000003L) -#define E_NOINTERFACE ((HRESULT)0x80000004L) -#define E_POINTER ((HRESULT)0x80000005L) -#define E_HANDLE ((HRESULT)0x80000006L) -#define E_ABORT ((HRESULT)0x80000007L) -#define E_FAIL ((HRESULT)0x80000008L) -#define E_ACCESSDENIED ((HRESULT)0x80000009L) -#define E_UNEXPECTED ((HRESULT)0x8000FFFFL) -#define DXGI_ERROR_DEVICE_HUNG ((HRESULT)0x887A0006L) -#define DXGI_ERROR_DEVICE_REMOVED ((HRESULT)0x887A0005L) -#define DXGI_ERROR_DEVICE_RESET ((HRESULT)0x887A0007L) -#define DXGI_ERROR_DRIVER_INTERNAL_ERROR ((HRESULT)0x887A0020L) -#define DXGI_ERROR_INVALID_CALL ((HRESULT)0x887A0001L) - -typedef struct _LUID -{ - ULONG LowPart; - LONG HighPart; -} LUID; - -struct RECT -{ - int left; - int top; - int right; - int bottom; -}; - -typedef union _LARGE_INTEGER { - struct { - uint32_t LowPart; - uint32_t HighPart; - } u; - int64_t QuadPart; -} LARGE_INTEGER; - -typedef union _ULARGE_INTEGER { - struct { - uint32_t LowPart; - uint32_t HighPart; - } u; - uint64_t QuadPart; -} ULARGE_INTEGER; - -struct SECURITY_ATTRIBUTES; -struct STATSTG; - -#ifdef __cplusplus -// ENUM_FLAG_OPERATORS -// Define operator overloads to enable bit operations on enum values that are -// used to define flags. Use DEFINE_ENUM_FLAG_OPERATORS(YOUR_TYPE) to enable these -// operators on YOUR_TYPE. -extern "C++" { - template - struct _ENUM_FLAG_INTEGER_FOR_SIZE; - - template <> - struct _ENUM_FLAG_INTEGER_FOR_SIZE<1> - { - typedef int8_t type; - }; - - template <> - struct _ENUM_FLAG_INTEGER_FOR_SIZE<2> - { - typedef int16_t type; - }; - - template <> - struct _ENUM_FLAG_INTEGER_FOR_SIZE<4> - { - typedef int32_t type; - }; - - template <> - struct _ENUM_FLAG_INTEGER_FOR_SIZE<8> - { - typedef int64_t type; - }; - - // used as an approximation of std::underlying_type - template - struct _ENUM_FLAG_SIZED_INTEGER - { - typedef typename _ENUM_FLAG_INTEGER_FOR_SIZE::type type; - }; - -} -#define DEFINE_ENUM_FLAG_OPERATORS(ENUMTYPE) \ -extern "C++" { \ -inline constexpr ENUMTYPE operator | (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((_ENUM_FLAG_SIZED_INTEGER::type)a) | ((_ENUM_FLAG_SIZED_INTEGER::type)b)); } \ -inline ENUMTYPE &operator |= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((_ENUM_FLAG_SIZED_INTEGER::type &)a) |= ((_ENUM_FLAG_SIZED_INTEGER::type)b)); } \ -inline constexpr ENUMTYPE operator & (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((_ENUM_FLAG_SIZED_INTEGER::type)a) & ((_ENUM_FLAG_SIZED_INTEGER::type)b)); } \ -inline ENUMTYPE &operator &= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((_ENUM_FLAG_SIZED_INTEGER::type &)a) &= ((_ENUM_FLAG_SIZED_INTEGER::type)b)); } \ -inline constexpr ENUMTYPE operator ~ (ENUMTYPE a) { return ENUMTYPE(~((_ENUM_FLAG_SIZED_INTEGER::type)a)); } \ -inline constexpr ENUMTYPE operator ^ (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((_ENUM_FLAG_SIZED_INTEGER::type)a) ^ ((_ENUM_FLAG_SIZED_INTEGER::type)b)); } \ -inline ENUMTYPE &operator ^= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((_ENUM_FLAG_SIZED_INTEGER::type &)a) ^= ((_ENUM_FLAG_SIZED_INTEGER::type)b)); } \ -} -#endif - -// D3DX12 uses these -#include -#define HeapAlloc(heap, flags, size) malloc(size) -#define HeapFree(heap, flags, ptr) free(ptr) - -#ifdef __cplusplus -// IUnknown - -interface DECLSPEC_UUID("00000000-0000-0000-C000-000000000046") DECLSPEC_NOVTABLE IUnknown -{ - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) = 0; - virtual ULONG STDMETHODCALLTYPE AddRef() = 0; - virtual ULONG STDMETHODCALLTYPE Release() = 0; - - template HRESULT STDMETHODCALLTYPE QueryInterface(Q** pp) { - return QueryInterface(uuidof(), (void **)pp); - } -}; - -template <> constexpr GUID uuidof() -{ - return { 0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }; -} - -extern "C++" -{ - template void** IID_PPV_ARGS_Helper(T** pp) - { - static_cast(*pp); - return reinterpret_cast(pp); - } -} - -#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType) -#endif - -#if defined(lint) -// Note: lint -e530 says don't complain about uninitialized variables for -// this variable. Error 527 has to do with unreachable code. -// -restore restores checking to the -save state -#define UNREFERENCED_PARAMETER(P) \ - /*lint -save -e527 -e530 */ \ - { \ - (P) = (P); \ - } \ - /*lint -restore */ -#else -#define UNREFERENCED_PARAMETER(P) (P) -#endif diff --git a/contrib/DirectX-Headers/include/wsl/wrladapter.h b/contrib/DirectX-Headers/include/wsl/wrladapter.h deleted file mode 100644 index 883ecab..0000000 --- a/contrib/DirectX-Headers/include/wsl/wrladapter.h +++ /dev/null @@ -1,801 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#pragma once - -#include "winadapter.h" - -// defined by winadapter.h and needed by some windows headers, but conflicts -// with some libc++ implementation headers -#ifdef __in -#undef __in -#endif -#ifdef __out -#undef __out -#endif - -#include -#include -#include -#include -#include - -namespace Microsoft -{ -namespace WRL -{ - namespace Details - { - struct BoolStruct { int Member; }; - typedef int BoolStruct::* BoolType; - - template // T should be the ComPtr or a derived type of it, not just the interface - class ComPtrRefBase - { - public: - typedef typename T::InterfaceType InterfaceType; - - operator IUnknown**() const throw() - { - static_assert(__is_base_of(IUnknown, InterfaceType), "Invalid cast: InterfaceType does not derive from IUnknown"); - return reinterpret_cast(ptr_->ReleaseAndGetAddressOf()); - } - - protected: - T* ptr_; - }; - - template - class ComPtrRef : public Details::ComPtrRefBase // T should be the ComPtr or a derived type of it, not just the interface - { - using Super = Details::ComPtrRefBase; - using InterfaceType = typename Super::InterfaceType; - public: - ComPtrRef(_In_opt_ T* ptr) throw() - { - this->ptr_ = ptr; - } - - // Conversion operators - operator void**() const throw() - { - return reinterpret_cast(this->ptr_->ReleaseAndGetAddressOf()); - } - - // This is our operator ComPtr (or the latest derived class from ComPtr (e.g. WeakRef)) - operator T*() throw() - { - *this->ptr_ = nullptr; - return this->ptr_; - } - - // We define operator InterfaceType**() here instead of on ComPtrRefBase, since - // if InterfaceType is IUnknown or IInspectable, having it on the base will collide. - operator InterfaceType**() throw() - { - return this->ptr_->ReleaseAndGetAddressOf(); - } - - // This is used for IID_PPV_ARGS in order to do __uuidof(**(ppType)). - // It does not need to clear ptr_ at this point, it is done at IID_PPV_ARGS_Helper(ComPtrRef&) later in this file. - InterfaceType* operator *() throw() - { - return this->ptr_->Get(); - } - - // Explicit functions - InterfaceType* const * GetAddressOf() const throw() - { - return this->ptr_->GetAddressOf(); - } - - InterfaceType** ReleaseAndGetAddressOf() throw() - { - return this->ptr_->ReleaseAndGetAddressOf(); - } - }; - } - - template - class ComPtr - { - public: - typedef T InterfaceType; - - protected: - InterfaceType *ptr_; - template friend class ComPtr; - - void InternalAddRef() const throw() - { - if (ptr_ != nullptr) - { - ptr_->AddRef(); - } - } - - unsigned long InternalRelease() throw() - { - unsigned long ref = 0; - T* temp = ptr_; - - if (temp != nullptr) - { - ptr_ = nullptr; - ref = temp->Release(); - } - - return ref; - } - - public: - ComPtr() throw() : ptr_(nullptr) - { - } - - ComPtr(decltype(nullptr)) throw() : ptr_(nullptr) - { - } - - template - ComPtr(_In_opt_ U *other) throw() : ptr_(other) - { - InternalAddRef(); - } - - ComPtr(const ComPtr& other) throw() : ptr_(other.ptr_) - { - InternalAddRef(); - } - - // copy constructor that allows to instantiate class when U* is convertible to T* - template - ComPtr(const ComPtr &other, typename std::enable_if::value, void *>::type * = 0) throw() : - ptr_(other.ptr_) - { - InternalAddRef(); - } - - ComPtr(_Inout_ ComPtr &&other) throw() : ptr_(nullptr) - { - if (this != reinterpret_cast(&reinterpret_cast(other))) - { - Swap(other); - } - } - - // Move constructor that allows instantiation of a class when U* is convertible to T* - template - ComPtr(_Inout_ ComPtr&& other, typename std::enable_if::value, void *>::type * = 0) throw() : - ptr_(other.ptr_) - { - other.ptr_ = nullptr; - } - - ~ComPtr() throw() - { - InternalRelease(); - } - - ComPtr& operator=(decltype(nullptr)) throw() - { - InternalRelease(); - return *this; - } - - ComPtr& operator=(_In_opt_ T *other) throw() - { - if (ptr_ != other) - { - ComPtr(other).Swap(*this); - } - return *this; - } - - template - ComPtr& operator=(_In_opt_ U *other) throw() - { - ComPtr(other).Swap(*this); - return *this; - } - - ComPtr& operator=(const ComPtr &other) throw() - { - if (ptr_ != other.ptr_) - { - ComPtr(other).Swap(*this); - } - return *this; - } - - template - ComPtr& operator=(const ComPtr& other) throw() - { - ComPtr(other).Swap(*this); - return *this; - } - - ComPtr& operator=(_Inout_ ComPtr &&other) throw() - { - ComPtr(static_cast(other)).Swap(*this); - return *this; - } - - template - ComPtr& operator=(_Inout_ ComPtr&& other) throw() - { - ComPtr(static_cast&&>(other)).Swap(*this); - return *this; - } - - void Swap(_Inout_ ComPtr&& r) throw() - { - T* tmp = ptr_; - ptr_ = r.ptr_; - r.ptr_ = tmp; - } - - void Swap(_Inout_ ComPtr& r) throw() - { - T* tmp = ptr_; - ptr_ = r.ptr_; - r.ptr_ = tmp; - } - - operator Details::BoolType() const throw() - { - return Get() != nullptr ? &Details::BoolStruct::Member : nullptr; - } - - T* Get() const throw() - { - return ptr_; - } - - InterfaceType* operator->() const throw() - { - return ptr_; - } - - Details::ComPtrRef> operator&() throw() - { - return Details::ComPtrRef>(this); - } - - const Details::ComPtrRef> operator&() const throw() - { - return Details::ComPtrRef>(this); - } - - T* const* GetAddressOf() const throw() - { - return &ptr_; - } - - T** GetAddressOf() throw() - { - return &ptr_; - } - - T** ReleaseAndGetAddressOf() throw() - { - InternalRelease(); - return &ptr_; - } - - T* Detach() throw() - { - T* ptr = ptr_; - ptr_ = nullptr; - return ptr; - } - - void Attach(_In_opt_ InterfaceType* other) throw() - { - if (ptr_ != nullptr) - { - auto ref = ptr_->Release(); - // DBG_UNREFERENCED_LOCAL_VARIABLE(ref); - // Attaching to the same object only works if duplicate references are being coalesced. Otherwise - // re-attaching will cause the pointer to be released and may cause a crash on a subsequent dereference. - assert(ref != 0 || ptr_ != other); - } - - ptr_ = other; - } - - unsigned long Reset() - { - return InternalRelease(); - } - - // Previously, unsafe behavior could be triggered when 'this' is ComPtr or ComPtr and CopyTo is used to copy to another type U. - // The user will use operator& to convert the destination into a ComPtrRef, which can then implicit cast to IInspectable** and IUnknown**. - // If this overload of CopyTo is not present, it will implicitly cast to IInspectable or IUnknown and match CopyTo(InterfaceType**) instead. - // A valid polymoprhic downcast requires run-time type checking via QueryInterface, so CopyTo(InterfaceType**) will break type safety. - // This overload matches ComPtrRef before the implicit cast takes place, preventing the unsafe downcast. - template - HRESULT CopyTo(Details::ComPtrRef> ptr, typename std::enable_if< - (std::is_same::value) - && !std::is_same::value, void *>::type * = 0) const throw() - { - return ptr_->QueryInterface(uuidof(), ptr); - } - - HRESULT CopyTo(_Outptr_result_maybenull_ InterfaceType** ptr) const throw() - { - InternalAddRef(); - *ptr = ptr_; - return S_OK; - } - - HRESULT CopyTo(REFIID riid, _Outptr_result_nullonfailure_ void** ptr) const throw() - { - return ptr_->QueryInterface(riid, ptr); - } - - template - HRESULT CopyTo(_Outptr_result_nullonfailure_ U** ptr) const throw() - { - return ptr_->QueryInterface(uuidof(), reinterpret_cast(ptr)); - } - - // query for U interface - template - HRESULT As(_Inout_ Details::ComPtrRef> p) const throw() - { - return ptr_->QueryInterface(uuidof(), p); - } - - // query for U interface - template - HRESULT As(_Out_ ComPtr* p) const throw() - { - return ptr_->QueryInterface(uuidof(), reinterpret_cast(p->ReleaseAndGetAddressOf())); - } - - // query for riid interface and return as IUnknown - HRESULT AsIID(REFIID riid, _Out_ ComPtr* p) const throw() - { - return ptr_->QueryInterface(riid, reinterpret_cast(p->ReleaseAndGetAddressOf())); - } - - }; // ComPtr - - - namespace Details - { - // Empty struct used as default template parameter - class Nil - { - }; - - // Empty struct used for validating template parameter types in Implements - struct ImplementsBase - { - }; - - class RuntimeClassBase - { - protected: - template - static HRESULT AsIID(_In_ T* implements, REFIID riid, _Outptr_result_nullonfailure_ void **ppvObject) noexcept - { - *ppvObject = nullptr; - bool isRefDelegated = false; - // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is almost always the case. - if (InlineIsEqualGUID(riid, uuidof())) - { - *ppvObject = implements->CastToUnknown(); - static_cast(*ppvObject)->AddRef(); - return S_OK; - } - - HRESULT hr = implements->CanCastTo(riid, ppvObject, &isRefDelegated); - if (SUCCEEDED(hr) && !isRefDelegated) - { - static_cast(*ppvObject)->AddRef(); - } - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 6102) // '*ppvObject' is used but may not be initialized -#endif - _Analysis_assume_(SUCCEEDED(hr) || (*ppvObject == nullptr)); -#ifdef _MSC_VER -#pragma warning(pop) -#endif - return hr; - } - - public: - HRESULT RuntimeClassInitialize() noexcept - { - return S_OK; - } - }; - - // Interface traits provides casting and filling iids methods helpers - template - struct InterfaceTraits - { - typedef I0 Base; - - template - static Base* CastToBase(_In_ T* ptr) noexcept - { - return static_cast(ptr); - } - - template - static IUnknown* CastToUnknown(_In_ T* ptr) noexcept - { - return static_cast(static_cast(ptr)); - } - - template - _Success_(return == true) - static bool CanCastTo(_In_ T* ptr, REFIID riid, _Outptr_ void **ppv) noexcept - { - // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is almost always the case. - if (InlineIsEqualGUID(riid, uuidof())) - { - *ppv = static_cast(ptr); - return true; - } - - return false; - } - }; - - // Specialization for Nil parameter - template<> - struct InterfaceTraits - { - typedef Nil Base; - - template - _Success_(return == true) - static bool CanCastTo(_In_ T*, REFIID, _Outptr_ void **) noexcept - { - return false; - } - }; - - // ChainInterfaces - template allows specifying a derived COM interface along with its class hierarchy to allow QI for the base interfaces - template - struct ChainInterfaces : I0 - { - protected: - HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv) throw() - { - typename InterfaceTraits::Base* ptr = InterfaceTraits::CastToBase(this); - - return (InterfaceTraits::CanCastTo(this, riid, ppv) || - InterfaceTraits::CanCastTo(ptr, riid, ppv) || - InterfaceTraits::CanCastTo(ptr, riid, ppv) || - InterfaceTraits::CanCastTo(ptr, riid, ppv) || - InterfaceTraits::CanCastTo(ptr, riid, ppv) || - InterfaceTraits::CanCastTo(ptr, riid, ppv) || - InterfaceTraits::CanCastTo(ptr, riid, ppv) || - InterfaceTraits::CanCastTo(ptr, riid, ppv) || - InterfaceTraits::CanCastTo(ptr, riid, ppv) || - InterfaceTraits::CanCastTo(ptr, riid, ppv)) ? S_OK : E_NOINTERFACE; - } - - IUnknown* CastToUnknown() throw() - { - return InterfaceTraits::CastToUnknown(this); - } - }; - - // Helper template used by Implements. This template traverses a list of interfaces and adds them as base class and information - // to enable QI. - template - struct ImplementsHelper; - - template - struct ImplementsMarker - {}; - - template - struct MarkImplements; - - template - struct MarkImplements - { - typedef I0 Type; - }; - - template - struct MarkImplements - { - typedef ImplementsMarker Type; - }; - - // AdjustImplements pre-processes the type list for more efficient builds. - template - struct AdjustImplements; - - template - struct AdjustImplements - { - typedef ImplementsHelper::value>::Type, Bases...> Type; - }; - - // Use AdjustImplements to remove instances of "Nil" from the type list. - template - struct AdjustImplements - { - typedef typename AdjustImplements::Type Type; - }; - - template <> - struct AdjustImplements<> - { - typedef ImplementsHelper<> Type; - }; - - // Specialization handles unadorned interfaces - template - struct ImplementsHelper : - I0, - AdjustImplements::Type - { - template friend struct ImplementsHelper; - friend class RuntimeClassBase; - - protected: - - HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) noexcept - { - // Prefer InlineIsEqualGUID over other forms since it's better perf on 4-byte aligned data, which is almost always the case. - if (InlineIsEqualGUID(riid, uuidof())) - { - *ppv = reinterpret_cast(reinterpret_cast(this)); - return S_OK; - } - return AdjustImplements::Type::CanCastTo(riid, ppv, pRefDelegated); - } - - IUnknown* CastToUnknown() noexcept - { - return reinterpret_cast(reinterpret_cast(this)); - } - }; - - - // Selector is used to "tag" base interfaces to be used in casting, since a runtime class may indirectly derive from - // the same interface or Implements<> template multiple times - template - struct Selector : public base - { - }; - - // Specialization handles types that derive from ImplementsHelper (e.g. nested Implements). - template - struct ImplementsHelper, TInterfaces...> : - Selector, TInterfaces...>>, - Selector::Type, ImplementsHelper, TInterfaces...>> - { - template friend struct ImplementsHelper; - friend class RuntimeClassBase; - - protected: - typedef Selector, TInterfaces...>> CurrentType; - typedef Selector::Type, ImplementsHelper, TInterfaces...>> BaseType; - - HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) noexcept - { - HRESULT hr = CurrentType::CanCastTo(riid, ppv); - if (hr == E_NOINTERFACE) - { - hr = BaseType::CanCastTo(riid, ppv, pRefDelegated); - } - return hr; - } - - IUnknown* CastToUnknown() noexcept - { - // First in list wins. - return CurrentType::CastToUnknown(); - } - }; - - // terminal case specialization. - template <> - struct ImplementsHelper<> - { - template friend struct ImplementsHelper; - friend class RuntimeClassBase; - - protected: - HRESULT CanCastTo(_In_ REFIID /*riid*/, _Outptr_ void ** /*ppv*/, bool * /*pRefDelegated*/ = nullptr) noexcept - { - return E_NOINTERFACE; - } - - // IUnknown* CastToUnknown() noexcept; // not defined for terminal case. - }; - - // Specialization handles chaining interfaces - template - struct ImplementsHelper, TInterfaces...> : - ChainInterfaces, - AdjustImplements::Type - { - template friend struct ImplementsHelper; - friend class RuntimeClassBase; - - protected: - typedef typename AdjustImplements::Type BaseType; - - HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv, bool *pRefDelegated = nullptr) noexcept - { - HRESULT hr = ChainInterfaces::CanCastTo(riid, ppv); - if (FAILED(hr)) - { - hr = BaseType::CanCastTo(riid, ppv, pRefDelegated); - } - - return hr; - } - - IUnknown* CastToUnknown() noexcept - { - return ChainInterfaces::CastToUnknown(); - } - }; - - // Implements - template implementing QI using the information provided through its template parameters - // Each template parameter has to be one of the following: - // * COM Interface - // * A class that implements one or more COM interfaces - // * ChainInterfaces template - template - struct Implements : - AdjustImplements::Type, - ImplementsBase - { - public: - typedef I0 FirstInterface; - protected: - typedef typename AdjustImplements::Type BaseType; - template friend struct ImplementsHelper; - friend class RuntimeClassBase; - - HRESULT CanCastTo(REFIID riid, _Outptr_ void **ppv) noexcept - { - return BaseType::CanCastTo(riid, ppv); - } - - IUnknown* CastToUnknown() noexcept - { - return BaseType::CastToUnknown(); - } - }; - - // Used on RuntimeClass to protect it from being constructed with new - class DontUseNewUseMake - { - private: - void* operator new(size_t) noexcept - { - assert(false); - return 0; - } - - public: - void* operator new(size_t, _In_ void* placement) noexcept - { - return placement; - } - }; - - template - class RuntimeClassImpl : - public AdjustImplements::Type, - public RuntimeClassBase, - public DontUseNewUseMake - { - public: - STDMETHOD(QueryInterface)(REFIID riid, _Outptr_result_nullonfailure_ void **ppvObject) - { - return Super::AsIID(this, riid, ppvObject); - } - - STDMETHOD_(ULONG, AddRef)() - { - return InternalAddRef(); - } - - STDMETHOD_(ULONG, Release)() - { - ULONG ref = InternalRelease(); - if (ref == 0) - { - delete this; - } - - return ref; - } - - protected: - using Super = RuntimeClassBase; - static const LONG c_lProtectDestruction = -(LONG_MAX / 2); - - RuntimeClassImpl() noexcept = default; - - virtual ~RuntimeClassImpl() noexcept - { - // Set refcount_ to -(LONG_MAX/2) to protect destruction and - // also catch mismatched Release in debug builds - refcount_ = static_cast(c_lProtectDestruction); - } - - ULONG InternalAddRef() noexcept - { - return ++refcount_; - } - - ULONG InternalRelease() noexcept - { - return --refcount_; - } - - unsigned long GetRefCount() const noexcept - { - return refcount_; - } - - std::atomic refcount_{1}; - }; - } - - template - class Base : public Details::RuntimeClassImpl - { - Base(const Base&) = delete; - Base& operator=(const Base&) = delete; - - protected: - HRESULT CustomQueryInterface(REFIID /*riid*/, _Outptr_result_nullonfailure_ void** /*ppvObject*/, _Out_ bool *handled) - { - *handled = false; - return S_OK; - } - - public: - Base() throw() = default; - typedef Base RuntimeClassT; - }; - - // Creates a Nano-COM object wrapped in a smart pointer. - template - ComPtr Make(TArgs&&... args) - { - ComPtr object; - - std::unique_ptr buffer(new unsigned char[sizeof(T)]); - if (buffer) - { - T* ptr = new (buffer.get())T(std::forward(args)...); - object.Attach(ptr); - buffer.release(); - } - - return object; - } - - using Details::ChainInterfaces; -} -} - -// Overloaded global function to provide to IID_PPV_ARGS that support Details::ComPtrRef -template -void** IID_PPV_ARGS_Helper(Microsoft::WRL::Details::ComPtrRef pp) throw() -{ - return pp; -} \ No newline at end of file -- cgit v1.2.3