Remove old Windows 7 support code (#1348)

This commit is contained in:
Kenny Kerr 2023-08-28 08:35:09 -05:00 коммит произвёл GitHub
Родитель 9b453cfc51
Коммит de6ca88bd6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
65 изменённых файлов: 17 добавлений и 4898 удалений

296
.github/workflows/ci.yml поставляемый
Просмотреть файл

@ -97,7 +97,7 @@ jobs:
compiler: [MSVC, clang-cl]
arch: [x86, x64, arm64]
config: [Debug, Release]
test_exe: [test, test_cpp20, test_cpp20_no_sourcelocation, test_win7, test_fast, test_slow, test_old, test_module_lock_custom, test_module_lock_none]
test_exe: [test, test_cpp20, test_cpp20_no_sourcelocation, test_fast, test_slow, test_old, test_module_lock_custom, test_module_lock_none]
exclude:
- arch: arm64
config: Debug
@ -250,120 +250,6 @@ jobs:
_build/${{ matrix.arch }}/${{ matrix.config }}/*.lib
_build/${{ matrix.arch }}/${{ matrix.config }}/*.pdb
test-llvm-mingw-cppwinrt:
name: 'llvm-mingw: Build and test'
strategy:
fail-fast: false
matrix:
arch: [i686, x86_64]
config: [Debug, Release]
runs-on: windows-latest
env:
CMAKE_COLOR_DIAGNOSTICS: 1
CLICOLOR_FORCE: 1
steps:
- uses: actions/checkout@v3
- id: setup-llvm
name: Set up llvm-mingw
uses: ./.github/actions/setup-llvm-mingw
with:
host-arch: ${{ matrix.arch }}
- name: Build cppwinrt
run: |
mkdir build
cd build
if ("${{ matrix.config }}" -eq "Debug") {
$sanitizers = "TRUE"
} else {
$sanitizers = "FALSE"
}
cmake ../ -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE=${{ matrix.config }} `
-DDOWNLOAD_WINDOWSNUMERICS=TRUE `
-DUSE_ANSI_COLOR=TRUE `
-DCMAKE_CXX_FLAGS="-fansi-escape-codes" `
-DENABLE_TEST_SANITIZERS=$sanitizers
cmake --build . -j2 --target cppwinrt
- name: Upload cppwinrt.exe
uses: actions/upload-artifact@v3
with:
name: llvm-mingw-build-${{ matrix.arch }}-bin
path: build/cppwinrt.exe
- name: Build tests
run: |
cd build
cmake --build . -j2 --target test-vanilla test_cpp20 test_cpp20_no_sourcelocation test_win7 test_old
- name: Upload test binaries
uses: actions/upload-artifact@v3
with:
name: llvm-mingw-tests-${{ matrix.arch }}-bin
path: build/test/*.exe
- name: Run tests
run: |
cd build
$env:UBSAN_OPTIONS = "print_stacktrace=1"
ctest --verbose
test-msys2-gcc-cppwinrt:
name: 'gcc/msys2: Build and test (${{ matrix.sys }}, ${{ matrix.config }})'
strategy:
fail-fast: false
matrix:
include:
# 32-bit builds are running out of memory
# - { sys: mingw32, arch: i686, config: Release }
- { sys: mingw64, arch: x86_64, config: Debug }
- { sys: mingw64, arch: x86_64, config: Release }
- { sys: ucrt64, arch: x86_64, config: Release }
runs-on: windows-latest
env:
CMAKE_COLOR_DIAGNOSTICS: 1
CLICOLOR_FORCE: 1
defaults:
run:
shell: msys2 {0}
steps:
- uses: msys2/setup-msys2@v2
with:
msystem: ${{matrix.sys}}
update: true
pacboy: >-
crt:p
gcc:p
binutils:p
cmake:p
ninja:p
- uses: actions/checkout@v3
- name: Build cppwinrt
run: |
mkdir build
cd build
if [[ "${{ matrix.arch }}" = "i686" ]]; then
skip_large_pch_arg="-DSKIP_LARGE_PCH=TRUE"
fi
cmake ../ -GNinja -DCMAKE_BUILD_TYPE=${{ matrix.config }} \
-DDOWNLOAD_WINDOWSNUMERICS=TRUE \
-DUSE_ANSI_COLOR=TRUE \
$skip_large_pch_arg
cmake --build . --target cppwinrt
- name: Build tests
run: |
cd build
cmake --build . -j2 --target test-vanilla test_cpp20 test_cpp20_no_sourcelocation test_win7 test_old
- name: Run tests
run: |
cd build
ctest --verbose
build-linux-cross-cppwinrt:
name: 'cross: Cross-build from Linux'
strategy:
@ -398,186 +284,6 @@ jobs:
name: cross-build-${{ matrix.arch }}-bin
path: install/bin/cppwinrt.exe
test-linux-cross-cppwinrt:
name: 'cross: Test run on Windows'
needs: build-linux-cross-cppwinrt
strategy:
fail-fast: false
matrix:
arch: [i686, x86_64]
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Fetch cppwinrt executable
uses: actions/download-artifact@v3
with:
name: cross-build-${{ matrix.arch }}-bin
path: ./.test
- name: Run cppwinrt to build projection
run: |
.\.test\cppwinrt.exe -in local -out .\.test\out -verbose
- id: setup-llvm
name: Set up llvm-mingw
uses: ./.github/actions/setup-llvm-mingw
with:
host-arch: ${{ matrix.arch }}
- name: Build cppwinrt tests
run: |
mkdir build
cd build
cmake ../test -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug `
-DCPPWINRT_PROJECTION_INCLUDE_DIR="../.test/out" `
-DDOWNLOAD_WINDOWSNUMERICS=TRUE `
-DUSE_ANSI_COLOR=TRUE
cmake --build . -j2
- name: Run tests
run: |
cd build
ctest --verbose
build-linux-native-cppwinrt:
name: 'linux: GCC native build + mingw-w64 cross-build tests'
strategy:
fail-fast: false
matrix:
# TODO: Enable gcc build once Arch Linux gets more recent mingw-w64 headers (ver. 11 perhaps?)
# cross_toolchain: [gcc, llvm-mingw]
cross_toolchain: [llvm-mingw]
cross_arch: [i686, x86_64]
# include:
# - cross_toolchain: gcc
# container:
# image: archlinux:base-devel
runs-on: ubuntu-22.04
container: ${{ matrix.container }}
defaults:
run:
shell: bash
env:
CMAKE_COLOR_DIAGNOSTICS: 1
CLICOLOR_FORCE: 1
steps:
- uses: actions/checkout@v3
- name: Install build tools
if: matrix.cross_toolchain == 'gcc'
run: |
pacman --noconfirm -Suuy
pacman --needed --noconfirm -S cmake ninja git
- name: Build cppwinrt
run: |
cmake -S . -B build/native/ \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_INSTALL_PREFIX=$PWD/install/
cmake --build build/native/ --target install -j2
- name: Test run (cppwinrt -?)
run: |
install/bin/cppwinrt -?
- name: Test run (build projection using Windows.winmd)
run: |
curl -o Windows.winmd -L https://github.com/microsoft/windows-rs/raw/master/crates/libs/bindgen/default/Windows.winmd
install/bin/cppwinrt -in Windows.winmd -out /tmp/cppwinrt -verbose
- id: setup-llvm
name: Set up llvm-mingw
if: matrix.cross_toolchain == 'llvm-mingw'
uses: ./.github/actions/setup-llvm-mingw
- name: Install GCC cross compiler
if: matrix.cross_toolchain == 'gcc'
run: |
pacman --needed --noconfirm -S mingw-w64-gcc
- name: Cross-build tests using projection
run: |
cmake -S test -B build/cross-tests --toolchain "$PWD/cross-mingw-toolchain.cmake" \
-DCMAKE_SYSTEM_PROCESSOR=${{ matrix.cross_arch }} \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="-static" \
-DCPPWINRT_PROJECTION_INCLUDE_DIR=/tmp/cppwinrt \
-DDOWNLOAD_WINDOWSNUMERICS=TRUE \
-DUSE_ANSI_COLOR=TRUE
cmake --build build/cross-tests -j2
- name: Upload built tests
uses: actions/upload-artifact@v3
with:
name: linux-native-cppwinrt-cross-build-tests-${{ matrix.cross_toolchain }}-${{ matrix.cross_arch }}-bin
path: build/cross-tests/*.exe
test-linux-native-cppwinrt-cross-tests:
name: 'linux: Run llvm-mingw cross-build tests'
needs: build-linux-native-cppwinrt
strategy:
fail-fast: false
matrix:
# TODO: Enable gcc build test when it is buildable
# cross_toolchain: [gcc, llvm-mingw]
cross_toolchain: [llvm-mingw]
cross_arch: [i686, x86_64]
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Fetch test executables
uses: actions/download-artifact@v3
with:
name: linux-native-cppwinrt-cross-build-tests-${{ matrix.cross_toolchain }}-${{ matrix.cross_arch }}-bin
path: ./
- name: Run tests
run: |
$test_exes = ls *.exe -Name
$has_failed_tests = 0
foreach ($test_exe in $test_exes) {
echo "::group::Run '$test_exe'"
& .\$test_exe --use-colour yes
echo "::endgroup::"
if ($LastExitCode -ne 0) {
echo "::error::Test '$test_exe' failed!"
$has_failed_tests = 1
}
}
if ($has_failed_tests -ne 0) {
exit 1
}
build-macos-native-cppwinrt:
name: 'macOS: GCC native build'
runs-on: macos-latest
defaults:
run:
shell: bash
env:
CMAKE_COLOR_DIAGNOSTICS: 1
CLICOLOR_FORCE: 1
steps:
- uses: actions/checkout@v3
- name: Build cppwinrt
run: |
cmake -S . -B build/native/ \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_INSTALL_PREFIX=$PWD/install/
cmake --build build/native/ --target install -j2
- name: Test run (cppwinrt -?)
run: |
install/bin/cppwinrt -?
- name: Test run (build projection using Windows.winmd)
run: |
curl -o Windows.winmd -L https://github.com/microsoft/windows-rs/raw/master/crates/libs/bindgen/default/Windows.winmd
install/bin/cppwinrt -in Windows.winmd -out build/out -verbose
build-msvc-natvis:
name: 'Build natvis'
strategy:

Просмотреть файл

@ -22,10 +22,6 @@ jobs:
TestExe: 'test_cpp20_no_sourcelocation'
TestProject: 'test_cpp20_no_sourcelocation'
BuildPlatform: 'x86'
test_win7.x86:
TestExe: 'test_win7'
TestProject: 'test_win7'
BuildPlatform: 'x86'
test_fast.x86:
TestExe: 'test_fast'
TestProject: 'test_fast'

Просмотреть файл

@ -32,7 +32,6 @@ call msbuild /p:Configuration=%target_configuration%,Platform=%target_platform%,
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_cpp20
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_cpp20_no_sourcelocation
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_win7
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_fast
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_slow
call msbuild /m /p:Configuration=%target_configuration%,Platform=%target_platform%,CppWinRTBuildVersion=%target_version% cppwinrt.sln /t:test\test_module_lock_custom

Просмотреть файл

@ -104,13 +104,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_module_lock_custom", "
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{3C7EA5F8-6E8C-4376-B499-2CAF596384B0}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_win7", "test\test_win7\test_win7.vcxproj", "{2EF696B9-7F4A-410F-AE5C-5301565C0F08}"
ProjectSection(ProjectDependencies) = postProject
{A91B8BF3-28E4-4D9E-8DBA-64B70E4F0270} = {A91B8BF3-28E4-4D9E-8DBA-64B70E4F0270}
{D613FB39-5035-4043-91E2-BAB323908AF4} = {D613FB39-5035-4043-91E2-BAB323908AF4}
{F1C915B3-2C64-4992-AFB7-7F035B1A7607} = {F1C915B3-2C64-4992-AFB7-7F035B1A7607}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_cpp20", "test\test_cpp20\test_cpp20.vcxproj", "{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}"
ProjectSection(ProjectDependencies) = postProject
{A91B8BF3-28E4-4D9E-8DBA-64B70E4F0270} = {A91B8BF3-28E4-4D9E-8DBA-64B70E4F0270}
@ -452,22 +445,6 @@ Global
{08C40663-B6A3-481E-8755-AE32BAD99501}.Release|x64.Build.0 = Release|x64
{08C40663-B6A3-481E-8755-AE32BAD99501}.Release|x86.ActiveCfg = Release|Win32
{08C40663-B6A3-481E-8755-AE32BAD99501}.Release|x86.Build.0 = Release|Win32
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|ARM.ActiveCfg = Debug|ARM
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|ARM.Build.0 = Debug|ARM
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|ARM64.ActiveCfg = Debug|ARM64
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|ARM64.Build.0 = Debug|ARM64
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|x64.ActiveCfg = Debug|x64
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|x64.Build.0 = Debug|x64
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|x86.ActiveCfg = Debug|Win32
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Debug|x86.Build.0 = Debug|Win32
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|ARM.ActiveCfg = Release|ARM
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|ARM.Build.0 = Release|ARM
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|ARM64.ActiveCfg = Release|ARM64
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|ARM64.Build.0 = Release|ARM64
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|x64.ActiveCfg = Release|x64
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|x64.Build.0 = Release|x64
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|x86.ActiveCfg = Release|Win32
{2EF696B9-7F4A-410F-AE5C-5301565C0F08}.Release|x86.Build.0 = Release|Win32
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Debug|ARM.ActiveCfg = Debug|ARM
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Debug|ARM.Build.0 = Debug|ARM
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA}.Debug|ARM64.ActiveCfg = Debug|ARM64
@ -521,7 +498,6 @@ Global
{303CC0FE-7D66-4F9F-B7A1-0AF7F9359074} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0}
{D48A96C2-8512-4CC3-B6E4-7CFF07ED8ED3} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0}
{08C40663-B6A3-481E-8755-AE32BAD99501} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0}
{2EF696B9-7F4A-410F-AE5C-5301565C0F08} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0}
{5FF6CD6C-515A-4D55-97B6-62AD9BCB77EA} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0}
{D4C8F881-84D5-4A7B-8BDE-AB4E34A05374} = {3C7EA5F8-6E8C-4376-B499-2CAF596384B0}
EndGlobalSection

Просмотреть файл

@ -11,7 +11,6 @@ if "%target_configuration%"=="" set target_configuration=Debug
call :run_test test
call :run_test test_cpp20
call :run_test test_cpp20_no_sourcelocation
call :run_test test_win7
call :run_test test_fast
call :run_test test_slow
call :run_test test_old

Просмотреть файл

@ -18,13 +18,6 @@ namespace winrt::impl
using library_handle = handle_type<library_traits>;
inline int32_t __stdcall fallback_RoGetActivationFactory(void*, guid const&, void** factory) noexcept
{
*factory = nullptr;
return error_class_not_available;
}
template <bool isSameInterfaceAsIActivationFactory>
WINRT_IMPL_NOINLINE hresult get_runtime_activation_factory_impl(param::hstring const& name, winrt::guid const& guid, void** result) noexcept
{
@ -33,9 +26,7 @@ namespace winrt::impl
return winrt_activation_handler(*(void**)(&name), guid, result);
}
static int32_t(__stdcall * handler)(void* classId, winrt::guid const& iid, void** factory) noexcept;
impl::load_runtime_function(L"combase.dll", "RoGetActivationFactory", handler, fallback_RoGetActivationFactory);
hresult hr = handler(*(void**)(&name), guid, result);
hresult hr = WINRT_IMPL_RoGetActivationFactory(*(void**)(&name), guid, result);
if (hr == impl::error_not_initialized)
{
@ -48,7 +39,7 @@ namespace winrt::impl
void* cookie;
usage(&cookie);
hr = handler(*(void**)(&name), guid, result);
hr = WINRT_IMPL_RoGetActivationFactory(*(void**)(&name), guid, result);
}
if (hr == 0)

Просмотреть файл

@ -131,54 +131,9 @@ namespace winrt::impl
return WINRT_IMPL_LoadLibraryExW(library, nullptr, 0x00001000 /* LOAD_LIBRARY_SEARCH_DEFAULT_DIRS */);
}
template <typename F, typename L>
void load_runtime_function(wchar_t const* library, char const* name, F& result, L fallback) noexcept
{
if (result)
{
return;
}
result = reinterpret_cast<F>(WINRT_IMPL_GetProcAddress(load_library(library), name));
if (result)
{
return;
}
result = fallback;
}
inline int32_t __stdcall fallback_RoGetAgileReference(uint32_t, winrt::guid const& iid, void* object, void** reference) noexcept
{
*reference = nullptr;
static constexpr guid git_clsid{ 0x00000323, 0x0000, 0x0000, { 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 } };
com_ptr<IGlobalInterfaceTable> git;
hresult hr = WINRT_IMPL_CoCreateInstance(git_clsid, nullptr, 1 /*CLSCTX_INPROC_SERVER*/, guid_of<IGlobalInterfaceTable>(), git.put_void());
if (hr < 0)
{
return hr;
}
uint32_t cookie{};
hr = git->RegisterInterfaceInGlobal(object, iid, &cookie);
if (hr < 0)
{
return hr;
}
*reference = new agile_ref_fallback(std::move(git), cookie);
return 0;
}
inline hresult get_agile_reference(winrt::guid const& iid, void* object, void** reference) noexcept
{
static int32_t(__stdcall * handler)(uint32_t options, winrt::guid const& iid, void* object, void** reference) noexcept;
load_runtime_function(L"combase.dll", "RoGetAgileReference", handler, fallback_RoGetAgileReference);
return handler(0, iid, object, reference);
return WINRT_IMPL_RoGetAgileReference(0, iid, object, reference);
}
}

Просмотреть файл

