[add] first
This commit is contained in:
68
Libraries/libil2cpp/include/os/WinRT/ReferenceCounter.h
Normal file
68
Libraries/libil2cpp/include/os/WinRT/ReferenceCounter.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
#include <utility>
|
||||
|
||||
#include <hstring.h>
|
||||
#include <Unknwn.h>
|
||||
|
||||
namespace il2cpp
|
||||
{
|
||||
namespace winrt
|
||||
{
|
||||
template<typename T, bool isIUnknown = std::is_base_of<IUnknown, std::remove_pointer<T>::type>::value>
|
||||
struct ReferenceCounter;
|
||||
|
||||
template<typename T>
|
||||
struct ReferenceCounter<T, false>
|
||||
{
|
||||
static inline void AddRef(T& value)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void Release(T& value)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ReferenceCounter<T, true>
|
||||
{
|
||||
static inline void AddRef(T& value)
|
||||
{
|
||||
if (value == nullptr)
|
||||
return;
|
||||
|
||||
value->AddRef();
|
||||
}
|
||||
|
||||
static inline void Release(T& value)
|
||||
{
|
||||
if (value == nullptr)
|
||||
return;
|
||||
|
||||
value->Release();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ReferenceCounter<HSTRING, false>
|
||||
{
|
||||
static inline void AddRef(HSTRING& value)
|
||||
{
|
||||
if (value == nullptr)
|
||||
return;
|
||||
|
||||
auto hr = WindowsDuplicateString(value, &value);
|
||||
Assert(SUCCEEDED(hr));
|
||||
}
|
||||
|
||||
static inline void Release(HSTRING& value)
|
||||
{
|
||||
if (value == nullptr)
|
||||
return;
|
||||
|
||||
auto hr = WindowsDeleteString(value);
|
||||
Assert(SUCCEEDED(hr));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
142
Libraries/libil2cpp/include/os/WinRT/SynchronousOperation.h
Normal file
142
Libraries/libil2cpp/include/os/WinRT/SynchronousOperation.h
Normal file
@@ -0,0 +1,142 @@
|
||||
#pragma once
|
||||
|
||||
#include "ReferenceCounter.h"
|
||||
|
||||
#include "os/Win32/WindowsHeaders.h"
|
||||
#include <windows.foundation.h>
|
||||
#include <windows.foundation.collections.h>
|
||||
#include <wrl.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace il2cpp
|
||||
{
|
||||
namespace winrt
|
||||
{
|
||||
template<typename T>
|
||||
struct ResultTypeTraits
|
||||
{
|
||||
typedef typename ABI::Windows::Foundation::Internal::GetLogicalType<typename T::TResult_complex>::type LogicalType;
|
||||
typedef typename ABI::Windows::Foundation::Internal::GetAbiType<typename T::TResult_complex>::type ResultType;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ResultTypeTraits<ABI::Windows::Foundation::IAsyncAction>
|
||||
{
|
||||
typedef void LogicalType;
|
||||
typedef void ResultType;
|
||||
};
|
||||
|
||||
template<typename OperationType, typename HandlerType>
|
||||
class SynchronousOperationBase : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>, Microsoft::WRL::FtmBase, HandlerType>
|
||||
{
|
||||
protected:
|
||||
HANDLE m_Event;
|
||||
HRESULT m_HR;
|
||||
|
||||
typedef OperationType OperationType;
|
||||
|
||||
inline SynchronousOperationBase(OperationType* op)
|
||||
{
|
||||
m_Event = CreateEventExW(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
|
||||
Assert(m_Event && "CreateEventExW failed.");
|
||||
}
|
||||
|
||||
inline ~SynchronousOperationBase()
|
||||
{
|
||||
CloseHandle(m_Event);
|
||||
|
||||
// This will be not 0 if it's allocated on the stack
|
||||
// This class must be allocated on the heap for correct COM ref counting!
|
||||
IL2CPP_ASSERT(GetRefCount() == 0);
|
||||
}
|
||||
|
||||
public:
|
||||
inline HRESULT Wait()
|
||||
{
|
||||
auto waitResult = WaitForSingleObjectEx(m_Event, INFINITE, FALSE);
|
||||
|
||||
if (waitResult != WAIT_OBJECT_0)
|
||||
return E_FAIL;
|
||||
|
||||
return m_HR;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class SynchronousOperation : public SynchronousOperationBase<ABI::Windows::Foundation::IAsyncOperation<T>, ABI::Windows::Foundation::IAsyncOperationCompletedHandler<T> >
|
||||
{
|
||||
private:
|
||||
typedef typename ResultTypeTraits<OperationType>::ResultType ResultType;
|
||||
ResultType m_Result;
|
||||
|
||||
public:
|
||||
inline SynchronousOperation(OperationType* op) :
|
||||
SynchronousOperationBase(op),
|
||||
m_Result(ResultType())
|
||||
{
|
||||
// NOTE: this is in the derived class because it might immediately complete.
|
||||
// If this was called from the base class, you'd get a callback on a partially
|
||||
// constructed vtable and crash.
|
||||
auto hr = op->put_Completed(this);
|
||||
Assert(SUCCEEDED(hr) && "IAsyncOperation<T>::put_Completed failed.");
|
||||
}
|
||||
|
||||
~SynchronousOperation()
|
||||
{
|
||||
ReferenceCounter<ResultType>::Release(m_Result);
|
||||
}
|
||||
|
||||
HRESULT GetResults(ResultType* result)
|
||||
{
|
||||
auto hr = Wait();
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
*result = m_Result;
|
||||
ReferenceCounter<ResultType>::AddRef(*result);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Invoke(ABI::Windows::Foundation::IAsyncOperation<T>* asyncInfo, ABI::Windows::Foundation::AsyncStatus status) override
|
||||
{
|
||||
m_HR = asyncInfo->GetResults(&m_Result);
|
||||
SetEvent(m_Event);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static Microsoft::WRL::ComPtr<SynchronousOperation<T> > Make(OperationType* op)
|
||||
{
|
||||
return Microsoft::WRL::Make<SynchronousOperation<T> >(op);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class SynchronousOperation<void> : public SynchronousOperationBase<ABI::Windows::Foundation::IAsyncAction, ABI::Windows::Foundation::IAsyncActionCompletedHandler>
|
||||
{
|
||||
public:
|
||||
inline SynchronousOperation(OperationType* op) :
|
||||
SynchronousOperationBase(op)
|
||||
{
|
||||
// NOTE: this is in the derived class because it might immediately complete.
|
||||
// If this was called from the base class, you'd get a callback on a partially
|
||||
// constructed vtable and crash.
|
||||
auto hr = op->put_Completed(this);
|
||||
Assert(SUCCEEDED(hr) && "IAsyncAction::put_Completed failed.");
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Invoke(ABI::Windows::Foundation::IAsyncAction* asyncInfo, ABI::Windows::Foundation::AsyncStatus status) override
|
||||
{
|
||||
m_HR = asyncInfo->GetResults();
|
||||
SetEvent(m_Event);
|
||||
return S_OK;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
Microsoft::WRL::ComPtr<SynchronousOperation<typename ResultTypeTraits<T>::LogicalType> > MakeSynchronousOperation(T* op)
|
||||
{
|
||||
return Microsoft::WRL::Make<SynchronousOperation<typename ResultTypeTraits<T>::LogicalType> >(op);
|
||||
}
|
||||
}
|
||||
}
|
||||
181
Libraries/libil2cpp/include/os/WinRT/Win32ApiSharedEmulation.h
Normal file
181
Libraries/libil2cpp/include/os/WinRT/Win32ApiSharedEmulation.h
Normal file
@@ -0,0 +1,181 @@
|
||||
#pragma once
|
||||
|
||||
#if IL2CPP_TARGET_WINRT || IL2CPP_TARGET_XBOXONE
|
||||
|
||||
#include "os/Win32/WindowsHeaders.h"
|
||||
#include <wrl.h>
|
||||
|
||||
#if WINDOWS_SDK_BUILD_VERSION < 16299 // This got readded on Windows 10 Fall Creators Update
|
||||
#define MAX_COMPUTERNAME_LENGTH 31
|
||||
#define GetComputerName GetComputerNameW
|
||||
#endif
|
||||
|
||||
namespace il2cpp
|
||||
{
|
||||
namespace winrt
|
||||
{
|
||||
inline DWORD WIN32_FROM_HRESULT(HRESULT hr)
|
||||
{
|
||||
if ((hr & 0xFFFF0000) == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, 0))
|
||||
return HRESULT_CODE(hr);
|
||||
if (hr == S_OK)
|
||||
return HRESULT_CODE(hr);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
inline static BOOL CopyHStringToBuffer(Microsoft::WRL::Wrappers::HString& source, LPWSTR target, LPDWORD targetSize)
|
||||
{
|
||||
unsigned int sourceLength;
|
||||
auto sourceBuffer = source.GetRawBuffer(&sourceLength);
|
||||
|
||||
if (sourceLength + 1 > *targetSize)
|
||||
{
|
||||
SetLastError(ERROR_BUFFER_OVERFLOW);
|
||||
*targetSize = sourceLength + 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*targetSize = sourceLength;
|
||||
|
||||
if (target != nullptr)
|
||||
{
|
||||
memcpy(target, sourceBuffer, sourceLength * sizeof(wchar_t));
|
||||
target[sourceLength] = L'\0';
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if WINDOWS_SDK_BUILD_VERSION < 16299 // These APIs got readded on Windows 10 Fall Creators Update
|
||||
|
||||
extern "C"
|
||||
{
|
||||
inline BOOL WINAPI CopyFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, BOOL bFailIfExists)
|
||||
{
|
||||
COPYFILE2_EXTENDED_PARAMETERS params;
|
||||
|
||||
params.dwSize = sizeof(params);
|
||||
params.dwCopyFlags = bFailIfExists ? COPY_FILE_FAIL_IF_EXISTS : 0;
|
||||
params.pfCancel = FALSE;
|
||||
params.pProgressRoutine = nullptr;
|
||||
params.pvCallbackContext = nullptr;
|
||||
|
||||
auto hr = CopyFile2(lpExistingFileName, lpNewFileName, ¶ms);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
SetLastError(il2cpp::winrt::WIN32_FROM_HRESULT(hr));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
inline UINT WINAPI GetACP()
|
||||
{
|
||||
return CP_ACP;
|
||||
}
|
||||
|
||||
BOOL WINAPI GetComputerNameW(LPWSTR lpBuffer, LPDWORD nSize);
|
||||
} // extern "C"
|
||||
|
||||
#endif
|
||||
|
||||
#if WINDOWS_SDK_BUILD_VERSION < 15063
|
||||
|
||||
extern "C"
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
char String[4 * 4];
|
||||
} IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
|
||||
|
||||
typedef struct _IP_ADDR_STRING
|
||||
{
|
||||
struct _IP_ADDR_STRING* Next;
|
||||
IP_ADDRESS_STRING IpAddress;
|
||||
IP_MASK_STRING IpMask;
|
||||
DWORD Context;
|
||||
} IP_ADDR_STRING, *PIP_ADDR_STRING;
|
||||
|
||||
#define MAX_HOSTNAME_LEN 128
|
||||
#define MAX_DOMAIN_NAME_LEN 128
|
||||
#define MAX_SCOPE_ID_LEN 256
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char HostName[MAX_HOSTNAME_LEN + 4];
|
||||
char DomainName[MAX_DOMAIN_NAME_LEN + 4];
|
||||
PIP_ADDR_STRING CurrentDnsServer;
|
||||
IP_ADDR_STRING DnsServerList;
|
||||
UINT NodeType;
|
||||
char ScopeId[MAX_SCOPE_ID_LEN + 4];
|
||||
UINT EnableRouting;
|
||||
UINT EnableProxy;
|
||||
UINT EnableDns;
|
||||
} FIXED_INFO, *PFIXED_INFO;
|
||||
|
||||
DWORD WINAPI GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen);
|
||||
} // extern "C"
|
||||
|
||||
#endif
|
||||
|
||||
#if IL2CPP_TARGET_WINRT
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#if WINDOWS_SDK_BUILD_VERSION < 15063
|
||||
|
||||
#define MAX_INTERFACE_NAME_LEN 256
|
||||
#define MAXLEN_PHYSADDR 8
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IF_OPER_STATUS_NON_OPERATIONAL = 0,
|
||||
IF_OPER_STATUS_UNREACHABLE = 1,
|
||||
IF_OPER_STATUS_DISCONNECTED = 2,
|
||||
IF_OPER_STATUS_CONNECTING = 3,
|
||||
IF_OPER_STATUS_CONNECTED = 4,
|
||||
IF_OPER_STATUS_OPERATIONAL = 5,
|
||||
} INTERNAL_IF_OPER_STATUS;
|
||||
|
||||
#define MAXLEN_IFDESCR 256
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WCHAR wszName[MAX_INTERFACE_NAME_LEN];
|
||||
IF_INDEX dwIndex;
|
||||
IFTYPE dwType;
|
||||
DWORD dwMtu;
|
||||
DWORD dwSpeed;
|
||||
DWORD dwPhysAddrLen;
|
||||
UCHAR bPhysAddr[MAXLEN_PHYSADDR];
|
||||
DWORD dwAdminStatus;
|
||||
INTERNAL_IF_OPER_STATUS dwOperStatus;
|
||||
DWORD dwLastChange;
|
||||
DWORD dwInOctets;
|
||||
DWORD dwInUcastPkts;
|
||||
DWORD dwInNUcastPkts;
|
||||
DWORD dwInDiscards;
|
||||
DWORD dwInErrors;
|
||||
DWORD dwInUnknownProtos;
|
||||
DWORD dwOutOctets;
|
||||
DWORD dwOutUcastPkts;
|
||||
DWORD dwOutNUcastPkts;
|
||||
DWORD dwOutDiscards;
|
||||
DWORD dwOutErrors;
|
||||
DWORD dwOutQLen;
|
||||
DWORD dwDescrLen;
|
||||
UCHAR bDescr[MAXLEN_IFDESCR];
|
||||
} MIB_IFROW, *PMIB_IFROW;
|
||||
|
||||
#endif
|
||||
|
||||
DWORD WINAPI GetIfEntry(PMIB_IFROW pIfRow);
|
||||
} // extern "C"
|
||||
|
||||
#endif // IL2CPP_TARGET_WINRT
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,89 @@
|
||||
#pragma once
|
||||
|
||||
#if IL2CPP_TARGET_WINRT
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#if WINDOWS_SDK_BUILD_VERSION < 16299 // These APIs got readded on Windows 10 Fall Creators Update
|
||||
|
||||
#define CreateEvent CreateEventW
|
||||
#define FreeEnvironmentStrings FreeEnvironmentStringsW
|
||||
#define GetEnvironmentStrings GetEnvironmentStringsW
|
||||
#define GetEnvironmentVariable GetEnvironmentVariableW
|
||||
#define GetVersionEx GetVersionExW
|
||||
#define SetEnvironmentVariable SetEnvironmentVariableW
|
||||
|
||||
#endif
|
||||
|
||||
#define GetUserName GetUserNameW
|
||||
|
||||
#if WINDOWS_SDK_BUILD_VERSION < 16299
|
||||
|
||||
inline HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName)
|
||||
{
|
||||
DWORD flags = 0;
|
||||
if (bManualReset)
|
||||
flags |= CREATE_EVENT_MANUAL_RESET;
|
||||
if (bInitialState)
|
||||
flags |= CREATE_EVENT_INITIAL_SET;
|
||||
return CreateEventExW(lpEventAttributes, lpName, flags, EVENT_ALL_ACCESS);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
inline HANDLE WINAPI CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
|
||||
{
|
||||
const DWORD kFileAttributeMask = 0x0000FFFF;
|
||||
const DWORD kFileFlagMask = 0xFFFF0000;
|
||||
|
||||
CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
|
||||
extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
|
||||
extendedParameters.dwFileAttributes = dwFlagsAndAttributes & kFileAttributeMask;
|
||||
extendedParameters.dwFileFlags = dwFlagsAndAttributes & kFileFlagMask;
|
||||
extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
|
||||
extendedParameters.lpSecurityAttributes = lpSecurityAttributes;
|
||||
extendedParameters.hTemplateFile = hTemplateFile;
|
||||
|
||||
return CreateFile2(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, &extendedParameters);
|
||||
}
|
||||
|
||||
#if WINDOWS_SDK_BUILD_VERSION < 16299
|
||||
|
||||
BOOL WINAPI FreeEnvironmentStringsW(LPWCH strings);
|
||||
|
||||
LPWCH WINAPI GetEnvironmentStringsW();
|
||||
|
||||
DWORD WINAPI GetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer, DWORD nSize);
|
||||
|
||||
BOOL WINAPI GetVersionExW(LPOSVERSIONINFOW lpVersionInformation);
|
||||
|
||||
#endif
|
||||
|
||||
BOOL WINAPI GetUserNameW(LPWSTR lpBuffer, LPDWORD pcbBuffer);
|
||||
|
||||
inline HMODULE WINAPI LoadLibraryW(LPCWSTR lpLibFileName)
|
||||
{
|
||||
return LoadPackagedLibrary(lpLibFileName, 0);
|
||||
}
|
||||
|
||||
#if WINDOWS_SDK_BUILD_VERSION < 16299
|
||||
|
||||
BOOL WINAPI SetEnvironmentVariableW(LPCWSTR lpName, LPCWSTR lpValue);
|
||||
|
||||
#endif
|
||||
|
||||
#define CreateFileMappingW(hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName) \
|
||||
CreateFileMappingFromApp(hFile, lpFileMappingAttributes, flProtect, (static_cast<ULONG64>(dwMaximumSizeHigh) << 32) | dwMaximumSizeLow, lpName);
|
||||
|
||||
#define MapViewOfFile(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap) \
|
||||
MapViewOfFileFromApp(hFileMappingObject, dwDesiredAccess, (static_cast<ULONG64>(dwFileOffsetHigh) << 32) | dwFileOffsetLow, dwNumberOfBytesToMap);
|
||||
|
||||
#if WINDOWS_SDK_BUILD_VERSION < 14393
|
||||
#define TlsAlloc() FlsAlloc(NULL)
|
||||
#define TlsGetValue FlsGetValue
|
||||
#define TlsSetValue FlsSetValue
|
||||
#define TlsFree FlsFree
|
||||
#endif
|
||||
} // extern "C"
|
||||
|
||||
#endif
|
||||
243
Libraries/libil2cpp/include/os/WinRT/WinRTVector.h
Normal file
243
Libraries/libil2cpp/include/os/WinRT/WinRTVector.h
Normal file
@@ -0,0 +1,243 @@
|
||||
#pragma once
|
||||
// This class was copied from Unity's source code and modified to not depend on Unity's MemoryManager
|
||||
|
||||
#include "ReferenceCounter.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <Windows.Foundation.Collections.h>
|
||||
#include <wrl.h>
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
template<typename T>
|
||||
inline void AddItemRef(T& value)
|
||||
{
|
||||
il2cpp::winrt::ReferenceCounter<T>::AddRef(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void ReleaseItem(T& value)
|
||||
{
|
||||
il2cpp::winrt::ReferenceCounter<T>::Release(value);
|
||||
value = T();
|
||||
}
|
||||
}
|
||||
|
||||
namespace il2cpp
|
||||
{
|
||||
namespace winrt
|
||||
{
|
||||
template<typename T>
|
||||
struct Vector :
|
||||
public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>,
|
||||
Microsoft::WRL::FtmBase,
|
||||
ABI::Windows::Foundation::Collections::IVector<T>,
|
||||
ABI::Windows::Foundation::Collections::IVectorView<T>,
|
||||
ABI::Windows::Foundation::Collections::IIterable<T> >
|
||||
{
|
||||
private:
|
||||
struct Iterator :
|
||||
public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>, Microsoft::WRL::FtmBase, ABI::Windows::Foundation::Collections::IIterator<T> >
|
||||
{
|
||||
private:
|
||||
Microsoft::WRL::ComPtr<Vector<T> > m_Vector;
|
||||
size_t m_Position;
|
||||
|
||||
public:
|
||||
Iterator(Vector<T>* vector) :
|
||||
m_Vector(vector), m_Position(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL get_Current(T* current) override
|
||||
{
|
||||
if (m_Position >= m_Vector->m_Vector.size())
|
||||
{
|
||||
return E_BOUNDS;
|
||||
}
|
||||
|
||||
*current = m_Vector->m_Vector[m_Position];
|
||||
::Internal::AddItemRef(*current);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL get_HasCurrent(boolean* hasCurrent) override
|
||||
{
|
||||
*hasCurrent = m_Position < m_Vector->m_Vector.size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL MoveNext(boolean* hasCurrent) override
|
||||
{
|
||||
if (m_Position < m_Vector->m_Vector.size())
|
||||
{
|
||||
m_Position++;
|
||||
*hasCurrent = m_Position < m_Vector->m_Vector.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
*hasCurrent = false;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL GetMany(uint32_t capacity, T* dest, uint32_t* actualCount) override
|
||||
{
|
||||
return m_Vector->GetMany(0, capacity, dest, actualCount);
|
||||
}
|
||||
};
|
||||
|
||||
friend struct Iterator;
|
||||
|
||||
std::vector<T> m_Vector;
|
||||
|
||||
inline void ClearInternal()
|
||||
{
|
||||
for (size_t i = 0; i < m_Vector.size(); i++)
|
||||
::Internal::ReleaseItem(m_Vector[i]);
|
||||
|
||||
m_Vector.clear();
|
||||
}
|
||||
|
||||
public:
|
||||
Vector()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~Vector()
|
||||
{
|
||||
ClearInternal();
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL GetAt(uint32_t index, T* item) override
|
||||
{
|
||||
*item = m_Vector[index];
|
||||
::Internal::AddItemRef(*item);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL GetMany(uint32_t startIndex, uint32_t capacity, T* dest, uint32_t* actualCount) override
|
||||
{
|
||||
ZeroMemory(dest, sizeof(T) * capacity);
|
||||
|
||||
if (startIndex > m_Vector.size())
|
||||
return E_BOUNDS;
|
||||
|
||||
uint32_t count = std::min(capacity, static_cast<uint32_t>(m_Vector.size()) - startIndex);
|
||||
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
dest[i] = m_Vector[i + startIndex];
|
||||
::Internal::AddItemRef(dest[i]);
|
||||
}
|
||||
|
||||
*actualCount = count;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL get_Size(uint32_t* size) override
|
||||
{
|
||||
*size = static_cast<unsigned>(m_Vector.size());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL GetView(ABI::Windows::Foundation::Collections::IVectorView<T>** view) override
|
||||
{
|
||||
AddRef();
|
||||
*view = this;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL IndexOf(T value, uint32_t* index, boolean* found) override
|
||||
{
|
||||
*found = false;
|
||||
|
||||
for (*index = 0; *index < m_Vector.size(); (*index)++)
|
||||
{
|
||||
if (value == m_Vector[*index])
|
||||
{
|
||||
*found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL SetAt(uint32_t index, T item) override
|
||||
{
|
||||
::Internal::ReleaseItem(m_Vector[index]);
|
||||
m_Vector[index] = item;
|
||||
::Internal::AddItemRef(m_Vector[index]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL InsertAt(uint32_t index, T item) override
|
||||
{
|
||||
m_Vector.insert(m_Vector.begin() + index, item);
|
||||
::Internal::AddItemRef(m_Vector[index]);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL RemoveAt(uint32_t index) override
|
||||
{
|
||||
if (m_Vector.size() <= index)
|
||||
return E_FAIL;
|
||||
|
||||
::Internal::ReleaseItem(m_Vector[index]);
|
||||
m_Vector.erase(m_Vector.begin() + index);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL Append(T item) override
|
||||
{
|
||||
m_Vector.push_back(item);
|
||||
::Internal::AddItemRef(m_Vector.back());
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL RemoveAtEnd() override
|
||||
{
|
||||
if (m_Vector.empty())
|
||||
return E_FAIL;
|
||||
|
||||
::Internal::ReleaseItem(m_Vector.back());
|
||||
m_Vector.pop_back();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL ReplaceAll(uint32_t count, T* values) override
|
||||
{
|
||||
ClearInternal();
|
||||
m_Vector.reserve(count);
|
||||
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
m_Vector.push_back(values[i]);
|
||||
::Internal::AddItemRef(m_Vector.back());
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL Clear() override
|
||||
{
|
||||
ClearInternal();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDCALL First(ABI::Windows::Foundation::Collections::IIterator<T>** first) override
|
||||
{
|
||||
*first = Microsoft::WRL::Make<Iterator>(this).Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void Reserve(size_t count)
|
||||
{
|
||||
m_Vector.reserve(count);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user