@ -409,17 +409,9 @@ namespace winrt::impl
}
}
static int32_t __stdcall fallback_SetThreadpoolTimerEx(winrt::impl::ptp_timer, void*, uint32_t, uint32_t) noexcept
{
return 0; // pretend timer has already triggered and a callback is on its way
}
void fire_immediately() noexcept
{
static int32_t(__stdcall * handler)(winrt::impl::ptp_timer, void*, uint32_t, uint32_t) noexcept;
impl::load_runtime_function(L"kernel32.dll", "SetThreadpoolTimerEx", handler, fallback_SetThreadpoolTimerEx);
if (handler(m_timer.get(), nullptr, 0, 0))
if (WINRT_IMPL_SetThreadpoolTimerEx(m_timer.get(), nullptr, 0, 0))
{
int64_t now = 0;
WINRT_IMPL_SetThreadpoolTimer(m_timer.get(), &now, 0, 0);
@ -513,10 +505,6 @@ namespace winrt::impl
}
private:
static int32_t __stdcall fallback_SetThreadpoolWaitEx(winrt::impl::ptp_wait, void*, void*, void*) noexcept
{
return 0; // pretend wait has already triggered and a callback is on its way
}
void create_threadpool_wait()
{
@ -534,10 +522,7 @@ namespace winrt::impl
void fire_immediately() noexcept
{
static int32_t(__stdcall * handler)(winrt::impl::ptp_wait, void*, void*, void*) noexcept;
impl::load_runtime_function(L"kernel32.dll", "SetThreadpoolWaitEx", handler, fallback_SetThreadpoolWaitEx);
if (handler(m_wait.get(), nullptr, nullptr, nullptr))
if (WINRT_IMPL_SetThreadpoolWaitEx(m_wait.get(), nullptr, nullptr, nullptr))
{
int64_t now = 0;
WINRT_IMPL_SetThreadpoolWait(m_wait.get(), WINRT_IMPL_GetCurrentProcess(), &now);

Просмотреть файл

@ -175,11 +175,6 @@ namespace winrt::impl
hstring const m_message;
atomic_ref_count m_references{ 1 };
};
[[noreturn]] inline void __stdcall fallback_RoFailFastWithErrorContext(int32_t) noexcept
{
abort();
}
}
WINRT_EXPORT namespace winrt
@ -301,18 +296,9 @@ WINRT_EXPORT namespace winrt
private:
static int32_t __stdcall fallback_RoOriginateLanguageException(int32_t error, void* message, void*) noexcept
{
com_ptr<impl::IErrorInfo> info(new (std::nothrow) impl::error_info_fallback(error, message), take_ownership_from_abi);
WINRT_VERIFY_(0, WINRT_IMPL_SetErrorInfo(0, info.get()));
return 1;
}
void originate(hresult const code, void* message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept
{
static int32_t(__stdcall* handler)(int32_t error, void* message, void* exception) noexcept;
impl::load_runtime_function(L"combase.dll", "RoOriginateLanguageException", handler, fallback_RoOriginateLanguageException);
WINRT_VERIFY(handler(code, message, nullptr));
WINRT_VERIFY(WINRT_IMPL_RoOriginateLanguageException(code, message, nullptr));
// This is an extension point that can be filled in by other libraries (such as WIL) to get call outs when errors are
// originated. This is intended for logging purposes. When possible include the std::source_information so that accurate
@ -642,9 +628,7 @@ WINRT_EXPORT namespace winrt
[[noreturn]] inline void terminate() noexcept
{
static void(__stdcall * handler)(int32_t) noexcept;
impl::load_runtime_function(L"combase.dll", "RoFailFastWithErrorContext", handler, impl::fallback_RoFailFastWithErrorContext);
handler(to_hresult());
WINRT_IMPL_RoFailFastWithErrorContext(to_hresult());
abort();
}
}

Просмотреть файл

@ -337,18 +337,10 @@ namespace winrt::impl
return { new(raw) event_array<T>(capacity), take_ownership_from_abi };
}
inline int32_t __stdcall fallback_RoTransformError(int32_t, int32_t, void*) noexcept
{
return 1;
}
WINRT_IMPL_NOINLINE inline bool report_failed_invoke()
{
int32_t const code = to_hresult();
static int32_t(__stdcall * handler)(int32_t, int32_t, void*) noexcept;
impl::load_runtime_function(L"combase.dll", "RoTransformError", handler, fallback_RoTransformError);
handler(code, 0, nullptr);
WINRT_IMPL_RoTransformError(code, 0, nullptr);
if (code == static_cast<int32_t>(0x80010108) || // RPC_E_DISCONNECTED
code == static_cast<int32_t>(0x800706BA) || // HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE)

Просмотреть файл

@ -24,6 +24,14 @@ __declspec(selectany) int32_t(__stdcall* winrt_activation_handler)(void* classId
extern "C"
{
int32_t __stdcall WINRT_IMPL_RoGetActivationFactory(void* classId, winrt::guid const& iid, void** factory) noexcept WINRT_IMPL_LINK(RoGetActivationFactory, 12);
int32_t __stdcall WINRT_IMPL_RoGetAgileReference(uint32_t options, winrt::guid const& iid, void* object, void** reference) noexcept WINRT_IMPL_LINK(RoGetAgileReference, 16);
int32_t __stdcall WINRT_IMPL_SetThreadpoolTimerEx(winrt::impl::ptp_timer, void*, uint32_t, uint32_t) noexcept WINRT_IMPL_LINK(SetThreadpoolTimerEx, 16);
int32_t __stdcall WINRT_IMPL_SetThreadpoolWaitEx(winrt::impl::ptp_wait, void*, void*, void*) noexcept WINRT_IMPL_LINK(SetThreadpoolWaitEx, 16);
int32_t __stdcall WINRT_IMPL_RoOriginateLanguageException(int32_t error, void* message, void* exception) noexcept WINRT_IMPL_LINK(RoOriginateLanguageException, 12);
void __stdcall WINRT_IMPL_RoFailFastWithErrorContext(int32_t) noexcept WINRT_IMPL_LINK(RoFailFastWithErrorContext, 4);
int32_t __stdcall WINRT_IMPL_RoTransformError(int32_t, int32_t, void*) noexcept WINRT_IMPL_LINK(RoTransformError, 12);
void* __stdcall WINRT_IMPL_LoadLibraryExW(wchar_t const* name, void* unused, uint32_t flags) noexcept WINRT_IMPL_LINK(LoadLibraryExW, 12);
int32_t __stdcall WINRT_IMPL_FreeLibrary(void* library) noexcept WINRT_IMPL_LINK(FreeLibrary, 4);
void* __stdcall WINRT_IMPL_GetProcAddress(void* library, char const* name) noexcept WINRT_IMPL_LINK(GetProcAddress, 8);

Просмотреть файл

@ -107,7 +107,6 @@ set(SKIP_LARGE_PCH FALSE CACHE BOOL "Skip building large precompiled headers.")
add_subdirectory(test)
add_subdirectory(test_cpp20)
add_subdirectory(test_cpp20_no_sourcelocation)
add_subdirectory(test_win7)
if(HAS_WINDOWSNUMERICS)
add_subdirectory(old_tests)

Просмотреть файл

@ -1,68 +0,0 @@
file(GLOB TEST_SRCS
LIST_DIRECTORIES false
CONFIGURE_DEPENDS
*.cpp
)
list(FILTER TEST_SRCS EXCLUDE REGEX "/(main|pch)\\.cpp")
# We can't build test_component[*] for mingw-w64 because it doesn't have an
# alternative to midl that can produce winmd files. Also, even if we do manage
# to reuse the MSVC-compiled binaries, mingw-w64 is still missing
# windowsnumerics.impl.h which is needed to provide the types
# winrt::Windows::Foundation::Numerics::float2 and friends that the components
# use.
list(APPEND BROKEN_TESTS
agility
delegates
enum
in_params
no_make_detection
noexcept
out_params
parent_includes
return_params
structs
uniform_in_params
velocity
)
list(APPEND BROKEN_TESTS
# depends on pplawait.h
when
)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# FIXME: GCC does not compile co_await on thread_pool because it wants
# a copy constructor. Disabling this test for now.
# This might be related to upstream bug:
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103963
list(APPEND BROKEN_TESTS
thread_pool
)
endif()
# Exclude broken tests
foreach(TEST_SRCS_EXCLUDE_ITEM IN LISTS BROKEN_TESTS)
list(FILTER TEST_SRCS EXCLUDE REGEX "/${TEST_SRCS_EXCLUDE_ITEM}\\.cpp")
endforeach()
add_executable(test_win7 main.cpp ${TEST_SRCS})
target_precompile_headers(test_win7 PRIVATE pch.h)
set_source_files_properties(
main.cpp
coro_foundation.cpp
coro_threadpool.cpp
generic_type_names.cpp
inspectable_interop.cpp
module_lock_dll.cpp
PROPERTIES SKIP_PRECOMPILE_HEADERS true
)
add_dependencies(test_win7 build-cppwinrt-projection)
add_test(
NAME test_win7
COMMAND "$<TARGET_FILE:test_win7>" ${TEST_COLOR_ARG}
)

Просмотреть файл

@ -1,382 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation::Collections;
//
// Now that all of the generics are generated (rather than hand-written), it's far less likely
// that something like GetMany is incorrect. And the "FillArray" pattern used by GetMany is
// tested elsewhere in the out_params and return_params tests. However since C++/WinRT provides
// an implementation of GetMany over and above the projection, these tests validate the this
// implementation is correct. Other tests exist for collections under 'old_tests' but new
// optimizations are coming for GetMany and I want to make sure that GetMany is completely
// covered.
//
namespace
{
template<typename T>
IIterator<T> single_threaded_generator(std::vector<T>&& values = {})
{
// This iterator may only be advanced once, ensuring the GetMany complexity optimization
// is actually enforced with this test.
struct generator_container
{
explicit generator_container(IIterator<T> const& first) : m_current(first)
{
if (!m_current.HasCurrent())
{
m_current = nullptr;
}
}
IIterator<T> begin() const { return m_current; }
IIterator<T> end() const { return nullptr; }
private:
IIterator<T> m_current;
};
struct generator : implements<generator, IIterable<T>>, iterable_base<generator, T>
{
explicit generator(IIterator<T> const& first) : m_container(first)
{
}
auto& get_container() noexcept
{
return m_container;
}
auto& get_container() const noexcept
{
return m_container;
}
private:
generator_container m_container;
};
auto v = single_threaded_vector<T>(std::move(values));
return make<generator>(v.First()).First();
}
}
TEST_CASE("GetMany")
{
// All
{
auto v = single_threaded_vector<int>({ 1,2,3 });
std::array<int, 3> buffer{ 0xCC, 0xCC, 0xCC };
REQUIRE(3 == v.GetMany(0, buffer));
REQUIRE(buffer[0] == 1);
REQUIRE(buffer[1] == 2);
REQUIRE(buffer[2] == 3);
}
{
auto v = single_threaded_vector<int>({ 1,2,3 });
std::array<int, 3> buffer{ 0xCC, 0xCC, 0xCC };
REQUIRE(3 == v.First().GetMany(buffer));
REQUIRE(buffer[0] == 1);
REQUIRE(buffer[1] == 2);
REQUIRE(buffer[2] == 3);
}
// None
{
auto v = single_threaded_vector<int>({ 1,2,3 });
std::array<int, 3> buffer{ 0xCC, 0xCC, 0xCC };
REQUIRE(0 == v.GetMany(3, buffer));
REQUIRE(buffer[0] == 0xCC);
REQUIRE(buffer[1] == 0xCC);
REQUIRE(buffer[2] == 0xCC);
}
{
auto v = single_threaded_vector<int>({ 1,2,3,4 });
auto pos = v.First();
std::array<int, 3> buffer{ 0xCC, 0xCC, 0xCC };
REQUIRE(3 == pos.GetMany(buffer));
REQUIRE(buffer[0] == 1);
REQUIRE(buffer[1] == 2);
REQUIRE(buffer[2] == 3);
buffer = { 0xCC, 0xCC, 0xCC };
REQUIRE(1 == pos.GetMany(buffer));
REQUIRE(buffer[0] == 4);
REQUIRE(buffer[1] == 0xCC);
REQUIRE(buffer[2] == 0xCC);
buffer = { 0xCC, 0xCC, 0xCC };
REQUIRE(0 == pos.GetMany(buffer));
REQUIRE(buffer[0] == 0xCC);
REQUIRE(buffer[1] == 0xCC);
REQUIRE(buffer[2] == 0xCC);
}
// Less
{
auto v = single_threaded_vector<int>({ 1,2,3 });
std::array<int, 2> buffer{ 0xCC, 0xCC };
REQUIRE(2 == v.GetMany(0, buffer));
REQUIRE(buffer[0] == 1);
REQUIRE(buffer[1] == 2);
}
{
auto v = single_threaded_vector<int>({ 1,2,3 });
std::array<int, 2> buffer{ 0xCC, 0xCC };
REQUIRE(2 == v.First().GetMany(buffer));
REQUIRE(buffer[0] == 1);
REQUIRE(buffer[1] == 2);
}
// More
{
auto v = single_threaded_vector<int>({ 1,2,3 });
std::array<int, 4> buffer{ 0xCC, 0xCC, 0xCC, 0xCC };
REQUIRE(3 == v.GetMany(0, buffer));
REQUIRE(buffer[0] == 1);
REQUIRE(buffer[1] == 2);
REQUIRE(buffer[2] == 3);
REQUIRE(buffer[3] == 0xCC);
}
{
auto v = single_threaded_vector<int>({ 1,2,3 });
std::array<int, 4> buffer{ 0xCC, 0xCC, 0xCC, 0xCC };
REQUIRE(3 == v.First().GetMany(buffer));
REQUIRE(buffer[0] == 1);
REQUIRE(buffer[1] == 2);
REQUIRE(buffer[2] == 3);
REQUIRE(buffer[3] == 0xCC);
}
// Offset
{
auto v = single_threaded_vector<int>({ 1,2,3 });
std::array<int, 4> buffer{ 0xCC, 0xCC, 0xCC, 0xCC };
REQUIRE(2 == v.GetMany(1, buffer));
REQUIRE(buffer[0] == 2);
REQUIRE(buffer[1] == 3);
REQUIRE(buffer[2] == 0xCC);
REQUIRE(buffer[3] == 0xCC);
}
// The same tests but with a non-trivially destructible type...
// All
{
auto v = single_threaded_vector<hstring>({ L"1",L"2",L"3" });
std::array<hstring, 3> buffer{ L"old", L"old", L"old" };
REQUIRE(3 == v.GetMany(0, buffer));
REQUIRE(buffer[0] == L"1");
REQUIRE(buffer[1] == L"2");
REQUIRE(buffer[2] == L"3");
}
{
auto v = single_threaded_vector<hstring>({ L"1",L"2",L"3" });
std::array<hstring, 3> buffer{ L"old", L"old", L"old" };
REQUIRE(3 == v.First().GetMany(buffer));
REQUIRE(buffer[0] == L"1");
REQUIRE(buffer[1] == L"2");
REQUIRE(buffer[2] == L"3");
}
// None
{
auto v = single_threaded_vector<hstring>({ L"1",L"2",L"3" });
std::array<hstring, 3> buffer{ L"old", L"old", L"old" };
REQUIRE(0 == v.GetMany(3, buffer));
REQUIRE(buffer[0] == L"");
REQUIRE(buffer[1] == L"");
REQUIRE(buffer[2] == L"");
}
{
auto v = single_threaded_vector<hstring>({ L"1",L"2",L"3",L"4" });
auto pos = v.First();
std::array<hstring, 3> buffer{ L"old", L"old", L"old" };
REQUIRE(3 == pos.GetMany(buffer));
REQUIRE(buffer[0] == L"1");
REQUIRE(buffer[1] == L"2");
REQUIRE(buffer[2] == L"3");
buffer = { L"old", L"old", L"old" };
REQUIRE(1 == pos.GetMany(buffer));
REQUIRE(buffer[0] == L"4");
REQUIRE(buffer[1] == L"");
REQUIRE(buffer[2] == L"");
buffer = { L"old", L"old", L"old" };
REQUIRE(0 == pos.GetMany(buffer));
REQUIRE(buffer[0] == L"");
REQUIRE(buffer[1] == L"");
REQUIRE(buffer[2] == L"");
}
// Less
{
auto v = single_threaded_vector<hstring>({ L"1",L"2",L"3" });
std::array<hstring, 2> buffer{ L"old", L"old" };
REQUIRE(2 == v.GetMany(0, buffer));
REQUIRE(buffer[0] == L"1");
REQUIRE(buffer[1] == L"2");
}
{
auto v = single_threaded_vector<hstring>({ L"1",L"2",L"3" });
std::array<hstring, 2> buffer{ L"old", L"old" };
REQUIRE(2 == v.First().GetMany(buffer));
REQUIRE(buffer[0] == L"1");
REQUIRE(buffer[1] == L"2");
}
// More
{
auto v = single_threaded_vector<hstring>({ L"1",L"2",L"3" });
std::array<hstring, 4> buffer{ L"old", L"old", L"old", L"old" };
REQUIRE(3 == v.GetMany(0, buffer));
REQUIRE(buffer[0] == L"1");
REQUIRE(buffer[1] == L"2");
REQUIRE(buffer[2] == L"3");
REQUIRE(buffer[3] == L"");
}
{
auto v = single_threaded_vector<hstring>({ L"1",L"2",L"3" });
std::array<hstring, 4> buffer{ L"old", L"old", L"old", L"old" };
REQUIRE(3 == v.First().GetMany(buffer));
REQUIRE(buffer[0] == L"1");
REQUIRE(buffer[1] == L"2");
REQUIRE(buffer[2] == L"3");
REQUIRE(buffer[3] == L"");
}
// Offset
{
auto v = single_threaded_vector<hstring>({ L"1",L"2",L"3" });
std::array<hstring, 4> buffer{ L"old", L"old", L"old", L"old" };
REQUIRE(2 == v.GetMany(1, buffer));
REQUIRE(buffer[0] == L"2");
REQUIRE(buffer[1] == L"3");
REQUIRE(buffer[2] == L"");
REQUIRE(buffer[3] == L"");
}
// FIXME: Fail to compile with Clang due to recursive template instantiation using single_threaded_generator.
#if !defined(__clang__)
// Similar tests but with a list to ensure optimal code gen for containers that don't offer random access.
// All
{
IIterator<int> v = single_threaded_generator<int>({ 1,2,3 });
std::array<int, 3> buffer{ 0xCC, 0xCC, 0xCC };
REQUIRE(3 == v.GetMany(buffer));
REQUIRE(buffer[0] == 1);
REQUIRE(buffer[1] == 2);
REQUIRE(buffer[2] == 3);
}
// None
{
IIterator<int> v = single_threaded_generator<int>({ 1,2,3,4,5 });
std::array<int, 3> buffer{ 0xCC, 0xCC, 0xCC };
REQUIRE(3 == v.GetMany(buffer));
REQUIRE(buffer[0] == 1);
REQUIRE(buffer[1] == 2);
REQUIRE(buffer[2] == 3);
buffer = { 0xCC, 0xCC, 0xCC };
REQUIRE(2 == v.GetMany(buffer));
REQUIRE(buffer[0] == 4);
REQUIRE(buffer[1] == 5);
REQUIRE(buffer[2] == 0xCC);
buffer = { 0xCC, 0xCC, 0xCC };
REQUIRE(0 == v.GetMany(buffer));
REQUIRE(buffer[0] == 0xCC);
REQUIRE(buffer[1] == 0xCC);
REQUIRE(buffer[2] == 0xCC);
}
// Less
{
IIterator<int> v = single_threaded_generator<int>({ 1,2,3 });
std::array<int, 2> buffer{ 0xCC, 0xCC };
REQUIRE(2 == v.GetMany(buffer));
REQUIRE(buffer[0] == 1);
REQUIRE(buffer[1] == 2);
}
// More
{
IIterator<int> v = single_threaded_generator<int>({ 1,2,3 });
std::array<int, 4> buffer{ 0xCC, 0xCC, 0xCC, 0xCC };
REQUIRE(3 == v.GetMany(buffer));
REQUIRE(buffer[0] == 1);
REQUIRE(buffer[1] == 2);
REQUIRE(buffer[2] == 3);
REQUIRE(buffer[3] == 0xCC);
}
// The same tests but with a non-trivially destructible type...
// All
{
IIterator<hstring> v = single_threaded_generator<hstring>({ L"1",L"2",L"3" });
std::array<hstring, 3> buffer{ L"old", L"old", L"old" };
REQUIRE(3 == v.GetMany(buffer));
REQUIRE(buffer[0] == L"1");
REQUIRE(buffer[1] == L"2");
REQUIRE(buffer[2] == L"3");
}
// None
{
IIterator<hstring> v = single_threaded_generator<hstring>({ L"1",L"2",L"3",L"4" });
std::array<hstring, 3> buffer{ L"old", L"old", L"old" };
REQUIRE(3 == v.GetMany(buffer));
REQUIRE(buffer[0] == L"1");
REQUIRE(buffer[1] == L"2");
REQUIRE(buffer[2] == L"3");
buffer = { L"old", L"old", L"old" };
REQUIRE(1 == v.GetMany(buffer));
REQUIRE(buffer[0] == L"4");
REQUIRE(buffer[1] == L"");
REQUIRE(buffer[2] == L"");
buffer = { L"old", L"old", L"old" };
REQUIRE(0 == v.GetMany(buffer));
REQUIRE(buffer[0] == L"");
REQUIRE(buffer[1] == L"");
REQUIRE(buffer[2] == L"");
}
// Less
{
IIterator<hstring> v = single_threaded_generator<hstring>({ L"1",L"2",L"3" });
std::array<hstring, 2> buffer{ L"old", L"old" };
REQUIRE(2 == v.GetMany(buffer));
REQUIRE(buffer[0] == L"1");
REQUIRE(buffer[1] == L"2");
}
// More
{
IIterator<hstring> v = single_threaded_generator<hstring>({ L"1",L"2",L"3" });
std::array<hstring, 4> buffer{ L"old", L"old", L"old", L"old" };
REQUIRE(3 == v.GetMany(buffer));
REQUIRE(buffer[0] == L"1");
REQUIRE(buffer[1] == L"2");
REQUIRE(buffer[2] == L"3");
REQUIRE(buffer[3] == L"");
}
#endif
// Pair
{
auto m = single_threaded_map<int, hstring>();
m.Insert(1, L"1");
m.Insert(2, L"2");
m.Insert(3, L"3");
m.Insert(4, L"4");
std::array<IKeyValuePair<int, hstring>, 3> buffer;
REQUIRE(3 == m.First().GetMany(buffer));
REQUIRE(buffer[0].Key() == 1);
REQUIRE(buffer[1].Key() == 2);
REQUIRE(buffer[2].Key() == 3);
REQUIRE(buffer[0].Value() == L"1");
REQUIRE(buffer[1].Value() == L"2");
REQUIRE(buffer[2].Value() == L"3");
}
}

Просмотреть файл

@ -1,293 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
//
// This implemenetation uses the simplest abi_enter and abi_exit methods
//
struct Simple : implements<Simple, IClosable, IStringable>
{
void Close()
{
}
hstring ToString()
{
return L"";
}
void abi_enter()
{
++m_enter;
}
void abi_exit()
{
++m_exit;
}
int m_enter{};
int m_exit{};
};
//
// This implemenetation uses the abi_enter but omits the abi_exit method
//
struct OnlyEnter : implements<OnlyEnter, IClosable, IStringable>
{
void Close()
{
}
hstring ToString()
{
return L"";
}
void abi_enter()
{
++m_enter;
}
int m_enter{};
};
//
// This implemenetation throws from the abi_enter method
//
struct Throwing : implements<Throwing, IClosable, IStringable>
{
void Close()
{
}
hstring ToString()
{
return L"";
}
void abi_enter()
{
throw hresult_wrong_thread();
}
void abi_exit()
{
++m_exit;
}
int m_exit{};
};
//
// This implemenetation provides a nested abi_guard
//
struct NestedGuard : implements<NestedGuard, IClosable, IStringable>
{
void Close()
{
}
hstring ToString()
{
return L"";
}
int m_enter{};
int m_exit{};
struct abi_guard
{
abi_guard(NestedGuard& that) :
m_that(that)
{
++m_that.m_enter;
}
~abi_guard()
{
++m_that.m_exit;
}
private:
NestedGuard& m_that;
};
};
template <typename T>
struct CountGuard
{
CountGuard(T& that) :
m_that(that)
{
++m_that.m_enter;
}
~CountGuard()
{
++m_that.m_exit;
}
private:
T& m_that;
};
//
// This implemenetation use an abi_guard type alias
//
struct GuardAlias : implements<GuardAlias, IClosable, IStringable>
{
void Close()
{
}
hstring ToString()
{
return L"";
}
int m_enter{};
int m_exit{};
using abi_guard = CountGuard<GuardAlias>;
};
template <typename T>
struct ThrowGuard
{
ThrowGuard(T&)
{
throw hresult_wrong_thread();
}
};
//
// This implemenetation use an abi_guard type alias that thows
//
struct ThrowAlias : implements<ThrowAlias, IClosable, IStringable>
{
void Close()
{
}
hstring ToString()
{
return L"";
}
using abi_guard = ThrowGuard<ThrowAlias>;
};
}
TEST_CASE("abi_guard")
{
{
com_ptr<Simple> impl = make_self<Simple>();
impl->Close();
impl->ToString();
REQUIRE(impl->m_enter == 0);
REQUIRE(impl->m_exit == 0);
IClosable closable = impl.as<IClosable>();
closable.Close();
REQUIRE(impl->m_enter == 1);
REQUIRE(impl->m_exit == 1);
IStringable stringable = impl.as<IStringable>();
stringable.ToString();
REQUIRE(impl->m_enter == 2);
REQUIRE(impl->m_exit == 2);
}
{
com_ptr<OnlyEnter> impl = make_self<OnlyEnter>();
impl->Close();
impl->ToString();
REQUIRE(impl->m_enter == 0);
IClosable closable = impl.as<IClosable>();
closable.Close();
REQUIRE(impl->m_enter == 1);
IStringable stringable = impl.as<IStringable>();
stringable.ToString();
REQUIRE(impl->m_enter == 2);
}
{
com_ptr<Throwing> impl = make_self<Throwing>();
impl->Close();
impl->ToString();
IClosable closable = impl.as<IClosable>();
REQUIRE_THROWS_AS(closable.Close(), hresult_wrong_thread);
IStringable stringable = impl.as<IStringable>();
REQUIRE_THROWS_AS(stringable.ToString(), hresult_wrong_thread);
REQUIRE(impl->m_exit == 0);
}
{
com_ptr<NestedGuard> impl = make_self<NestedGuard>();
impl->Close();
impl->ToString();
REQUIRE(impl->m_enter == 0);
REQUIRE(impl->m_exit == 0);
IClosable closable = impl.as<IClosable>();
closable.Close();
REQUIRE(impl->m_enter == 1);
REQUIRE(impl->m_exit == 1);
IStringable stringable = impl.as<IStringable>();
stringable.ToString();
REQUIRE(impl->m_enter == 2);
REQUIRE(impl->m_exit == 2);
}
{
com_ptr<GuardAlias> impl = make_self<GuardAlias>();
impl->Close();
impl->ToString();
REQUIRE(impl->m_enter == 0);
REQUIRE(impl->m_exit == 0);
IClosable closable = impl.as<IClosable>();
closable.Close();
REQUIRE(impl->m_enter == 1);
REQUIRE(impl->m_exit == 1);
IStringable stringable = impl.as<IStringable>();
stringable.ToString();
REQUIRE(impl->m_enter == 2);
REQUIRE(impl->m_exit == 2);
}
{
com_ptr<ThrowAlias> impl = make_self<ThrowAlias>();
impl->Close();
impl->ToString();
IClosable closable = impl.as<IClosable>();
REQUIRE_THROWS_AS(closable.Close(), hresult_wrong_thread);
IStringable stringable = impl.as<IStringable>();
REQUIRE_THROWS_AS(stringable.ToString(), hresult_wrong_thread);
}
}

Просмотреть файл

@ -1,54 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
struct Object : implements<Object, IStringable>
{
hstring ToString()
{
return L"Object";
}
};
}
TEST_CASE("agile_ref")
{
agile_ref<IStringable> ref = make<Object>();
//
// Here we're creating an agile_ref explicitly and using a traditional lambda variable capture
// to pass it to the delegate.
//
delegate<> a = [ref]
{
IStringable object = ref.get();
REQUIRE(object.ToString() == L"Object");
};
a();
//
// Here's we're using the make_agile helper with generalized lambda capture to produce a
// variable local to the lambda.
//
delegate<> b = [ref = make_agile(make<Object>())]
{
IStringable object = ref.get();
REQUIRE(object.ToString() == L"Object");
};
b();
//
// And it's ok to resolve a nullptr agile_ref.
//
agile_ref<IStringable> empty;
IStringable object = empty.get();
REQUIRE(object == nullptr);
}

Просмотреть файл

@ -1,140 +0,0 @@
#include "pch.h"
#include "winrt/test_component.Delegates.h"
//
// These tests confirm the COM identity and other behaviours for agile implementations.
//
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
struct TestAgile : implements<TestAgile, IClosable>
{
bool& m_destroyed;
TestAgile(bool& destroyed) : m_destroyed(destroyed) { m_destroyed = false; }
~TestAgile() { m_destroyed = true; }
void Close() {}
};
struct TestNonAgile : implements<TestNonAgile, non_agile, IClosable>
{
void Close() {}
};
}
TEST_CASE("agility")
{
using Windows::Foundation::IUnknown;
using Windows::Foundation::IInspectable;
// Test agility
{
bool destroyed = false;
{
IInspectable object = make<TestAgile>(destroyed);
// Confirm agility
object.as<IAgileObject>();
// Confirm legacy agility
com_ptr<IMarshal> marshal = object.as<IMarshal>();
// Confirm tear-off identity
IUnknown object_identity = object.as<IUnknown>();
IUnknown marshal_identity = marshal.as<IUnknown>();
REQUIRE(object_identity == marshal_identity);
REQUIRE(!destroyed);
}
// Confirm tear-off does not leak reference
REQUIRE(destroyed);
}
// Test non-agility
{
IInspectable object = make<TestNonAgile>();
// Does not implement IAgileObject
REQUIRE_THROWS_AS(object.as<IAgileObject>(), hresult_no_interface);
// Does not implement IMarshal
REQUIRE_THROWS_AS(object.as<IMarshal>(), hresult_no_interface);
}
// Test IMarshal tearoff lifetime
{
bool destroyed = false;
IInspectable object = make<TestAgile>(destroyed);
com_ptr<IMarshal> marshal = object.as<IMarshal>();
object = nullptr;
REQUIRE(!destroyed);
// Confirm agility (back to object)
marshal.as<IAgileObject>();
// QI on tearoff itself
com_ptr<IMarshal> marshal2 = marshal.as<IMarshal>();
REQUIRE(marshal == marshal2);
marshal2 = nullptr;
// Confirm tear-off does not leak reference
REQUIRE(!destroyed);
marshal = nullptr;
REQUIRE(destroyed);
}
// Test agile delegate
{
IUnknown object = test_component::Delegates::AgileDelegate([] {});
com_ptr<IMarshal> marshal = object.as<IMarshal>();
object = nullptr;
// Confirm agility (back to object)
marshal.as<IAgileObject>();
// QI on tearoff itself
com_ptr<IMarshal> marshal2 = marshal.as<IMarshal>();
REQUIRE(marshal == marshal2);
}
// Test agile weak reference
{
bool destroyed = false;
IClosable object = make<TestAgile>(destroyed);
com_ptr<winrt::impl::IWeakReferenceSource> source = object.as<winrt::impl::IWeakReferenceSource>();
// Clear object but source keeps object alive
object = nullptr;
source.as<IMarshal>();
com_ptr<winrt::impl::IWeakReference> ref;
check_hresult(source->GetWeakReference(ref.put()));
// Drop the source object
REQUIRE(S_OK == ref->Resolve(guid_of<IClosable>(), put_abi(object)));
REQUIRE(object != nullptr);
source = nullptr;
REQUIRE(!destroyed);
object = nullptr;
REQUIRE(destroyed);
REQUIRE(S_OK == ref->Resolve(guid_of<IClosable>(), put_abi(object)));
REQUIRE(object == nullptr);
// Marshaling support on weak ref
com_ptr<IMarshal> marshal = ref.as<IMarshal>();
ref = nullptr;
// Confirm agility (back to object):
marshal.as<IAgileObject>();
// QI on tearoff itself
com_ptr<IMarshal> marshal2 = marshal.as<IMarshal>();
REQUIRE(marshal == marshal2);
}
}

Просмотреть файл

@ -1,84 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
#ifdef __cpp_lib_coroutine
using std::suspend_never;
#else
using std::experimental::suspend_never;
#endif
//
// Checks that the coroutine is automatically canceled when reaching a suspension point.
//
IAsyncAction Action(HANDLE event)
{
co_await resume_on_signal(event);
co_await suspend_never();
REQUIRE(false);
}
IAsyncActionWithProgress<int> ActionWithProgress(HANDLE event)
{
co_await resume_on_signal(event);
co_await suspend_never();
REQUIRE(false);
}
IAsyncOperation<int> Operation(HANDLE event)
{
co_await resume_on_signal(event);
co_await suspend_never();
REQUIRE(false);
co_return 1;
}
IAsyncOperationWithProgress<int, int> OperationWithProgress(HANDLE event)
{
co_await resume_on_signal(event);
co_await suspend_never();
REQUIRE(false);
co_return 1;
}
template <typename F>
void Check(F make)
{
handle start{ CreateEvent(nullptr, true, false, nullptr) };
handle completed{ CreateEvent(nullptr, true, false, nullptr) };
auto async = make(start.get());
REQUIRE(async.Status() == AsyncStatus::Started);
async.Completed([&](auto&& sender, AsyncStatus status)
{
REQUIRE(async == sender);
REQUIRE(status == AsyncStatus::Canceled);
SetEvent(completed.get());
});
async.Cancel();
SetEvent(start.get());
REQUIRE(WaitForSingleObject(completed.get(), 1000) == WAIT_OBJECT_0);
REQUIRE(async.Status() == AsyncStatus::Canceled);
REQUIRE(async.ErrorCode() == HRESULT_FROM_WIN32(ERROR_CANCELLED));
REQUIRE_THROWS_AS(async.GetResults(), hresult_canceled);
}
}
#if defined(__clang__) && defined(_MSC_VER)
// FIXME: Test is known to segfault when built with Clang.
TEST_CASE("async_auto_cancel", "[.clang-crash]")
#else
TEST_CASE("async_auto_cancel")
#endif
{
Check(Action);
Check(ActionWithProgress);
Check(Operation);
Check(OperationWithProgress);
}

Просмотреть файл

@ -1,104 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
#ifdef __cpp_lib_coroutine
using std::suspend_never;
#else
using std::experimental::suspend_never;
#endif
//
// Checks that the cancellation callback is invoked.
//
IAsyncAction Action(HANDLE event, bool& canceled)
{
auto cancel = co_await get_cancellation_token();
cancel.callback([&]
{
REQUIRE(!canceled);
canceled = true;
});
co_await resume_on_signal(event);
co_await suspend_never();
REQUIRE(false);
}
IAsyncActionWithProgress<int> ActionWithProgress(HANDLE event, bool& canceled)
{
auto cancel = co_await get_cancellation_token();
cancel.callback([&]
{
REQUIRE(!canceled);
canceled = true;
});
co_await resume_on_signal(event);
co_await suspend_never();
REQUIRE(false);
}
IAsyncOperation<int> Operation(HANDLE event, bool& canceled)
{
auto cancel = co_await get_cancellation_token();
cancel.callback([&]
{
REQUIRE(!canceled);
canceled = true;
});
co_await resume_on_signal(event);
co_await suspend_never();
REQUIRE(false);
co_return 1;
}
IAsyncOperationWithProgress<int, int> OperationWithProgress(HANDLE event, bool& canceled)
{
auto cancel = co_await get_cancellation_token();
cancel.callback([&]
{
REQUIRE(!canceled);
canceled = true;
});
co_await resume_on_signal(event);
co_await suspend_never();
REQUIRE(false);
co_return 1;
}
template <typename F>
void Check(F make)
{
handle event{ CreateEvent(nullptr, true, false, nullptr) };
bool canceled = false;
auto async = make(event.get(), canceled);
async.Cancel();
REQUIRE(canceled);
SetEvent(event.get());
REQUIRE_THROWS_AS(async.GetResults(), hresult_canceled);
}
}
#if defined(__clang__) && defined(_MSC_VER)
// FIXME: Test is known to segfault when built with Clang.
TEST_CASE("async_cancel_callback", "[.clang-crash]")
#else
TEST_CASE("async_cancel_callback")
#endif
{
Check(Action);
Check(ActionWithProgress);
Check(Operation);
Check(OperationWithProgress);
}

Просмотреть файл

@ -1,118 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
#ifdef __cpp_lib_coroutine
using std::suspend_never;
#else
using std::experimental::suspend_never;
#endif
//
// Checks that manual cancellation checks work.
//
IAsyncAction Action(HANDLE event, bool& canceled)
{
co_await resume_on_signal(event);
auto cancel = co_await get_cancellation_token();
if (cancel())
{
REQUIRE(!canceled);
canceled = true;
}
co_await suspend_never();
REQUIRE(false);
}
IAsyncActionWithProgress<int> ActionWithProgress(HANDLE event, bool& canceled)
{
co_await resume_on_signal(event);
auto cancel = co_await get_cancellation_token();
if (cancel())
{
REQUIRE(!canceled);
canceled = true;
}
co_await suspend_never();
REQUIRE(false);
}
IAsyncOperation<int> Operation(HANDLE event, bool& canceled)
{
co_await resume_on_signal(event);
auto cancel = co_await get_cancellation_token();
if (cancel())
{
REQUIRE(!canceled);
canceled = true;
}
co_await suspend_never();
REQUIRE(false);
co_return 1;
}
IAsyncOperationWithProgress<int, int> OperationWithProgress(HANDLE event, bool& canceled)
{
co_await resume_on_signal(event);
auto cancel = co_await get_cancellation_token();
if (cancel())
{
REQUIRE(!canceled);
canceled = true;
}
co_await suspend_never();
REQUIRE(false);
co_return 1;
}
template <typename F>
void Check(F make)
{
handle start{ CreateEvent(nullptr, true, false, nullptr) };
handle completed{ CreateEvent(nullptr, true, false, nullptr) };
bool canceled = false;
auto async = make(start.get(), canceled);
REQUIRE(async.Status() == AsyncStatus::Started);
async.Completed([&](auto&& sender, AsyncStatus status)
{
REQUIRE(async == sender);
REQUIRE(status == AsyncStatus::Canceled);
REQUIRE(canceled);
SetEvent(completed.get());
});
async.Cancel();
SetEvent(start.get());
REQUIRE(WaitForSingleObject(completed.get(), 1000) == WAIT_OBJECT_0);
REQUIRE(async.Status() == AsyncStatus::Canceled);
REQUIRE(async.ErrorCode() == HRESULT_FROM_WIN32(ERROR_CANCELLED));
REQUIRE_THROWS_AS(async.GetResults(), hresult_canceled);
}
}
#if defined(__clang__) && defined(_MSC_VER)
// FIXME: Test is known to segfault when built with Clang.
TEST_CASE("async_check_cancel", "[.clang-crash]")
#else
TEST_CASE("async_check_cancel")
#endif
{
Check(Action);
Check(ActionWithProgress);
Check(Operation);
Check(OperationWithProgress);
}

Просмотреть файл

@ -1,74 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
//
// Checks that coroutine locals are destroyed prior to notifying waiters.
//
struct Local
{
bool& destroyed;
~Local()
{
REQUIRE(!destroyed);
destroyed = true;
}
};
IAsyncAction Action(HANDLE event, bool& destroyed)
{
co_await resume_on_signal(event);
Local local{ destroyed };
}
IAsyncActionWithProgress<int> ActionWithProgress(HANDLE event, bool& destroyed)
{
co_await resume_on_signal(event);
Local local{ destroyed };
}
IAsyncOperation<int> Operation(HANDLE event, bool& destroyed)
{
co_await resume_on_signal(event);
Local local{ destroyed };
co_return 1;
}
IAsyncOperationWithProgress<int, int> OperationWithProgress(HANDLE event, bool& destroyed)
{
co_await resume_on_signal(event);
Local local{ destroyed };
co_return 1;
}
template <typename F>
void Check(F make)
{
handle start{ CreateEvent(nullptr, true, false, nullptr) };
handle completed{ CreateEvent(nullptr, true, false, nullptr) };
bool destroyed = false;
auto async = make(start.get(), destroyed);
async.Completed([&](auto&&...)
{
REQUIRE(destroyed);
SetEvent(completed.get());
});
SetEvent(start.get());
REQUIRE(WaitForSingleObject(completed.get(), 1000) == WAIT_OBJECT_0);
}
}
TEST_CASE("async_local")
{
Check(Action);
Check(ActionWithProgress);
Check(Operation);
Check(OperationWithProgress);
}

Просмотреть файл

@ -1,85 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
//
// Checks that coroutines lacking suspension points work.
//
IAsyncAction Action()
{
co_return;
}
IAsyncActionWithProgress<int> ActionWithProgress()
{
co_return;
}
IAsyncOperation<int> Operation()
{
co_return 1;
}
IAsyncOperationWithProgress<int, int> OperationWithProgress()
{
co_return 1;
}
IAsyncAction Await()
{
co_await Action();
co_await ActionWithProgress();
co_await Operation();
co_await OperationWithProgress();
}
template <typename T>
void Check(T const& async)
{
REQUIRE(async.Status() == AsyncStatus::Completed);
REQUIRE(async.ErrorCode() == 0);
REQUIRE(async.Id() == 1);
// Should not throw in the Completed state.
async.GetResults();
bool completed = false;
async.Completed([&](auto&& sender, AsyncStatus status)
{
completed = true;
REQUIRE(async == sender);
REQUIRE(status == AsyncStatus::Completed);
});
REQUIRE(completed);
// May only assign Completed handler once.
REQUIRE_THROWS_AS(async.Completed([&](auto && ...) {}), hresult_illegal_delegate_assignment);
// Close does nothing.
async.Close();
// Harmless but too late to cancel.
async.Cancel();
REQUIRE(async.Status() == AsyncStatus::Completed);
}
}
TEST_CASE("async_no_suspend")
{
Action().get();
ActionWithProgress().get();
Operation().get();
OperationWithProgress().get();
Await().get();
Check(Action());
Check(ActionWithProgress());
Check(Operation());
Check(OperationWithProgress());
}

Просмотреть файл

@ -1,82 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
//
// Checks that progress reporting works.
//
IAsyncActionWithProgress<int> Action(HANDLE event)
{
co_await resume_on_signal(event);
auto progress = co_await get_progress_token();
progress(123);
}
IAsyncOperationWithProgress<int, int> Operation(HANDLE event)
{
co_await resume_on_signal(event);
auto progress = co_await get_progress_token();
progress(123);
co_return 1;
}
template <typename F>
IAsyncAction Check(F make)
{
// Event not set to allow Progress handler to be wired up.
handle start{ CreateEvent(nullptr, true, false, nullptr) };
auto async = make(start.get());
bool progress = false;
async.Progress([&](auto&& sender, int value)
{
progress = true;
REQUIRE(async == sender);
REQUIRE(value == 123);
});
SetEvent(start.get());
co_await async;
REQUIRE(progress);
REQUIRE(async.Status() == AsyncStatus::Completed);
REQUIRE(async.ErrorCode() == S_OK);
}
template <typename F>
IAsyncAction TooLate(F make)
{
// Event initially set so that coroutine does not suspend.
handle start{ CreateEvent(nullptr, true, true, nullptr) };
auto async = make(start.get());
REQUIRE(async.Status() == AsyncStatus::Completed);
bool progress = false;
async.Progress([&](auto&&...)
{
REQUIRE(false);
});
co_await async;
REQUIRE(!progress);
REQUIRE(async.Status() == AsyncStatus::Completed);
REQUIRE(async.ErrorCode() == S_OK);
}
}
TEST_CASE("async_progress")
{
Check(Action);
Check(Operation);
TooLate(Action);
TooLate(Operation);
}

Просмотреть файл

@ -1,86 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
//
// Checks that result values are propagated properly.
//
IAsyncOperation<int> Operation(HANDLE event)
{
co_await resume_on_signal(event);
co_return 123;
}
IAsyncOperationWithProgress<int, int> OperationWithProgress(HANDLE event)
{
co_await resume_on_signal(event);
co_return 123;
}
IAsyncAction Await()
{
// Manual reset so that all waiters will resume and initially set so they won't block.
handle event{ CreateEvent(nullptr, true, true, nullptr) };
int a = co_await Operation(event.get());
int b = co_await OperationWithProgress(event.get());
REQUIRE(a == 123);
REQUIRE(b == 123);
}
template <typename F>
void Check(F make)
{
handle start{ CreateEvent(nullptr, true, false, nullptr) };
handle completed{ CreateEvent(nullptr, true, false, nullptr) };
auto async = make(start.get());
REQUIRE(async.Status() == AsyncStatus::Started);
if constexpr (has_async_progress<decltype(async)>)
{
// You're allowed to peek at partial results of IAsyncXxxWithProgress.
REQUIRE_NOTHROW(async.GetResults());
}
else
{
REQUIRE_THROWS_AS(async.GetResults(), hresult_illegal_method_call);
}
async.Completed([&](auto&& sender, AsyncStatus status)
{
REQUIRE(async == sender);
REQUIRE(status == AsyncStatus::Completed);
SetEvent(completed.get());
});
// Still in Started state waiting for signal.
Sleep(100);
REQUIRE(WaitForSingleObject(completed.get(), 0) == WAIT_TIMEOUT);
REQUIRE(async.Status() == AsyncStatus::Started);
// Signal async to run.
SetEvent(start.get());
// Wait for async to complete.
REQUIRE(WaitForSingleObject(completed.get(), 1000) == WAIT_OBJECT_0);
REQUIRE(async.Status() == AsyncStatus::Completed);
REQUIRE(async.ErrorCode() == S_OK);
REQUIRE(async.GetResults() == 123);
}
}
TEST_CASE("async_result")
{
handle start{ CreateEvent(nullptr, true, true, nullptr) };
REQUIRE(123 == Operation(start.get()).get());
REQUIRE(123 == OperationWithProgress(start.get()).get());
Await().get();
Check(Operation);
Check(OperationWithProgress);
}

Просмотреть файл

@ -1,52 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
//
// Checks that return values support both rvalue and lvalue.
//
IAsyncOperation<hstring> Operation(bool rvalue)
{
if (rvalue)
{
hstring value = L"rvalue";
co_return std::move(value);
}
else
{
hstring value = L"lvalue";
co_return value;
}
}
IAsyncOperationWithProgress<hstring, int> OperationWithProgress(bool rvalue)
{
if (rvalue)
{
hstring value = L"rvalue";
co_return std::move(value);
}
else
{
hstring value = L"lvalue";
co_return value;
}
}
template <typename F>
void Check(F make)
{
REQUIRE(make(true).get() == L"rvalue");
REQUIRE(make(false).get() == L"lvalue");
}
}
TEST_CASE("async_return")
{
Check(Operation);
Check(OperationWithProgress);
}

Просмотреть файл

@ -1,98 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
//
// Checks basic suspension behavior.
//
IAsyncAction Action(HANDLE event)
{
co_await resume_on_signal(event);
}
IAsyncActionWithProgress<int> ActionWithProgress(HANDLE event)
{
co_await resume_on_signal(event);
}
IAsyncOperation<int> Operation(HANDLE event)
{
co_await resume_on_signal(event);
co_return 1;
}
IAsyncOperationWithProgress<int, int> OperationWithProgress(HANDLE event)
{
co_await resume_on_signal(event);
co_return 1;
}
IAsyncAction Await()
{
// Manual reset so that all waiters will resume and initially set so they won't block.
handle event{ CreateEvent(nullptr, true, true, nullptr) };
co_await Action(event.get());
co_await ActionWithProgress(event.get());
co_await Operation(event.get());
co_await OperationWithProgress(event.get());
}
template <typename F>
void Check(F make)
{
handle start{ CreateEvent(nullptr, true, false, nullptr) };
handle completed{ CreateEvent(nullptr, true, false, nullptr) };
auto async = make(start.get());
REQUIRE(async.Status() == AsyncStatus::Started);
if constexpr (has_async_progress<decltype(async)>)
{
// You're allowed to peek at partial results of IAsyncXxxWithProgress.
REQUIRE_NOTHROW(async.GetResults());
}
else
{
REQUIRE_THROWS_AS(async.GetResults(), hresult_illegal_method_call);
}
async.Completed([&](auto&& sender, AsyncStatus status)
{
REQUIRE(async == sender);
REQUIRE(status == AsyncStatus::Completed);
SetEvent(completed.get());
});
// Still in Started state waiting for signal.
Sleep(100);
REQUIRE(WaitForSingleObject(completed.get(), 0) == WAIT_TIMEOUT);
REQUIRE(async.Status() == AsyncStatus::Started);
// Signal async to run.
SetEvent(start.get());
// Wait for async to complete.
REQUIRE(WaitForSingleObject(completed.get(), 1000) == WAIT_OBJECT_0);
REQUIRE(async.Status() == AsyncStatus::Completed);
REQUIRE(async.ErrorCode() == S_OK);
}
}
TEST_CASE("async_suspend")
{
handle start{ CreateEvent(nullptr, true, true, nullptr) };
Action(start.get()).get();
ActionWithProgress(start.get()).get();
Operation(start.get()).get();
OperationWithProgress(start.get()).get();
Await().get();
Check(Action);
Check(ActionWithProgress);
Check(Operation);
Check(OperationWithProgress);
}

Просмотреть файл

@ -1,91 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
using namespace std::chrono_literals;
namespace
{
//
// Checks that exceptions are correctly captured and propagated.
//
IAsyncAction Action()
{
co_await 10ms;
throw hresult_invalid_argument(L"Async");
}
IAsyncActionWithProgress<int> ActionWithProgress()
{
co_await 10ms;
throw hresult_invalid_argument(L"Async");
}
IAsyncOperation<int> Operation()
{
co_await 10ms;
throw hresult_invalid_argument(L"Async");
co_return 1;
}
IAsyncOperationWithProgress<int, int> OperationWithProgress()
{
co_await 10ms;
throw hresult_invalid_argument(L"Async");
co_return 1;
}
template <typename F>
void Check(F make)
{
try
{
make().get();
REQUIRE(false);
}
catch (hresult_invalid_argument const& e)
{
REQUIRE(e.message() == L"Async");
}
handle completed{ CreateEvent(nullptr, true, false, nullptr) };
auto async = make();
async.Completed([&](auto&& sender, AsyncStatus status)
{
REQUIRE(async == sender);
REQUIRE(status == AsyncStatus::Error);
SetEvent(completed.get());
});
REQUIRE(WaitForSingleObject(completed.get(), 1000) == WAIT_OBJECT_0);
REQUIRE(async.Status() == AsyncStatus::Error);
hresult_error e(async.ErrorCode(), take_ownership_from_abi);
REQUIRE(e.message() == L"Async");
try
{
async.GetResults();
REQUIRE(false);
}
catch (hresult_invalid_argument const& e)
{
REQUIRE(e.message() == L"Async");
}
}
}
#if defined(__clang__) && defined(_MSC_VER)
// FIXME: Test is known to segfault when built with Clang.
TEST_CASE("async_throw", "[.clang-crash]")
#else
TEST_CASE("async_throw")
#endif
{
Check(Action);
Check(ActionWithProgress);
Check(Operation);
Check(OperationWithProgress);
}

Просмотреть файл

@ -1,141 +0,0 @@
#include "pch.h"
using namespace std::literals;
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
IAsyncAction Action(TimeSpan delay, AsyncStatus result)
{
co_await resume_after(delay);
if (result == AsyncStatus::Error)
{
throw hresult_invalid_argument();
}
if (result == AsyncStatus::Canceled)
{
throw hresult_canceled();
}
}
IAsyncActionWithProgress<int> ActionWithProgress(TimeSpan delay, AsyncStatus result)
{
co_await resume_after(delay);
if (result == AsyncStatus::Error)
{
throw hresult_invalid_argument();
}
if (result == AsyncStatus::Canceled)
{
throw hresult_canceled();
}
}
IAsyncOperation<int> Operation(TimeSpan delay, AsyncStatus result)
{
co_await resume_after(delay);
if (result == AsyncStatus::Error)
{
throw hresult_invalid_argument();
}
if (result == AsyncStatus::Canceled)
{
throw hresult_canceled();
}
co_return 1;
}
IAsyncOperationWithProgress<int, int> OperationWithProgress(TimeSpan delay, AsyncStatus result)
{
co_await resume_after(delay);
if (result == AsyncStatus::Error)
{
throw hresult_invalid_argument();
}
if (result == AsyncStatus::Canceled)
{
throw hresult_canceled();
}
co_return 1;
}
template <typename T>
void check(T const& no_suspend_ok, T const& no_suspend_fail, T const& delay_ok, T const& delay_fail, T const& no_suspend_cancel, T const& delay_cancel, T const& long_delay)
{
REQUIRE(no_suspend_ok.wait_for(0s) == AsyncStatus::Completed);
no_suspend_ok.get();
REQUIRE_THROWS_AS(no_suspend_ok.wait_for(0s), hresult_illegal_delegate_assignment);
REQUIRE(no_suspend_fail.wait_for(0s) == AsyncStatus::Error);
REQUIRE_THROWS_AS(no_suspend_fail.get(), hresult_invalid_argument);
REQUIRE(delay_ok.wait_for(1s) == AsyncStatus::Completed);
delay_ok.get();
REQUIRE(delay_fail.wait_for(1s) == AsyncStatus::Error);
REQUIRE_THROWS_AS(delay_fail.get(), hresult_invalid_argument);
REQUIRE(no_suspend_cancel.wait_for(0s) == AsyncStatus::Canceled);
REQUIRE_THROWS_AS(no_suspend_cancel.get(), hresult_canceled);
REQUIRE(delay_cancel.wait_for(1s) == AsyncStatus::Canceled);
REQUIRE_THROWS_AS(delay_cancel.get(), hresult_canceled);
REQUIRE(long_delay.wait_for(100ms) == AsyncStatus::Started);
}
}
#if defined(__clang__) && defined(_MSC_VER)
// FIXME: Test is known to segfault when built with Clang.
TEST_CASE("async_wait_for", "[.clang-crash]")
#else
TEST_CASE("async_wait_for")
#endif
{
check(
Action(0s, AsyncStatus::Completed),
Action(0s, AsyncStatus::Error),
Action(100ms, AsyncStatus::Completed),
Action(100ms, AsyncStatus::Error),
Action(0s, AsyncStatus::Canceled),
Action(100ms, AsyncStatus::Canceled),
Action(1h, AsyncStatus::Completed));
check(
ActionWithProgress(0s, AsyncStatus::Completed),
ActionWithProgress(0s, AsyncStatus::Error),
ActionWithProgress(100ms, AsyncStatus::Completed),
ActionWithProgress(100ms, AsyncStatus::Error),
ActionWithProgress(0s, AsyncStatus::Canceled),
ActionWithProgress(100ms, AsyncStatus::Canceled),
ActionWithProgress(1h, AsyncStatus::Completed));
check(
Operation(0s, AsyncStatus::Completed),
Operation(0s, AsyncStatus::Error),
Operation(100ms, AsyncStatus::Completed),
Operation(100ms, AsyncStatus::Error),
Operation(0s, AsyncStatus::Canceled),
Operation(100ms, AsyncStatus::Canceled),
Operation(1h, AsyncStatus::Completed));
check(
OperationWithProgress(0s, AsyncStatus::Completed),
OperationWithProgress(0s, AsyncStatus::Error),
OperationWithProgress(100ms, AsyncStatus::Completed),
OperationWithProgress(100ms, AsyncStatus::Error),
OperationWithProgress(0s, AsyncStatus::Canceled),
OperationWithProgress(100ms, AsyncStatus::Canceled),
OperationWithProgress(1h, AsyncStatus::Completed));
}

Просмотреть файл

@ -1,75 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
struct DECLSPEC_UUID("5fb96f8d-409c-42a9-99a7-8a95c1459dbd") ICapture : ::IUnknown
{
virtual int32_t __stdcall GetValue() noexcept = 0;
virtual int32_t __stdcall CreateMemberCapture(int32_t value, GUID const& iid, void** object) noexcept = 0;
};
#ifdef __CRT_UUID_DECL
__CRT_UUID_DECL(ICapture, 0x5fb96f8d, 0x409c, 0x42a9, 0x99, 0xa7, 0x8a, 0x95, 0xc1, 0x45, 0x9d, 0xbd)
#endif
struct Capture : implements<Capture, ICapture, IStringable>
{
int32_t const m_value{};
Capture(int32_t value) :
m_value{ value }
{
}
hstring ToString()
{
return hstring{ std::to_wstring(m_value) };
}
int32_t __stdcall GetValue() noexcept override
{
return m_value;
}
int32_t __stdcall CreateMemberCapture(int32_t value, GUID const& iid, void** object) noexcept override
{
auto capture = make<Capture>(value);
return capture->QueryInterface(iid, object);
}
};
HRESULT __stdcall CreateNonMemberCapture(int value, GUID const& iid, void** object) noexcept
{
auto capture = make<Capture>(value);
return capture->QueryInterface(iid, object);
}
TEST_CASE("capture")
{
com_ptr<ICapture> a = capture<ICapture>(CreateNonMemberCapture, 10);
REQUIRE(a->GetValue() == 10);
a = nullptr;
a.capture(CreateNonMemberCapture, 20);
REQUIRE(a->GetValue() == 20);
com_ptr<ICapture> b = capture<ICapture>(a, &ICapture::CreateMemberCapture, 30);
REQUIRE(b->GetValue() == 30);
b = nullptr;
b.capture(a, &ICapture::CreateMemberCapture, 40);
REQUIRE(b->GetValue() == 40);
IStringable c = capture<IStringable>(CreateNonMemberCapture, 50);
REQUIRE(c.ToString() == L"50");
c = capture<IStringable>(a, &ICapture::CreateMemberCapture, 60);
REQUIRE(c.ToString() == L"60");
com_ptr<IDispatch> d;
REQUIRE_THROWS_AS(capture<IDispatch>(CreateNonMemberCapture, 0), hresult_no_interface);
REQUIRE_THROWS_AS(capture<IClosable>(CreateNonMemberCapture, 0), hresult_no_interface);
REQUIRE_THROWS_AS(d.capture(CreateNonMemberCapture, 0), hresult_no_interface);
REQUIRE_THROWS_AS(capture<IDispatch>(a, &ICapture::CreateMemberCapture, 0), hresult_no_interface);
REQUIRE_THROWS_AS(capture<IClosable>(a, &ICapture::CreateMemberCapture, 0), hresult_no_interface);
REQUIRE_THROWS_AS(d.capture(a, &ICapture::CreateMemberCapture, 0), hresult_no_interface);
}

Просмотреть файл

@ -1,154 +0,0 @@
#include "pch.h"
#include "cmd_reader.h"
#include <fstream>
using namespace cppwinrt;
class response_file
{
const char* resp_file_name = "respfile.txt";
void write_response_file(const char* input)
{
std::ofstream resp_file(resp_file_name);
if (!resp_file.is_open())
FAIL("Response file could not be created");
resp_file << input;
resp_file.close();
}
void remove_response_file()
{
std::remove(resp_file_name);
}
public:
response_file(const char* input)
{
write_response_file(input);
}
template<size_t numOptions>
reader create_reader(size_t const argc, const char* argv[], const option(&options)[numOptions])
{
return reader{ argc, argv, options };
}
~response_file()
{
remove_response_file();
}
};
TEST_CASE("cmd_reader")
{
static constexpr option options[]
{
{ "input", 1 },
{ "reference", 0 },
{ "output", 0, 1 },
{ "component", 0, 1 },
{ "filter", 0 },
{ "name", 0, 1 },
{ "verbose", 0, 0 },
};
// input and output
{
const char* argv[] = { "progname", "-in", "example_file.in", "-out", "example_file.out" };
const size_t argc = 5;
reader args{ argc, argv, options };
REQUIRE(args.exists("input"));
REQUIRE(args.value("input") == "example_file.in");
REQUIRE_FALSE(args.exists("reference"));
REQUIRE(args.exists("output"));
REQUIRE(args.value("output") == "example_file.out");
REQUIRE_FALSE(args.exists("filter"));
REQUIRE_FALSE(args.exists("name"));
REQUIRE_FALSE(args.exists("verbose"));
}
// response file #1: filename no quotes
{
const char* argv[] = { "progname", "@respfile.txt" };
const size_t argc = _countof(argv);
response_file rf{ R"(-in example_file.in -out example_file.out)" };
reader args = rf.create_reader(argc, argv, options);
REQUIRE(args.exists("input"));
REQUIRE(args.value("input") == "example_file.in");
REQUIRE_FALSE(args.exists("reference"));
REQUIRE(args.exists("output"));
REQUIRE(args.value("output") == "example_file.out");
REQUIRE_FALSE(args.exists("filter"));
REQUIRE_FALSE(args.exists("name"));
REQUIRE_FALSE(args.exists("verbose"));
}
// response file #2: filename with quotes
{
const char* argv[] = { "progname", "@respfile.txt" };
const size_t argc = _countof(argv);
response_file rf{ R"(-in "example file.in" -out "example file.out")" };
reader args = rf.create_reader(argc, argv, options);
REQUIRE(args.exists("input"));
REQUIRE(args.value("input") == "example file.in");
REQUIRE_FALSE(args.exists("reference"));
REQUIRE(args.exists("output"));
REQUIRE(args.value("output") == "example file.out");
REQUIRE_FALSE(args.exists("filter"));
REQUIRE_FALSE(args.exists("name"));
REQUIRE_FALSE(args.exists("verbose"));
}
// response file #3: filename with quote within name
{
const char* argv[] = { "progname", "@respfile.txt" };
const size_t argc = _countof(argv);
response_file rf{ R"(-in example\"file.in -out example\"file.out)" };
reader args = rf.create_reader(argc, argv, options);
REQUIRE(args.exists("input"));
REQUIRE(args.value("input") == R"(example"file.in)");
REQUIRE_FALSE(args.exists("reference"));
REQUIRE(args.exists("output"));
REQUIRE(args.value("output") == R"(example"file.out)");
REQUIRE_FALSE(args.exists("filter"));
REQUIRE_FALSE(args.exists("name"));
REQUIRE_FALSE(args.exists("verbose"));
}
// response file #4: really really long path
{
const char* argv[] = { "progname", "@respfile.txt" };
const size_t argc = _countof(argv);
std::string file_name_in(R"(C:\)");
std::string file_name_out(R"(C:\)");
std::string input_str("-in ");
for (int i = 0; i < 500; i++) {
file_name_in.append(R"(dirname\)");
file_name_out.append(R"(dirname\)");
}
file_name_in.append("example_file.in");
file_name_out.append("example_file.out");
input_str.append(file_name_in).append(" -out ").append(file_name_out);
response_file rf{ input_str.data() };
reader args = rf.create_reader(argc, argv, options);
REQUIRE(args.exists("input"));
REQUIRE(args.value("input") == file_name_in);
REQUIRE_FALSE(args.exists("reference"));
REQUIRE(args.exists("output"));
REQUIRE(args.value("output") == file_name_out);
REQUIRE_FALSE(args.exists("filter"));
REQUIRE_FALSE(args.exists("name"));
REQUIRE_FALSE(args.exists("verbose"));
}
}

Просмотреть файл

@ -1,21 +0,0 @@
// Intentionally not using pch...
#include "catch.hpp"
// Only need winrt/Windows.Foundation.h for IAsyncXxx coroutine support
#include "winrt/Windows.Foundation.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
IAsyncOperation<hstring> Async()
{
co_return L"hello";
}
}
TEST_CASE("coro_foundation")
{
REQUIRE(Async().get() == L"hello");
}

Просмотреть файл

@ -1,20 +0,0 @@
// Intentionally not using pch...
#include "catch.hpp"
// Only need winrt/base.h for coroutine thread pool support.
#include "winrt/base.h"
using namespace winrt;
namespace
{
fire_and_forget Async()
{
co_await resume_background();
}
}
TEST_CASE("coro_base")
{
Async();
}

Просмотреть файл

@ -1,52 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
// Some custom exception type unknown to C++/WinRT
struct CustomError
{
};
struct Sample : implements<Sample, IStringable>
{
hstring ToString()
{
// Throw custom exception inside C++/WinRT projection
throw CustomError();
}
};
// Global handler to translate custom exception
int32_t __stdcall handler(void* address) noexcept
{
REQUIRE(address);
try
{
throw;
}
catch (CustomError)
{
return 0x80000018; // E_ILLEGAL_DELEGATE_ASSIGNMENT
}
REQUIRE(false);
return 0;
}
}
TEST_CASE("custom_error")
{
// Set up global handler
REQUIRE(!winrt_to_hresult_handler);
winrt_to_hresult_handler = handler;
// Validate that handler translated exception
REQUIRE_THROWS_AS(make<Sample>().ToString(), hresult_illegal_delegate_assignment);
// Remove global handler
winrt_to_hresult_handler = nullptr;
}

Просмотреть файл

@ -1,72 +0,0 @@
#include "pch.h"
using namespace winrt;
TEST_CASE("delegate")
{
// <>
{
bool invoked = false;
delegate<> d = [&] {invoked = true; };
d();
REQUIRE(invoked);
}
// <int>
{
int result = 0;
delegate<int> d = [&](int a) {result = a; };
d(123);
REQUIRE(result == 123);
}
// <int,int>
{
int result = 0;
delegate<int, int> d = [&](int a, int b) {result = a + b; };
d(4,5);
REQUIRE(result == 9);
}
// void()
{
bool invoked = false;
delegate<void()> d = [&] {invoked = true; };
d();
REQUIRE(invoked);
}
// void(int)
{
int result = 0;
delegate<void(int)> d = [&](int a) {result = a; };
d(123);
REQUIRE(result == 123);
}
// void(int,int)
{
int result = 0;
delegate<void(int,int)> d = [&](int a, int b) {result = a + b; };
d(4, 5);
REQUIRE(result == 9);
}
// int()
{
delegate<int()> d = [] { return 123; };
REQUIRE(d() == 123);
}
// int(int)
{
delegate<int(int)> d = [](int a) {return a; };
REQUIRE(d(123) == 123);
}
// int(int,int)
{
delegate<int(int, int)> d = [](int a, int b) {return a + b; };
REQUIRE(d(4, 5) == 9);
}
}

Просмотреть файл

@ -1,98 +0,0 @@
#include "pch.h"
#include "winrt/test_component.Delegates.h"
using namespace winrt;
using namespace test_component::Delegates;
TEST_CASE("delegates")
{
{
bool run{};
AgileDelegate d = [&] {run = true; };
REQUIRE(!run);
d();
REQUIRE(run);
}
{
hstring value;
InDelegate d = [&](hstring const& in)
{
value = in;
};
REQUIRE(value.empty());
d(L"Test");
REQUIRE(value == L"Test");
}
{
ReturnStringDelegate d = [] {return L"Test"; };
REQUIRE(d() == L"Test");
}
{
ReturnInt32Delegate d = [] {return 123; };
REQUIRE(d() == 123);
}
{
OutStringDelegate d = [](hstring& value)
{
value = L"Test";
};
hstring value;
d(value);
REQUIRE(value == L"Test");
}
{
OutStringDelegate d = [](hstring&)
{
};
hstring value = L"old";
d(value);
REQUIRE(value == L"");
}
{
OutInt32Delegate d = [](int32_t & value)
{
value = 123;
};
int32_t value{ 0xCC };
d(value);
REQUIRE(value == 123);
}
{
OutInt32Delegate d = [](int32_t&)
{
};
int32_t value{ 123 };
d(value);
REQUIRE(value == 123);
}
{
ReturnStringArrayDelegate d = [] { return com_array<hstring>{ L"One", L"Two", L"Three" }; };
com_array<hstring> value = d();
REQUIRE(value.size() == 3);
REQUIRE(value[0] == L"One");
REQUIRE(value[1] == L"Two");
REQUIRE(value[2] == L"Three");
}
{
OutStringArrayDelegate d = [](com_array<hstring>& value) { value = { L"One", L"Two", L"Three" }; };
com_array<hstring> value;
d(value);
REQUIRE(value.size() == 3);
REQUIRE(value[0] == L"One");
REQUIRE(value[1] == L"Two");
REQUIRE(value[2] == L"Three");
}
{
RefStringArrayDelegate d = [](array_view<hstring> value) { value[0] = L"One"; value[1] = L"Two"; value[2] = L"Three"; };
std::array<hstring, 4> value{ L"r1", L"r2", L"r3", L"r4" };
d(value);
REQUIRE(value[0] == L"One");
REQUIRE(value[1] == L"Two");
REQUIRE(value[2] == L"Three");
REQUIRE(value[3] == L"");
}
}

Просмотреть файл

@ -1,130 +0,0 @@
#include "pch.h"
using namespace std::literals;
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
IAsyncAction Action()
{
co_return;
}
IAsyncActionWithProgress<int> ActionProgress()
{
co_await 500ms;
auto progress = co_await get_progress_token();
progress(123);
co_return;
}
IAsyncOperation<int> Operation()
{
co_return 123;
}
IAsyncOperationWithProgress<int, int> OperationProgress()
{
co_await 500ms;
auto progress = co_await get_progress_token();
progress(123);
co_return 123;
}
}
TEST_CASE("disconnected,1")
{
event<EventHandler<int>> source;
source.add([](auto...)
{
throw hresult_error(RPC_E_DISCONNECTED);
});
auto token = source.add([](auto...)
{
throw hresult_error(E_INVALIDARG);
});
// Should have two delegates
REQUIRE(source);
// Should lose the disconnected delegate
source(nullptr, 123);
REQUIRE(source);
// Fire the remaining delegate
source(nullptr, 123);
REQUIRE(source);
// Remove the final delegate
source.remove(token);
// No more delegates
REQUIRE(!source);
source(nullptr, 123);
}
TEST_CASE("disconnected,2")
{
auto async = Action();
async.Completed([](auto&&...)
{
throw hresult_error(RPC_E_DISCONNECTED);
});
}
TEST_CASE("disconnected,3")
{
auto async = ActionProgress();
handle signal{ CreateEventW(nullptr, true, false, nullptr) };
async.Progress([](auto&&...)
{
throw hresult_error(RPC_E_DISCONNECTED);
});
async.Completed([&](auto&&...)
{
SetEvent(signal.get());
throw hresult_error(RPC_E_DISCONNECTED);
});
WaitForSingleObject(signal.get(), INFINITE);
// Give some time for to_hresult() to complete.
Sleep(500);
}
TEST_CASE("disconnected,4")
{
auto async = Operation();
async.Completed([](auto&&...)
{
throw hresult_error(RPC_E_DISCONNECTED);
});
}
TEST_CASE("disconnected,5")
{
auto async = OperationProgress();
handle signal{ CreateEventW(nullptr, true, false, nullptr) };
async.Progress([](auto&&...)
{
throw hresult_error(RPC_E_DISCONNECTED);
});
async.Completed([&](auto&&...)
{
SetEvent(signal.get());
throw hresult_error(RPC_E_DISCONNECTED);
});
WaitForSingleObject(signal.get(), INFINITE);
// Give some time for to_hresult() to complete.
Sleep(500);
}

Просмотреть файл

@ -1,24 +0,0 @@
#include "pch.h"
#include "winrt/test_component.h"
using namespace winrt;
using namespace test_component;
TEST_CASE("enum")
{
STATIC_REQUIRE(std::is_same_v<std::underlying_type_t<Signed>, int32_t>);
STATIC_REQUIRE(std::is_same_v<std::underlying_type_t<Unsigned>, uint32_t>);
STATIC_REQUIRE(name_of<Signed>() == L"test_component.Signed"sv);
STATIC_REQUIRE(name_of<Unsigned>() == L"test_component.Unsigned"sv);
REQUIRE(((Unsigned::First | Unsigned::Second | Unsigned::Third) & Unsigned::Second) == Unsigned::Second);
REQUIRE(static_cast<int32_t>(Signed::First) == -1);
REQUIRE(static_cast<int32_t>(Signed::Second) == 0);
REQUIRE(static_cast<int32_t>(Signed::Third) == 1);
REQUIRE(static_cast<uint32_t>(Unsigned::First) == 0);
REQUIRE(static_cast<uint32_t>(Unsigned::Second) == 1);
REQUIRE(static_cast<uint32_t>(Unsigned::Third) == 2);
}

Просмотреть файл

@ -1,23 +0,0 @@
#include "pch.h"
TEST_CASE("fast_iterator")
{
{
auto v = winrt::single_threaded_vector<int>({ 1, 2, 3 });
std::vector<int> result;
std::copy(begin(v), end(v), std::back_inserter(result));
REQUIRE((result == std::vector{ 1, 2, 3 }));
}
{
auto v = winrt::single_threaded_vector<int>({ 1, 2, 3 });
std::vector<int> result;
std::copy(rbegin(v), rend(v), std::back_inserter(result));
REQUIRE((result == std::vector{ 3, 2, 1 }));
}
}

Просмотреть файл

@ -1,66 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
struct Sample : implements<Sample, IStringable>
{
hstring ToString()
{
return L"Sample";
}
~Sample()
{
// It's safe to QI/AddRef/Release inside destructor.
IStringable s;
check_hresult(QueryInterface(guid_of<IStringable>(), put_abi(s)));
REQUIRE(s.ToString() == L"Sample");
// Weak references are also supported during destruction.
REQUIRE(weak_ref<IStringable>{ s }.get());
REQUIRE(released);
REQUIRE(!destroyed);
destroyed = true;
}
static void final_release(std::unique_ptr<Sample> ptr) noexcept
{
// It's safe to QI/AddRef/Release inside final_release.
IStringable s;
check_hresult(ptr->QueryInterface(guid_of<IStringable>(), put_abi(s)));
REQUIRE(s.ToString() == L"Sample");
// References must be released prior to destroying the unique_ptr.
s = nullptr;
REQUIRE(!released);
REQUIRE(!destroyed);
released = true;
ptr = nullptr;
REQUIRE(destroyed);
}
static inline bool released;
static inline bool destroyed;
};
}
TEST_CASE("final_release")
{
{
auto s = make<Sample>();
// Weak references are supported prior to destruction.
REQUIRE(weak_ref<IStringable>{ s }.get());
REQUIRE(!Sample::released);
REQUIRE(!Sample::destroyed);
s = nullptr;
REQUIRE(Sample::released);
REQUIRE(Sample::destroyed);
}
}

Просмотреть файл

@ -1,152 +0,0 @@
// Windows.Foundation is intentionally *not* included here to ensure that stable names/guids
// are generated with only the xxx.0.h header. This ensures that indirect declarations produce
// stable identity values.
#define WINRT_LEAN_AND_MEAN
#include "winrt/Windows.Storage.h"
#include "catch.hpp"
#include "generic_types.h"
TEST_CASE("generic_type_names")
{
using A = IIterable<IStringable>;
using B = IKeyValuePair<hstring, IAsyncOperationWithProgress<A, float>>;
test_guids();
//
// Generated Windows.Foundation names
//
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IStringable",
IStringable);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IAsyncActionWithProgress`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
IAsyncActionWithProgress<A>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IAsyncOperationWithProgress`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Windows.Foundation.Collections.IKeyValuePair`2<String, Windows.Foundation.IAsyncOperationWithProgress`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Single>>>",
IAsyncOperationWithProgress<A, B>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IAsyncOperation`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
IAsyncOperation<A>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReferenceArray`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
IReferenceArray<A>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
IReference<A>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.AsyncActionProgressHandler`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
AsyncActionProgressHandler<A>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.AsyncActionWithProgressCompletedHandler`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
AsyncActionWithProgressCompletedHandler<A>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.AsyncOperationCompletedHandler`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
AsyncOperationCompletedHandler<A>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.AsyncOperationProgressHandler`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Windows.Foundation.Collections.IKeyValuePair`2<String, Windows.Foundation.IAsyncOperationWithProgress`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Single>>>",
AsyncOperationProgressHandler<A, B>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.AsyncOperationWithProgressCompletedHandler`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Windows.Foundation.Collections.IKeyValuePair`2<String, Windows.Foundation.IAsyncOperationWithProgress`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Single>>>",
AsyncOperationWithProgressCompletedHandler<A, B>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.EventHandler`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
EventHandler<A>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.TypedEventHandler`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Windows.Foundation.Collections.IKeyValuePair`2<String, Windows.Foundation.IAsyncOperationWithProgress`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Single>>>",
TypedEventHandler<A, B>);
//
// Generated Windows.Foundation.Collections names
//
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IIterable`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
IIterable<A>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IIterator`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
IIterator<A>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IKeyValuePair`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Windows.Foundation.Collections.IKeyValuePair`2<String, Windows.Foundation.IAsyncOperationWithProgress`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Single>>>",
IKeyValuePair<A, B>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IMapChangedEventArgs`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
IMapChangedEventArgs<A>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IMapView`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Windows.Foundation.Collections.IKeyValuePair`2<String, Windows.Foundation.IAsyncOperationWithProgress`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Single>>>",
IMapView<A, B>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IMap`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Windows.Foundation.Collections.IKeyValuePair`2<String, Windows.Foundation.IAsyncOperationWithProgress`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Single>>>",
IMap<A, B>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IObservableMap`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Windows.Foundation.Collections.IKeyValuePair`2<String, Windows.Foundation.IAsyncOperationWithProgress`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Single>>>",
IObservableMap<A, B>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IObservableVector`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
IObservableVector<A>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IVectorView`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
IVectorView<A>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IVector`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
IVector<A>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.MapChangedEventHandler`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Windows.Foundation.Collections.IKeyValuePair`2<String, Windows.Foundation.IAsyncOperationWithProgress`2<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>, Single>>>",
MapChangedEventHandler<A, B>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.VectorChangedEventHandler`1<Windows.Foundation.Collections.IIterable`1<Windows.Foundation.IStringable>>",
VectorChangedEventHandler<A>);
//
// Generated primitive names
//
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Boolean>",
IReference<bool>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Int8>",
IReference<int8_t>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Int16>",
IReference<int16_t>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Int32>",
IReference<int32_t>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Int64>",
IReference<int64_t>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<UInt8>",
IReference<uint8_t>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<UInt16>",
IReference<uint16_t>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<UInt32>",
IReference<uint32_t>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<UInt64>",
IReference<uint64_t>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Single>",
IReference<float>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Double>",
IReference<double>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Char16>",
IReference<char16_t>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Guid>",
IReference<guid>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.HResult>",
IReference<hresult>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<String>",
IReference<hstring>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.EventRegistrationToken>",
IReference<event_token>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.TimeSpan>",
IReference<TimeSpan>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.DateTime>",
IReference<DateTime>);
#if __has_include(<windowsnumerics.impl.h>)
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.Point>",
IReference<Point>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.Rect>",
IReference<Rect>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.Size>",
IReference<Size>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.Numerics.Vector2>",
IReference<float2>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.Numerics.Vector3>",
IReference<float3>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.Numerics.Vector4>",
IReference<float4>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.Numerics.Matrix3x2>",
IReference<float3x2>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.Numerics.Matrix4x4>",
IReference<float4x4>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.Numerics.Quaternion>",
IReference<quaternion>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.Numerics.Plane>",
IReference<plane>);
#endif
// Enums, structs, IInspectable, classes, and delegates
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.PropertyType>",
IReference<PropertyType>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IReference`1<Windows.Foundation.Point>",
IReference<Point>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IVector`1<Object>",
IVector<IInspectable>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IVector`1<Windows.Foundation.Uri>",
IVector<Uri>);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Collections.IVector`1<Windows.Foundation.AsyncActionCompletedHandler>",
IVector<AsyncActionCompletedHandler>);
}

Просмотреть файл

@ -1,12 +0,0 @@
#include "pch.h"
#include "generic_types.h"
TEST_CASE("generic_types")
{
test_guids();
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Uri", Uri);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.PropertyType", PropertyType);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.Point", Point);
REQUIRE_EQUAL_NAME(L"Windows.Foundation.IStringable", IStringable);
}

Просмотреть файл

@ -1,115 +0,0 @@
#pragma once
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
#if __has_include(<windowsnumerics.impl.h>)
using namespace Windows::Foundation::Numerics;
#endif
using namespace std::literals;
#define REQUIRE_EQUAL_GUID(left, ...) STATIC_REQUIRE(equal(guid(left), guid_of<__VA_ARGS__>()));
#define REQUIRE_EQUAL_NAME(left, ...) STATIC_REQUIRE(left == name_of<__VA_ARGS__>());
namespace
{
constexpr bool equal(guid const& left, guid const& right) noexcept
{
return left.Data1 == right.Data1 &&
left.Data2 == right.Data2 &&
left.Data3 == right.Data3 &&
left.Data4[0] == right.Data4[0] &&
left.Data4[1] == right.Data4[1] &&
left.Data4[2] == right.Data4[2] &&
left.Data4[3] == right.Data4[3] &&
left.Data4[4] == right.Data4[4] &&
left.Data4[5] == right.Data4[5] &&
left.Data4[6] == right.Data4[6] &&
left.Data4[7] == right.Data4[7];
}
void test_guids()
{
using A = IIterable<IStringable>;
using B = IKeyValuePair<hstring, IAsyncOperationWithProgress<A, float>>;
REQUIRE_EQUAL_GUID("96369F54-8EB6-48F0-ABCE-C1B211E627C3"sv, IStringable);
//
// Generated Windows.Foundation GUIDs
//
REQUIRE_EQUAL_GUID("DD725452-2DA3-5103-9C7D-22EE9BB14AD3", IAsyncActionWithProgress<A>);
REQUIRE_EQUAL_GUID("94645425-B9E5-5B91-B509-8DA4DF6A8916", IAsyncOperationWithProgress<A, B>);
REQUIRE_EQUAL_GUID("2BD35EE6-72D9-5C5D-9827-05EBB81487AB", IAsyncOperation<A>);
REQUIRE_EQUAL_GUID("4A33FE03-E8B9-5346-A124-5449913ECA57", IReferenceArray<A>);
REQUIRE_EQUAL_GUID("F9E4006C-6E8C-56DF-811C-61F9990EBFB0", IReference<A>);
REQUIRE_EQUAL_GUID("C261D8D0-71BA-5F38-A239-872342253A18", AsyncActionProgressHandler<A>);
REQUIRE_EQUAL_GUID("9A0D211C-0374-5D23-9E15-EAA3570FAE63", AsyncActionWithProgressCompletedHandler<A>);
REQUIRE_EQUAL_GUID("9D534225-231F-55E7-A6D0-6C938E2D9160", AsyncOperationCompletedHandler<A>);
REQUIRE_EQUAL_GUID("264F1E0C-ABE4-590B-9D37-E1CC118ECC75", AsyncOperationProgressHandler<A, B>);
REQUIRE_EQUAL_GUID("C2D078D8-AC47-55AB-83E8-123B2BE5BC5A", AsyncOperationWithProgressCompletedHandler<A, B>);
REQUIRE_EQUAL_GUID("FA0B7D80-7EFA-52DF-9B69-0574CE57ADA4", EventHandler<A>);
REQUIRE_EQUAL_GUID("EDB31843-B4CF-56EB-925A-D4D0CE97A08D", TypedEventHandler<A, B>);
//
// Generated Windows.Foundation.Collections GUIDs
//
REQUIRE_EQUAL_GUID("96565EB9-A692-59C8-BCB5-647CDE4E6C4D", IIterable<A>);
REQUIRE_EQUAL_GUID("3C9B1E27-8357-590B-8828-6E917F172390", IIterator<A>);
REQUIRE_EQUAL_GUID("89336CD9-8B66-50A7-9759-EB88CCB2E1FE", IKeyValuePair<A, B>);
REQUIRE_EQUAL_GUID("E1AA5138-12BD-51A1-8558-698DFD070ABE", IMapChangedEventArgs<A>);
REQUIRE_EQUAL_GUID("B78F0653-FA89-59CF-BA95-726938AAE666", IMapView<A, B>);
REQUIRE_EQUAL_GUID("9962CD50-09D5-5C46-B1E1-3C679C1C8FAE", IMap<A, B>);
REQUIRE_EQUAL_GUID("75F99E2A-137E-537E-A5B1-0B5A6245FC02", IObservableMap<A, B>);
REQUIRE_EQUAL_GUID("D24C289F-2341-5128-AAA1-292DD0DC1950", IObservableVector<A>);
REQUIRE_EQUAL_GUID("5F07498B-8E14-556E-9D2E-2E98D5615DA9", IVectorView<A>);
REQUIRE_EQUAL_GUID("0E3F106F-A266-50A1-8043-C90FCF3844F6", IVector<A>);
REQUIRE_EQUAL_GUID("19046F0B-CF81-5DEC-BBB2-7CC250DA8B8B", MapChangedEventHandler<A, B>);
REQUIRE_EQUAL_GUID("A1E9ACD7-E4DF-5A79-AEFA-DE07934AB0FB", VectorChangedEventHandler<A>);
//
// Generated primitive GUIDs
//
REQUIRE_EQUAL_GUID("3C00FD60-2950-5939-A21A-2D12C5A01B8A", IReference<bool>);
REQUIRE_EQUAL_GUID("95500129-FBF6-5AFC-89DF-70642D741990", IReference<int8_t>);
REQUIRE_EQUAL_GUID("6EC9E41B-6709-5647-9918-A1270110FC4E", IReference<int16_t>);
REQUIRE_EQUAL_GUID("548CEFBD-BC8A-5FA0-8DF2-957440FC8BF4", IReference<int32_t>);
REQUIRE_EQUAL_GUID("4DDA9E24-E69F-5C6A-A0A6-93427365AF2A", IReference<int64_t>);
REQUIRE_EQUAL_GUID("e5198cc8-2873-55f5-b0a1-84ff9e4aad62", IReference<uint8_t>);
REQUIRE_EQUAL_GUID("5AB7D2C3-6B62-5E71-A4B6-2D49C4F238FD", IReference<uint16_t>);
REQUIRE_EQUAL_GUID("513ef3af-e784-5325-a91e-97c2b8111cf3", IReference<uint32_t>);
REQUIRE_EQUAL_GUID("6755e376-53bb-568b-a11d-17239868309e", IReference<uint64_t>);
REQUIRE_EQUAL_GUID("719CC2BA-3E76-5DEF-9F1A-38D85A145EA8", IReference<float>);
REQUIRE_EQUAL_GUID("2F2D6C29-5473-5F3E-92E7-96572BB990E2", IReference<double>);
REQUIRE_EQUAL_GUID("FB393EF3-BBAC-5BD5-9144-84F23576F415", IReference<char16_t>);
REQUIRE_EQUAL_GUID("7D50F649-632C-51F9-849A-EE49428933EA", IReference<guid>);
REQUIRE_EQUAL_GUID("6FF27A1E-4B6A-59B7-B2C3-D1F2EE474593", IReference<hresult>);
REQUIRE_EQUAL_GUID("FD416DFB-2A07-52EB-AAE3-DFCE14116C05", IReference<hstring>);
REQUIRE_EQUAL_GUID("A9B18291-CE2A-5DAE-8A23-B7F7388416DB", IReference<event_token>);
REQUIRE_EQUAL_GUID("604D0C4C-91DE-5C2A-935F-362F13EAF800", IReference<TimeSpan>);
REQUIRE_EQUAL_GUID("5541D8A7-497C-5AA4-86FC-7713ADBF2A2C", IReference<DateTime>);
REQUIRE_EQUAL_GUID("84F14C22-A00A-5272-8D3D-82112E66DF00", IReference<Point>);
REQUIRE_EQUAL_GUID("80423F11-054F-5EAC-AFD3-63B6CE15E77B", IReference<Rect>);
REQUIRE_EQUAL_GUID("61723086-8e53-5276-9f36-2a4bb93e2b75", IReference<Size>);
#if __has_include(<windowsnumerics.impl.h>)
REQUIRE_EQUAL_GUID("48F6A69E-8465-57AE-9400-9764087F65AD", IReference<float2>);
REQUIRE_EQUAL_GUID("1EE770FF-C954-59CA-A754-6199A9BE282C", IReference<float3>);
REQUIRE_EQUAL_GUID("A5E843C9-ED20-5339-8F8D-9FE404CF3654", IReference<float4>);
REQUIRE_EQUAL_GUID("76358CFD-2CBD-525B-A49E-90EE18247B71", IReference<float3x2>);
REQUIRE_EQUAL_GUID("DACBFFDC-68EF-5FD0-B657-782D0AC9807E", IReference<float4x4>);
REQUIRE_EQUAL_GUID("B27004BB-C014-5DCE-9A21-799C5A3C1461", IReference<quaternion>);
REQUIRE_EQUAL_GUID("46D542A1-52F7-58E7-ACFC-9A6D364DA022", IReference<plane>);
#endif
// Enums, structs, IInspectable, classes, and delegates
REQUIRE_EQUAL_GUID("ECEBDE54-FAC0-5AEB-9BA9-9E1FE17E31D5", IReference<PropertyType>);
REQUIRE_EQUAL_GUID("84F14C22-A00A-5272-8D3D-82112E66DF00", IReference<Point>);
REQUIRE_EQUAL_GUID("B32BDCA4-5E52-5B27-BC5D-D66A1A268C2A", IVector<IInspectable>);
REQUIRE_EQUAL_GUID("0D82BD8D-FE62-5D67-A7B9-7886DD75BC4E", IVector<Uri>);
REQUIRE_EQUAL_GUID("5DAFE591-86DC-59AA-BFDA-07F5D59FC708", IVector<AsyncActionCompletedHandler>);
}
}

Просмотреть файл

@ -1,22 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
TEST_CASE("guid_key")
{
auto uri = guid_of<Uri>();
auto deferral = guid_of<Deferral>();
std::map<guid, std::string> ordered;
ordered[uri] = "Uri";
ordered[deferral] = "Deferral";
REQUIRE(ordered[uri] == "Uri");
REQUIRE(ordered[deferral] == "Deferral");
std::unordered_map<guid, std::string> unordered;
unordered[uri] = "Uri";
unordered[deferral] = "Deferral";
REQUIRE(unordered[uri] == "Uri");
REQUIRE(unordered[deferral] == "Deferral");
}

Просмотреть файл

@ -1,39 +0,0 @@
#include "pch.h"
#include <windows.foundation.h>
namespace
{
struct Stringable : winrt::implements<Stringable, winrt::Windows::Foundation::IStringable>
{
winrt::hstring ToString()
{
return L"hello";
}
};
HRESULT GetStringable(GUID const& id, void** object) noexcept
{
*object = nullptr;
if (id != __uuidof(ABI::Windows::Foundation::IStringable))
{
return E_NOINTERFACE;
}
*object = winrt::detach_abi(winrt::make<Stringable>());
return S_OK;
}
}
TEST_CASE("iid_ppv_args")
{
{
winrt::com_ptr<ABI::Windows::Foundation::IStringable> ptr;
REQUIRE(S_OK == GetStringable(IID_PPV_ARGS(&ptr)));
REQUIRE(ptr.as<winrt::Windows::Foundation::IStringable>().ToString() == L"hello");
}
{
winrt::com_ptr<ABI::Windows::Foundation::IClosable> ptr;
REQUIRE(E_NOINTERFACE == GetStringable(IID_PPV_ARGS(&ptr)));
}
}

Просмотреть файл

@ -1,61 +0,0 @@
#include "pch.h"
#include "winrt/test_component.h"
using namespace winrt;
using namespace Windows::Foundation;
using namespace test_component;
namespace
{
struct Value : implements<Value, IStringable>
{
Value(int32_t value) :
m_value(value)
{
}
hstring ToString()
{
return hstring{ std::to_wstring(m_value) };
}
private:
int32_t m_value{};
};
}
TEST_CASE("in_params")
{
Class object;
REQUIRE(object.InInt32(123) == L"123");
REQUIRE(object.InString(L"123") == L"123");
REQUIRE(object.InObject(make<Value>(123)) == L"123");
REQUIRE(object.InStringable(make<Value>(123)) == L"123");
REQUIRE(object.InStruct({ L"1", L"2" }) == L"12");
REQUIRE(object.InStructRef({ L"1", L"2" }) == L"12ref");
REQUIRE(object.InEnum(Signed::First) == L"First");
REQUIRE(object.InInt32Array({ 1,2 }) == L"12");
REQUIRE(object.InStringArray({ L"1", L"2" }) == L"12");
REQUIRE(object.InObjectArray({ make<Value>(1), make<Value>(2) }) == L"12");
REQUIRE(object.InStringableArray({ make<Value>(1), make<Value>(2) }) == L"12");
REQUIRE(object.InStructArray({ {L"1",L"2"}, {L"3",L"4"} }) == L"1234");
REQUIRE(object.InEnumArray({ Signed::First, Signed::Second }) == L"FirstSecond");
// Ensure 0-length arrays are passed as non-null pointers to the ABI,
// in order to keep RPC happy.
REQUIRE(object.InInt32Array({ }) == L"");
REQUIRE(object.InStringArray({ }) == L"");
REQUIRE(object.InObjectArray({ }) == L"");
REQUIRE(object.InStringableArray({ }) == L"");
REQUIRE(object.InStructArray({ }) == L"");
REQUIRE(object.InEnumArray({ }) == L"");
// params::hstring optimizations
REQUIRE(object.InString(L"") == L"");
REQUIRE(object.InString({}) == L"");
wchar_t non_const_string[1] = { L'\0' };
REQUIRE(object.InString(non_const_string) == L"");
}

Просмотреть файл

@ -1,85 +0,0 @@
#include <inspectable.h>
#include "winrt/Windows.Foundation.h"
#include "catch.hpp"
using namespace winrt;
namespace
{
struct DECLSPEC_UUID("ed0dd761-c31e-4803-8cf9-22a2cb20ec47") IBadInterop : ::IInspectable
{
virtual int32_t __stdcall JustSayNo() noexcept = 0;
};
}
#ifdef __CRT_UUID_DECL
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
__CRT_UUID_DECL(IBadInterop, 0xed0dd761, 0xc31e, 0x4803, 0x8c, 0xf9, 0x22, 0xa2, 0xcb, 0x20, 0xec, 0x47)
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#endif
namespace
{
struct Sample : implements<Sample, Windows::Foundation::IActivationFactory, IBadInterop>
{
Windows::Foundation::IInspectable ActivateInstance()
{
throw hresult_not_implemented();
}
hstring GetRuntimeClassName() const
{
return L"Sample";
}
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
#endif
Windows::Foundation::TrustLevel GetTrustLevel() const noexcept
{
return Windows::Foundation::TrustLevel::PartialTrust;
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
int32_t __stdcall JustSayNo() noexcept final
{
return 123;
}
};
}
TEST_CASE("inspectable_interop")
{
Windows::Foundation::IActivationFactory a = make<Sample>();
REQUIRE(a != nullptr);
Windows::Foundation::IActivationFactory b = a.as<Windows::Foundation::IActivationFactory>();
REQUIRE(b != nullptr);
com_ptr<IBadInterop> c = a.as<IBadInterop>();
REQUIRE(c != nullptr);
REQUIRE(c->JustSayNo() == 123);
Windows::Foundation::IActivationFactory d = c.as<Windows::Foundation::IActivationFactory>();
REQUIRE(a == d);
Windows::Foundation::IInspectable f = c.as<Windows::Foundation::IInspectable>();
REQUIRE(f != nullptr);
Windows::Foundation::IInspectable e(c.detach(), take_ownership_from_abi);
REQUIRE(winrt::get_class_name(e) == L"Sample");
REQUIRE(winrt::get_trust_level(e) == Windows::Foundation::TrustLevel::PartialTrust);
auto interfaces = winrt::get_interfaces(e);
REQUIRE(interfaces.size() == 1);
REQUIRE(interfaces[0] == guid_of<Windows::Foundation::IActivationFactory>());
}

Просмотреть файл

@ -1,86 +0,0 @@
#include "pch.h"
#include <inspectable.h>
struct DECLSPEC_UUID("5040a5f4-796a-42ff-9f06-be89137a518f") IBase : IUnknown
{
};
struct DECLSPEC_UUID("529fed32-514f-4150-b1ba-15b47df700b7") IDerived : IBase
{
};
struct DECLSPEC_UUID("b81fb2a2-eab4-488a-96a7-434873c2c20b") IMoreDerived : IDerived
{
};
#ifdef __CRT_UUID_DECL
__CRT_UUID_DECL(IBase, 0x5040a5f4, 0x796a, 0x42ff, 0x9f, 0x06, 0xbe, 0x89, 0x13, 0x7a, 0x51, 0x8f)
__CRT_UUID_DECL(IDerived, 0x529fed32, 0x514f, 0x4150, 0xb1, 0xba, 0x15, 0xb4, 0x7d, 0xf7, 0x00, 0xb7)
__CRT_UUID_DECL(IMoreDerived, 0xb81fb2a2, 0xeab4, 0x488a, 0x96, 0xa7, 0x43, 0x48, 0x73, 0xc2, 0xc2, 0x0b)
#endif
namespace winrt
{
template<> bool is_guid_of<IDerived>(guid const& id) noexcept
{
return is_guid_of<IDerived, IBase>(id);
}
template<> bool is_guid_of<IMoreDerived>(guid const& id) noexcept
{
return is_guid_of<IMoreDerived, IDerived, IBase>(id);
}
}
using namespace winrt;
struct MyBase : implements<MyBase, IBase>
{
};
struct MyDerived : implements<MyDerived, IDerived>
{
};
struct MyMoreDerived : implements<MyMoreDerived, IMoreDerived, Windows::Foundation::IInspectable>
{
};
Windows::Foundation::IAsyncAction Async()
{
co_return;
}
TEST_CASE("interop")
{
{
Windows::Foundation::IAsyncAction a = Async();
com_ptr<::IInspectable> b = a.as<::IInspectable>();
Windows::Foundation::IAsyncAction c = b.as<Windows::Foundation::IAsyncAction>();
REQUIRE(a == c);
}
{
com_ptr<IBase> a = make<MyBase>();
REQUIRE(a);
REQUIRE(a.try_as<IBase>() != nullptr);
REQUIRE(a.try_as<IDerived>() == nullptr);
REQUIRE(a.try_as<IMoreDerived>() == nullptr);
REQUIRE(a.try_as<::IInspectable>() == nullptr);
}
{
com_ptr<IDerived> a = make<MyDerived>();
REQUIRE(a);
REQUIRE(a.try_as<IBase>() != nullptr);
REQUIRE(a.try_as<IDerived>() != nullptr);
REQUIRE(a.try_as<IMoreDerived>() == nullptr);
REQUIRE(a.try_as<::IInspectable>() == nullptr);
}
{
com_ptr<IMoreDerived> a = make<MyMoreDerived>();
REQUIRE(a);
REQUIRE(a.try_as<IBase>() != nullptr);
REQUIRE(a.try_as<IDerived>() != nullptr);
REQUIRE(a.try_as<IMoreDerived>() != nullptr);
REQUIRE(a.try_as<::IInspectable>() != nullptr);
}
}

Просмотреть файл

@ -1,63 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
//
// Checks that invalid tokens may be removed harmlessly.
//
TEST_CASE("invalid_events")
{
event<TypedEventHandler<int, int>> event;
int counter{};
auto a = event.add([&](auto && ...)
{
counter += 1;
});
auto b = event.add([&](auto && ...)
{
counter += 10;
});
REQUIRE(counter == 0);
event(0, 0);
REQUIRE(counter == 11);
// Remove invalid token (with two valids)
event.remove(event_token {1});
counter = 0;
event(0, 0);
REQUIRE(counter == 11);
// Remove valid token
event.remove(b);
counter = 0;
event(0, 0);
REQUIRE(counter == 1);
// Remove invalid token (with one valid)
event.remove(event_token {1});
counter = 0;
event(0, 0);
REQUIRE(counter == 1);
// Remove remaining valid token
event.remove(a);
counter = 0;
event(0, 0);
REQUIRE(counter == 0);
// Remove invalid token (with no valids)
event.remove(event_token {1});
counter = 0;
event(0, 0);
REQUIRE(counter == 0);
}

Просмотреть файл

@ -1,26 +0,0 @@
#include <crtdbg.h>
#define CATCH_CONFIG_RUNNER
// Force reportFatal to be available on mingw-w64
#define CATCH_CONFIG_WINDOWS_SEH
#include "catch.hpp"
#include "winrt/base.h"
using namespace winrt;
int main(int const argc, char** argv)
{
init_apartment();
std::set_terminate([] { reportFatal("Abnormal termination"); ExitProcess(1); });
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
(void)_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
(void)_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
return Catch::Session().run(argc, argv);
}
CATCH_TRANSLATE_EXCEPTION(hresult_error const& e)
{
return to_string(e.message());
}

Просмотреть файл

@ -1,50 +0,0 @@
#include "catch.hpp"
// The default behavior (no macro) provides the static winrt::get_module_lock implementation for components/DLLs.
#include "winrt/Windows.Foundation.h"
namespace
{
struct Stringable : winrt::implements<Stringable, winrt::Windows::Foundation::IStringable>
{
winrt::hstring ToString()
{
return L"Stringable";
}
};
}
TEST_CASE("module_lock_dll")
{
uint32_t const count = winrt::get_module_lock();
++winrt::get_module_lock();
REQUIRE(winrt::get_module_lock() == count + 1);
--winrt::get_module_lock();
REQUIRE(winrt::get_module_lock() == count);
{
auto stringable = winrt::make<Stringable>();
REQUIRE(winrt::get_module_lock() == count + 1);
}
REQUIRE(winrt::get_module_lock() == count);
{
winrt::Windows::Foundation::EventHandler<int> delegate = [](auto&&...) {};
REQUIRE(winrt::get_module_lock() == count + 1);
}
REQUIRE(winrt::get_module_lock() == count);
{
winrt::delegate<void()> delegate = [] {};
REQUIRE(winrt::get_module_lock() == count + 1);
}
REQUIRE(winrt::get_module_lock() == count);
}

Просмотреть файл

@ -1,19 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
void check_terminated(winrt::param::hstring const&)
{
}
TEST_CASE("names")
{
REQUIRE(name_of<Windows::Foundation::IUnknown>() == L"{00000000-0000-0000-c000-000000000046}"sv);
STATIC_REQUIRE(name_of<IInspectable>() == L"Object"sv);
check_terminated(name_of<Windows::Foundation::IUnknown>());
check_terminated(name_of<IInspectable>());
check_terminated(name_of<EventHandler<guid>>());
check_terminated(name_of<TypedEventHandler<guid, Point>>());
}

Просмотреть файл

@ -1,10 +0,0 @@
#include "pch.h"
#include "winrt/test_component.h"
using namespace winrt;
using namespace test_component;
TEST_CASE("no_make_detection")
{
REQUIRE(test_component::Class::TestNoMakeDetection());
}

Просмотреть файл

@ -1,17 +0,0 @@
#include "pch.h"
#include "winrt/test_component.h"
using namespace winrt;
using namespace test_component;
TEST_CASE("noexcept")
{
Class c;
c.NoexceptVoid();
int32_t a = c.NoexceptInt32();
hstring b = c.NoexceptString();
REQUIRE(a == 123);
REQUIRE(b == L"123");
}

Просмотреть файл

@ -1,15 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation::Numerics;
TEST_CASE("numerics")
{
#if __has_include(<windowsnumerics.impl.h>)
// Basic smoke test exercising SIMD intrinsics used by numerics.
auto one = float4::one();
REQUIRE(one * one == one);
#endif
}

Просмотреть файл

@ -1,278 +0,0 @@
#include "pch.h"
#include "winrt/test_component.h"
using namespace winrt;
using namespace Windows::Foundation;
using namespace test_component;
namespace
{
struct Stringable : implements<Stringable, IStringable>
{
hstring ToString()
{
return L"Stringable";
}
};
}
TEST_CASE("out_params")
{
Class object;
{
int value;
object.OutInt32(value);
REQUIRE(value == 123);
}
{
hstring value = L"replace";
object.OutString(value);
REQUIRE(value == L"123");
}
{
IInspectable value = make<Stringable>();
object.OutObject(value);
REQUIRE(value.as<IStringable>().ToString() == L"123");
}
{
IStringable value = make<Stringable>();
object.OutStringable(value);
REQUIRE(value.ToString() == L"123");
}
{
Struct value{ L"First", L"Second" };
object.OutStruct(value);
REQUIRE(value.First == L"1");
REQUIRE(value.Second == L"2");
}
{
Signed value;
object.OutEnum(value);
REQUIRE(value == Signed::First);
}
{
com_array<int32_t> value(10);
object.OutInt32Array(value);
REQUIRE(value.size() == 3);
REQUIRE(value[0] == 1);
REQUIRE(value[1] == 2);
REQUIRE(value[2] == 3);
}
{
com_array<hstring> value(10);
object.OutStringArray(value);
REQUIRE(value.size() == 3);
REQUIRE(value[0] == L"1");
REQUIRE(value[1] == L"2");
REQUIRE(value[2] == L"3");
}
{
com_array<IInspectable> value(10);
object.OutObjectArray(value);
REQUIRE(value.size() == 3);
REQUIRE(value[0].as<IStringable>().ToString() == L"1");
REQUIRE(value[1].as<IStringable>().ToString() == L"2");
REQUIRE(value[2].as<IStringable>().ToString() == L"3");
}
{
com_array<IStringable> value(10);
object.OutStringableArray(value);
REQUIRE(value.size() == 3);
REQUIRE(value[0].ToString() == L"1");
REQUIRE(value[1].ToString() == L"2");
REQUIRE(value[2].ToString() == L"3");
}
{
com_array<Struct> value(10);
object.OutStructArray(value);
REQUIRE(value.size() == 2);
REQUIRE(value[0].First == L"1");
REQUIRE(value[0].Second == L"2");
REQUIRE(value[1].First == L"10");
REQUIRE(value[1].Second == L"20");
}
{
com_array<Signed> value(10);
object.OutEnumArray(value);
REQUIRE(value.size() == 2);
REQUIRE(value[0] == Signed::First);
REQUIRE(value[1] == Signed::Second);
}
{
std::array<int32_t, 4> value{ 0xCC, 0xCC, 0xCC, 0xCC };
object.RefInt32Array(value);
REQUIRE(value[0] == 1);
REQUIRE(value[1] == 2);
REQUIRE(value[2] == 3);
REQUIRE(value[3] == 0xCC);
}
{
std::array<hstring, 4> value{ L"r1", L"r2", L"r3", L"r4" };
object.RefStringArray(value);
REQUIRE(value[0] == L"1");
REQUIRE(value[1] == L"2");
REQUIRE(value[2] == L"3");
REQUIRE(value[3] == L"");
}
{
std::array<IInspectable, 4> value{ make<Stringable>(), make<Stringable>(), make<Stringable>(), make<Stringable>() };
object.RefObjectArray(value);
REQUIRE(value[0].as<IStringable>().ToString() == L"1");
REQUIRE(value[1].as<IStringable>().ToString() == L"2");
REQUIRE(value[2].as<IStringable>().ToString() == L"3");
REQUIRE(value[3] == nullptr);
}
{
std::array<IStringable, 4> value{ make<Stringable>(), make<Stringable>(), make<Stringable>(), make<Stringable>() };
object.RefStringableArray(value);
REQUIRE(value[0].ToString() == L"1");
REQUIRE(value[1].ToString() == L"2");
REQUIRE(value[2].ToString() == L"3");
REQUIRE(value[3] == nullptr);
}
{
std::array<Struct, 3> value{ {L"First", L"Second"} };
object.RefStructArray(value);
REQUIRE(value[0].First == L"1");
REQUIRE(value[0].Second == L"2");
REQUIRE(value[1].First == L"3");
REQUIRE(value[1].Second == L"4");
REQUIRE(value[2].First == L"");
REQUIRE(value[2].Second == L"");
}
{
std::array<Signed, 3> value{};
object.RefEnumArray(value);
REQUIRE(value.size() == 3);
REQUIRE(value[0] == Signed::First);
REQUIRE(value[1] == Signed::Second);
REQUIRE(value[2] == static_cast<Signed>(0));
}
// Ensure 0-length arrays are passed as non-null pointers to the ABI,
// in order to keep RPC happy.
{
REQUIRE_NOTHROW(object.RefInt32Array({}));
REQUIRE_NOTHROW(object.RefStringArray({}));
REQUIRE_NOTHROW(object.RefObjectArray({}));
REQUIRE_NOTHROW(object.RefStringableArray({}));
REQUIRE_NOTHROW(object.RefStructArray({}));
REQUIRE_NOTHROW(object.RefEnumArray({}));
}
object.Fail(true);
{
int value = 0xCC;
REQUIRE_THROWS_AS(object.OutInt32(value), hresult_invalid_argument);
REQUIRE(value == 0xCC);
}
{
hstring value = L"replace";
REQUIRE_THROWS_AS(object.OutString(value), hresult_invalid_argument);
REQUIRE(value == L"");
}
{
IInspectable value = make<Stringable>();
REQUIRE_THROWS_AS(object.OutObject(value), hresult_invalid_argument);
REQUIRE(value == nullptr);
}
{
IStringable value = make<Stringable>();
REQUIRE_THROWS_AS(object.OutStringable(value), hresult_invalid_argument);
REQUIRE(value == nullptr);
}
{
Struct value{ L"First", L"Second" };
REQUIRE_THROWS_AS(object.OutStruct(value), hresult_invalid_argument);
REQUIRE(value.First == L"");
REQUIRE(value.Second == L"");
}
{
Signed value = static_cast<Signed>(0xCC);
REQUIRE_THROWS_AS(object.OutEnum(value), hresult_invalid_argument);
REQUIRE(static_cast<int32_t>(value) == 0xCC);
}
{
com_array<int32_t> value(10);
REQUIRE_THROWS_AS(object.OutInt32Array(value), hresult_invalid_argument);
REQUIRE(value.size() == 0);
}
{
com_array<hstring> value(10);
REQUIRE_THROWS_AS(object.OutStringArray(value), hresult_invalid_argument);
REQUIRE(value.size() == 0);
}
{
com_array<IInspectable> value(10);
REQUIRE_THROWS_AS(object.OutObjectArray(value), hresult_invalid_argument);
REQUIRE(value.size() == 0);
}
{
com_array<IStringable> value(10);
REQUIRE_THROWS_AS(object.OutStringableArray(value), hresult_invalid_argument);
REQUIRE(value.size() == 0);
}
{
com_array<Struct> value(10);
REQUIRE_THROWS_AS(object.OutStructArray(value), hresult_invalid_argument);
REQUIRE(value.size() == 0);
}
{
com_array<Signed> value(10);
REQUIRE_THROWS_AS(object.OutEnumArray(value), hresult_invalid_argument);
REQUIRE(value.size() == 0);
}
{
std::array<int32_t, 4> value{ 0xCC, 0xCC, 0xCC, 0xCC };
REQUIRE_THROWS_AS(object.RefInt32Array(value), hresult_invalid_argument);
REQUIRE(value[0] == 0xCC);
REQUIRE(value[1] == 0xCC);
REQUIRE(value[2] == 0xCC);
REQUIRE(value[3] == 0xCC);
}
{
std::array<hstring, 4> value{ L"r1", L"r2", L"r3", L"r4" };
REQUIRE_THROWS_AS(object.RefStringArray(value), hresult_invalid_argument);
REQUIRE(value[0] == L"");
REQUIRE(value[1] == L"");
REQUIRE(value[2] == L"");
REQUIRE(value[3] == L"");
}
{
std::array<IInspectable, 4> value{ make<Stringable>(), make<Stringable>(), make<Stringable>(), make<Stringable>() };
REQUIRE_THROWS_AS(object.RefObjectArray(value), hresult_invalid_argument);
REQUIRE(value[0] == nullptr);
REQUIRE(value[1] == nullptr);
REQUIRE(value[2] == nullptr);
REQUIRE(value[3] == nullptr);
}
{
std::array<IStringable, 4> value{ make<Stringable>(), make<Stringable>(), make<Stringable>(), make<Stringable>() };
REQUIRE_THROWS_AS(object.RefStringableArray(value), hresult_invalid_argument);
REQUIRE(value[0] == nullptr);
REQUIRE(value[1] == nullptr);
REQUIRE(value[2] == nullptr);
REQUIRE(value[3] == nullptr);
}
{
std::array<Struct, 3> value{ {L"First", L"Second"} };
REQUIRE_THROWS_AS(object.RefStructArray(value), hresult_invalid_argument);
REQUIRE(value[0].First == L"");
REQUIRE(value[0].Second == L"");
REQUIRE(value[1].First == L"");
REQUIRE(value[1].Second == L"");
REQUIRE(value[2].First == L"");
REQUIRE(value[2].Second == L"");
}
{
std::array<Signed, 2> value{ static_cast<Signed>(0xCC), static_cast<Signed>(0xCC) };
REQUIRE_THROWS_AS(object.RefEnumArray(value), hresult_invalid_argument);
REQUIRE(value[0] == static_cast<Signed>(0xCC));
REQUIRE(value[1] == static_cast<Signed>(0xCC));
}
}

Просмотреть файл

@ -1,17 +0,0 @@
#include "pch.h"
#include "winrt/test_component.Parent.One.Two.Three.h"
using namespace winrt::test_component;
TEST_CASE("parent_includes")
{
// Including "...Three.h" should include all (available) ancestors, skipping
// any that are empty. In this case, "Three" and "Parent" are not empty while
// the intermediate namespaces are empty.
Parent::One::Two::Three::ThreeStruct three;
three.Value = 0;
Parent::ParentStruct parent;
parent.Value = 0;
}

Просмотреть файл

@ -1 +0,0 @@
#include "pch.h"

Просмотреть файл

@ -1,47 +0,0 @@
#pragma once
#include "mingw_com_support.h"
#define WINRT_LEAN_AND_MEAN
#include <unknwn.h>
#include "winrt/Windows.Foundation.Collections.h"
#include "winrt/Windows.Foundation.Numerics.h"
#include "catch.hpp"
using namespace std::literals;
// Extracts return and progress types from IAsyncXxx.
template<typename T>
struct async_traits;
template<>
struct async_traits<winrt::Windows::Foundation::IAsyncAction>
{
using progress_type = void;
};
template<typename P>
struct async_traits<winrt::Windows::Foundation::IAsyncActionWithProgress<P>>
{
using progress_type = P;
};
template<typename R>
struct async_traits<winrt::Windows::Foundation::IAsyncOperation<R>>
{
using progress_type = void;
};
template<typename R, typename P>
struct async_traits<winrt::Windows::Foundation::IAsyncOperationWithProgress<R, P>>
{
using progress_type = P;
};
template<typename T>
using async_return_type = decltype(std::declval<T>().GetResults());
template<typename T>
using async_progress_type = typename async_traits<std::decay_t<T>>::progress_type;
template<typename T>
inline constexpr bool has_async_progress = !std::is_same_v<void, typename async_traits<std::decay_t<T>>::progress_type>;

Просмотреть файл

@ -1,80 +0,0 @@
#include "pch.h"
#include "winrt/test_component.h"
using namespace winrt;
using namespace Windows::Foundation;
using namespace test_component;
namespace
{
struct Stringable : implements<Stringable, IStringable>
{
hstring ToString()
{
return L"Stringable";
}
};
}
TEST_CASE("return_params")
{
Class object;
{
int value = object.ReturnInt32();
REQUIRE(value == 123);
}
{
hstring value = object.ReturnString();
REQUIRE(value == L"123");
}
{
IInspectable value = object.ReturnObject();
REQUIRE(value.as<IStringable>().ToString() == L"123");
}
{
IStringable value = object.ReturnStringable();
REQUIRE(value.ToString() == L"123");
}
{
Struct value = object.ReturnStruct();
REQUIRE(value.First == L"1");
REQUIRE(value.Second == L"2");
}
{
com_array<int32_t> value = object.ReturnInt32Array();
REQUIRE(value.size() == 3);
REQUIRE(value[0] == 1);
REQUIRE(value[1] == 2);
REQUIRE(value[2] == 3);
}
{
com_array<hstring> value = object.ReturnStringArray();
REQUIRE(value.size() == 3);
REQUIRE(value[0] == L"1");
REQUIRE(value[1] == L"2");
REQUIRE(value[2] == L"3");
}
{
com_array<IInspectable> value = object.ReturnObjectArray();
REQUIRE(value.size() == 3);
REQUIRE(value[0].as<IStringable>().ToString() == L"1");
REQUIRE(value[1].as<IStringable>().ToString() == L"2");
REQUIRE(value[2].as<IStringable>().ToString() == L"3");
}
{
com_array<IStringable> value = object.ReturnStringableArray();
REQUIRE(value.size() == 3);
REQUIRE(value[0].ToString() == L"1");
REQUIRE(value[1].ToString() == L"2");
REQUIRE(value[2].ToString() == L"3");
}
{
com_array<Struct> value = object.ReturnStructArray();
REQUIRE(value.size() == 2);
REQUIRE(value[0].First == L"1");
REQUIRE(value[0].Second == L"2");
REQUIRE(value[1].First == L"10");
REQUIRE(value[1].Second == L"20");
}
}

Просмотреть файл

@ -1,18 +0,0 @@
#include "pch.h"
#include "winrt/test_component.Structs.Nested.h"
#include "winrt/test_component_no_pch.Peer2.h"
using namespace winrt;
TEST_CASE("structs")
{
test_component::Structs::Nested::Outer outer{};
outer.Depends.InnerValue = 1;
outer.OuterValue = 2;
test_component_no_pch::Peer2::B depends{};
depends.First.Value = 1;
test_component::Structs::All all{};
all.H = {};
}

Просмотреть файл

@ -1,363 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{2EF696B9-7F4A-410F-AE5C-5301565C0F08}</ProjectGuid>
<RootNamespace>unittests</RootNamespace>
<ProjectName>test_win7</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..;..\..\cppwinrt</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PreBuildEvent>
<Command>$(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi</Command>
</PreBuildEvent>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..;..\..\cppwinrt</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
<PreBuildEvent>
<Command>$(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi</Command>
</PreBuildEvent>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..;..\..\cppwinrt</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
<PreBuildEvent>
<Command>$(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi</Command>
</PreBuildEvent>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..;..\..\cppwinrt</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
<PreBuildEvent>
<Command>$(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi</Command>
</PreBuildEvent>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..;..\..\cppwinrt</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
<PreBuildEvent>
<Command>$(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi</Command>
</PreBuildEvent>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..;..\..\cppwinrt</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PreBuildEvent>
<Command>$(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi</Command>
</PreBuildEvent>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..;..\..\cppwinrt</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PreBuildEvent>
<Command>$(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi</Command>
</PreBuildEvent>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(OutputPath);Generated Files;..;..\..\cppwinrt</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NOMINMAX;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PreBuildEvent>
<Command>$(CppWinRTDir)cppwinrt -in $(OutputPath)test_component.winmd $(OutputPath)test_component_no_pch.winmd -out "$(ProjectDir)Generated Files" -ref sdk -verbose -fastabi</Command>
</PreBuildEvent>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="generic_types.h" />
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="abi_guard.cpp" />
<ClCompile Include="agile_ref.cpp" />
<ClCompile Include="agility.cpp" />
<ClCompile Include="async_auto_cancel.cpp" />
<ClCompile Include="async_cancel_callback.cpp" />
<ClCompile Include="async_check_cancel.cpp" />
<ClCompile Include="async_local.cpp" />
<ClCompile Include="async_no_suspend.cpp" />
<ClCompile Include="async_progress.cpp" />
<ClCompile Include="async_result.cpp" />
<ClCompile Include="async_return.cpp" />
<ClCompile Include="async_suspend.cpp" />
<ClCompile Include="async_throw.cpp" />
<ClCompile Include="async_wait_for.cpp" />
<ClCompile Include="capture.cpp" />
<ClCompile Include="cmd_reader.cpp" />
<ClCompile Include="coro_foundation.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="coro_threadpool.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="custom_error.cpp" />
<ClCompile Include="delegate.cpp" />
<ClCompile Include="delegates.cpp" />
<ClCompile Include="disconnected.cpp" />
<ClCompile Include="enum.cpp" />
<ClCompile Include="fast_iterator.cpp" />
<ClCompile Include="final_release.cpp" />
<ClCompile Include="generic_types.cpp" />
<ClCompile Include="generic_type_names.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="GetMany.cpp" />
<ClCompile Include="guid_key.cpp" />
<ClCompile Include="iid_ppv_args.cpp" />
<ClCompile Include="inspectable_interop.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="interop.cpp" />
<ClCompile Include="invalid_events.cpp" />
<ClCompile Include="in_params.cpp" />
<ClCompile Include="main.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="module_lock_dll.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="names.cpp" />
<ClCompile Include="noexcept.cpp" />
<ClCompile Include="no_make_detection.cpp" />
<ClCompile Include="numerics.cpp" />
<ClCompile Include="out_params.cpp" />
<ClCompile Include="parent_includes.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="return_params.cpp" />
<ClCompile Include="structs.cpp" />
<ClCompile Include="thread_pool.cpp" />
<ClCompile Include="uniform_in_params.cpp" />
<ClCompile Include="velocity.cpp" />
<ClCompile Include="when.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

Просмотреть файл

@ -1,61 +0,0 @@
#include "pch.h"
using namespace winrt;
using namespace Windows::Foundation;
namespace
{
struct AsyncQueue
{
thread_pool m_pool;
AsyncQueue(uint32_t const high, uint32_t const low)
{
m_pool.thread_limits(high, low);
}
IAsyncAction Async(delegate<> callback)
{
co_await m_pool;
callback();
}
};
uint32_t test(uint32_t const iterations, uint32_t const high, uint32_t const low)
{
AsyncQueue queue(high, low);
std::vector<IAsyncAction> results;
uint32_t counter{};
for (uint32_t i = 0; i < iterations; ++i)
{
results.push_back(queue.Async([&]
{
auto value = counter + 1;
Sleep(10); // Induce thread pool to use more threads if available, also force race condition
counter = value;
}));
}
for (auto&& async : results)
{
async.get();
}
return counter;
}
}
TEST_CASE("thread_pool")
{
uint32_t const test_iterations = 100;
uint32_t const stable_counter = test(test_iterations, 1, 1);
uint32_t const unstable_counter = test(test_iterations, 10, 10);
// This is determinstic since the queue is single-threaded.
REQUIRE(stable_counter == test_iterations);
// This is unlikely to fail since the pool is multi-threaded.
REQUIRE(unstable_counter < test_iterations);
}

Просмотреть файл

@ -1,29 +0,0 @@
#include "pch.h"
#include "winrt/test_component.h"
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace test_component;
TEST_CASE("uniform_in_params")
{
Class{ single_threaded_vector<hstring>({ L"test" }).as<IIterable<hstring>>(), 0 };
Class{ single_threaded_map<hstring, hstring>(std::map<hstring, hstring>{ {L"test", L"test" } }).as<IIterable<IKeyValuePair<hstring, hstring>>>(), 0, 0 };
Class{ single_threaded_map<hstring, hstring>(std::map<hstring, hstring>{ {L"test", L"test" } }), 0, 0, 0 };
Class{ single_threaded_map<hstring, hstring>(std::map<hstring, hstring>{ {L"test", L"test" } }).GetView(), 0, 0, 0, 0 };
Class{ single_threaded_vector<hstring>({ L"test" }), 0, 0, 0, 0, 0 };
Class{ single_threaded_vector<hstring>({ L"test" }).GetView(), 0, 0, 0, 0, 0, 0 };
Class c;
REQUIRE(L"test" == c.InIterable({L"test"}));
REQUIRE(L"test" == c.InIterablePair(single_threaded_map<hstring, hstring>(std::map<hstring, hstring>{ {L"test", L"test" } })));
REQUIRE(L"test" == c.InAsyncIterable({ L"test" }).get());
REQUIRE(L"test" == c.InAsyncIterablePair(single_threaded_map<hstring, hstring>(std::map<hstring, hstring>{ {L"test", L"test" } })).get());
REQUIRE(L"test" == c.InMap(single_threaded_map<hstring, hstring>(std::map<hstring, hstring>{ {L"test", L"test" } })));
REQUIRE(L"test" == c.InMapView(single_threaded_map<hstring, hstring>(std::map<hstring, hstring>{ {L"test", L"test" } }).GetView()));
REQUIRE(L"test" == c.InAsyncMapView(single_threaded_map<hstring, hstring>(std::map<hstring, hstring>{ {L"test", L"test" } }).GetView()).get());
REQUIRE(L"test" == c.InVector({ L"test" }));
REQUIRE(L"test" == c.InVectorView({ L"test" }));
REQUIRE(L"test" == c.InAsyncVectorView({ L"test" }).get());
}

Просмотреть файл

@ -1,44 +0,0 @@
#include "pch.h"
#include "winrt/test_component.Velocity.h"
using namespace winrt;
using namespace test_component::Velocity;
TEST_CASE("velocity")
{
// This interface is always disabled but shows up in the type system
// if it is present in the winmd.
IInterface1 a;
REQUIRE(a == nullptr);
// This interface is always enabled and is naturally available in
// the projection.
IInterface2 b;
REQUIRE(b == nullptr);
// Class1 is always disabled and thus will not activate.
REQUIRE_THROWS_AS(Class1(), hresult_class_not_registered);
// Class2 is always enabled so should activate just fine.
Class2 c;
c.Class2_Method();
// Class3 is always disabled and thus will not activate.
REQUIRE_THROWS_AS(Class3(), hresult_class_not_registered);
// Class4 is not feature-controlled but uses feature interfaces.
Class4 d;
d.Class4_Method();
// The single argument constructor is always disabled.
REQUIRE_THROWS_AS(Class4(1), hresult_class_not_registered);
// The Class4_Static1 static is always disabled.
REQUIRE_THROWS_AS(Class4::Class4_Static1(), hresult_class_not_registered);
// The two argument constructor is always enabled.
Class4 e(1, 2);
// The Class4_Static2 static is always enabled.
Class4::Class4_Static2();
}

Просмотреть файл

@ -1,74 +0,0 @@
#include "pch.h"
#include <pplawait.h>
using namespace concurrency;
using namespace winrt;
using namespace Windows::Foundation;
task<void> ppl(bool& done)
{
co_await resume_background();
done = true;
}
IAsyncAction async(bool& done)
{
co_await resume_background();
done = true;
}
IAsyncOperation<int> when_signaled(int value, handle const& event)
{
co_await resume_on_signal(event.get());
co_return value;
}
IAsyncAction done()
{
co_return;
}
TEST_CASE("when")
{
{
bool ppl_done = false;
bool async_done = false;
// Ensures that different async types can be aggregated.
when_all(ppl(ppl_done), async(async_done)).get();
REQUIRE(ppl_done);
REQUIRE(async_done);
}
{
// Works with IAsyncAction (with no return value).
IAsyncAction result = when_any(done(), done());
result.get();
}
{
handle first_event{ check_pointer(CreateEventW(nullptr, true, false, nullptr)) };
handle second_event{ check_pointer(CreateEventW(nullptr, true, false, nullptr)) };
IAsyncOperation<int> first = when_signaled(1, first_event);
IAsyncOperation<int> second = when_signaled(2, second_event);
IAsyncOperation<int> result = when_any(first, second);
// Make sure we're still waiting.
Sleep(100);
REQUIRE(result.Status() == AsyncStatus::Started);
REQUIRE(first.Status() == AsyncStatus::Started);
REQUIRE(second.Status() == AsyncStatus::Started);
// Allow only one of the async objects to complete.
SetEvent(second_event.get());
// This should now complete.
REQUIRE(2 == result.get());
REQUIRE(first.Status() == AsyncStatus::Started);
REQUIRE(second.Status() == AsyncStatus::Completed);
SetEvent(first_event.get());
}
}