// WARNING: Please don't edit this file. It was generated by C++/WinRT v2.0.240405.15 #pragma once #ifndef WINRT_Windows_Foundation_Collections_H #define WINRT_Windows_Foundation_Collections_H #include "winrt/base.h" static_assert(winrt::check_version(CPPWINRT_VERSION, "2.0.240405.15"), "Mismatched C++/WinRT headers."); #define CPPWINRT_VERSION "2.0.240405.15" #include "winrt/Windows.Foundation.h" #include "winrt/impl/Windows.Foundation.2.h" #include "winrt/impl/Windows.Foundation.Collections.2.h" namespace winrt::impl { template auto consume_Windows_Foundation_Collections_IIterable::First() const { void* winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IIterable)->First(&winrt_impl_result)); return winrt::Windows::Foundation::Collections::IIterator{ winrt_impl_result, take_ownership_from_abi }; } template auto consume_Windows_Foundation_Collections_IIterator::Current() const { T winrt_impl_result{ empty_value() }; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IIterator)->get_Current(put_abi(winrt_impl_result))); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IIterator::HasCurrent() const { bool winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IIterator)->get_HasCurrent(&winrt_impl_result)); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IIterator::MoveNext() const { bool winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IIterator)->MoveNext(&winrt_impl_result)); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IIterator::GetMany(array_view items) const { uint32_t winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IIterator)->GetMany(items.size(), put_abi(items), &winrt_impl_result)); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IKeyValuePair::Key() const { K winrt_impl_result{ empty_value() }; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IKeyValuePair)->get_Key(put_abi(winrt_impl_result))); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IKeyValuePair::Value() const { V winrt_impl_result{ empty_value() }; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IKeyValuePair)->get_Value(put_abi(winrt_impl_result))); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IMapChangedEventArgs::CollectionChange() const { winrt::Windows::Foundation::Collections::CollectionChange winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IMapChangedEventArgs)->get_CollectionChange(reinterpret_cast(&winrt_impl_result))); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IMapChangedEventArgs::Key() const { K winrt_impl_result{ empty_value() }; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IMapChangedEventArgs)->get_Key(put_abi(winrt_impl_result))); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IMapView::Lookup(impl::param_type const& key) const { V winrt_impl_result{ empty_value() }; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IMapView)->Lookup(impl::bind_in(key), put_abi(winrt_impl_result))); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IMapView::Size() const { uint32_t winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IMapView)->get_Size(&winrt_impl_result)); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IMapView::HasKey(impl::param_type const& key) const { bool winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IMapView)->HasKey(impl::bind_in(key), &winrt_impl_result)); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IMapView::Split(winrt::Windows::Foundation::Collections::IMapView& first, winrt::Windows::Foundation::Collections::IMapView& second) const { check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IMapView)->Split(impl::bind_out(first), impl::bind_out(second))); } template auto consume_Windows_Foundation_Collections_IMap::Lookup(impl::param_type const& key) const { V winrt_impl_result{ empty_value() }; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IMap)->Lookup(impl::bind_in(key), put_abi(winrt_impl_result))); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IMap::Size() const { uint32_t winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IMap)->get_Size(&winrt_impl_result)); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IMap::HasKey(impl::param_type const& key) const { bool winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IMap)->HasKey(impl::bind_in(key), &winrt_impl_result)); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IMap::GetView() const { void* winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IMap)->GetView(&winrt_impl_result)); return winrt::Windows::Foundation::Collections::IMapView{ winrt_impl_result, take_ownership_from_abi }; } template auto consume_Windows_Foundation_Collections_IMap::Insert(impl::param_type const& key, impl::param_type const& value) const { bool winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IMap)->Insert(impl::bind_in(key), impl::bind_in(value), &winrt_impl_result)); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IMap::Remove(impl::param_type const& key) const { check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IMap)->Remove(impl::bind_in(key))); } template auto consume_Windows_Foundation_Collections_IMap::Clear() const { check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IMap)->Clear()); } template auto consume_Windows_Foundation_Collections_IObservableMap::MapChanged(winrt::Windows::Foundation::Collections::MapChangedEventHandler const& vhnd) const { winrt::event_token winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IObservableMap)->add_MapChanged(*(void**)(&vhnd), put_abi(winrt_impl_result))); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IObservableMap::MapChanged(auto_revoke_t, winrt::Windows::Foundation::Collections::MapChangedEventHandler const& vhnd) const { return impl::make_event_revoker(this, MapChanged(vhnd)); } template auto consume_Windows_Foundation_Collections_IObservableMap::MapChanged(winrt::event_token const& token) const noexcept { WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IObservableMap)->remove_MapChanged(impl::bind_in(token)); } template auto consume_Windows_Foundation_Collections_IObservableVector::VectorChanged(winrt::Windows::Foundation::Collections::VectorChangedEventHandler const& vhnd) const { winrt::event_token winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IObservableVector)->add_VectorChanged(*(void**)(&vhnd), put_abi(winrt_impl_result))); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IObservableVector::VectorChanged(auto_revoke_t, winrt::Windows::Foundation::Collections::VectorChangedEventHandler const& vhnd) const { return impl::make_event_revoker(this, VectorChanged(vhnd)); } template auto consume_Windows_Foundation_Collections_IObservableVector::VectorChanged(winrt::event_token const& token) const noexcept { WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IObservableVector)->remove_VectorChanged(impl::bind_in(token)); } template auto consume_Windows_Foundation_Collections_IVectorChangedEventArgs::CollectionChange() const { winrt::Windows::Foundation::Collections::CollectionChange value{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVectorChangedEventArgs)->get_CollectionChange(reinterpret_cast(&value))); return value; } template auto consume_Windows_Foundation_Collections_IVectorChangedEventArgs::Index() const { uint32_t value{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVectorChangedEventArgs)->get_Index(&value)); return value; } template auto consume_Windows_Foundation_Collections_IVectorView::GetAt(uint32_t index) const { T winrt_impl_result{ empty_value() }; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVectorView)->GetAt(index, put_abi(winrt_impl_result))); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IVectorView::Size() const { uint32_t winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVectorView)->get_Size(&winrt_impl_result)); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IVectorView::IndexOf(impl::param_type const& value, uint32_t& index) const { bool winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVectorView)->IndexOf(impl::bind_in(value), &index, &winrt_impl_result)); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IVectorView::GetMany(uint32_t startIndex, array_view items) const { uint32_t winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVectorView)->GetMany(startIndex, items.size(), put_abi(items), &winrt_impl_result)); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IVector::GetAt(uint32_t index) const { T winrt_impl_result{ empty_value() }; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVector)->GetAt(index, put_abi(winrt_impl_result))); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IVector::Size() const { uint32_t winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVector)->get_Size(&winrt_impl_result)); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IVector::GetView() const { void* winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVector)->GetView(&winrt_impl_result)); return winrt::Windows::Foundation::Collections::IVectorView{ winrt_impl_result, take_ownership_from_abi }; } template auto consume_Windows_Foundation_Collections_IVector::IndexOf(impl::param_type const& value, uint32_t& index) const { bool winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVector)->IndexOf(impl::bind_in(value), &index, &winrt_impl_result)); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IVector::SetAt(uint32_t index, impl::param_type const& value) const { check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVector)->SetAt(index, impl::bind_in(value))); } template auto consume_Windows_Foundation_Collections_IVector::InsertAt(uint32_t index, impl::param_type const& value) const { check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVector)->InsertAt(index, impl::bind_in(value))); } template auto consume_Windows_Foundation_Collections_IVector::RemoveAt(uint32_t index) const { check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVector)->RemoveAt(index)); } template auto consume_Windows_Foundation_Collections_IVector::Append(impl::param_type const& value) const { check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVector)->Append(impl::bind_in(value))); } template auto consume_Windows_Foundation_Collections_IVector::RemoveAtEnd() const { check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVector)->RemoveAtEnd()); } template auto consume_Windows_Foundation_Collections_IVector::Clear() const { check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVector)->Clear()); } template auto consume_Windows_Foundation_Collections_IVector::GetMany(uint32_t startIndex, array_view items) const { uint32_t winrt_impl_result{}; check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVector)->GetMany(startIndex, items.size(), put_abi(items), &winrt_impl_result)); return winrt_impl_result; } template auto consume_Windows_Foundation_Collections_IVector::ReplaceAll(array_view items) const { check_hresult(WINRT_IMPL_SHIM(winrt::Windows::Foundation::Collections::IVector)->ReplaceAll(items.size(), get_abi(items))); } template struct delegate, H> final : implements_delegate, H> { delegate(H&& handler) : implements_delegate, H>(std::forward(handler)) {} int32_t __stdcall Invoke(void* sender, void* event) noexcept final try { (*this)(*reinterpret_cast const*>(&sender), *reinterpret_cast const*>(&event)); return 0; } catch (...) { return to_hresult(); } }; template struct delegate, H> final : implements_delegate, H> { delegate(H&& handler) : implements_delegate, H>(std::forward(handler)) {} int32_t __stdcall Invoke(void* sender, void* event) noexcept final try { (*this)(*reinterpret_cast const*>(&sender), *reinterpret_cast(&event)); return 0; } catch (...) { return to_hresult(); } }; template struct produce> : produce_base> { int32_t __stdcall First(void** winrt_impl_result) noexcept final try { clear_abi(winrt_impl_result); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from>(this->shim().First()); return 0; } catch (...) { return to_hresult(); } }; template struct produce> : produce_base> { int32_t __stdcall get_Current(arg_out winrt_impl_result) noexcept final try { clear_abi(winrt_impl_result); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().Current()); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall get_HasCurrent(bool* winrt_impl_result) noexcept final try { typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().HasCurrent()); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall MoveNext(bool* winrt_impl_result) noexcept final try { typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().MoveNext()); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall GetMany(uint32_t __itemsSize, arg_out items, uint32_t* winrt_impl_result) noexcept final try { zero_abi(items, __itemsSize); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().GetMany(array_view(reinterpret_cast(items), reinterpret_cast(items) + __itemsSize))); return 0; } catch (...) { return to_hresult(); } }; template struct produce> : produce_base> { int32_t __stdcall get_Key(arg_out winrt_impl_result) noexcept final try { clear_abi(winrt_impl_result); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().Key()); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall get_Value(arg_out winrt_impl_result) noexcept final try { clear_abi(winrt_impl_result); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().Value()); return 0; } catch (...) { return to_hresult(); } }; template struct produce> : produce_base> { int32_t __stdcall get_CollectionChange(int32_t* winrt_impl_result) noexcept final try { typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().CollectionChange()); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall get_Key(arg_out winrt_impl_result) noexcept final try { clear_abi(winrt_impl_result); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().Key()); return 0; } catch (...) { return to_hresult(); } }; template struct produce> : produce_base> { int32_t __stdcall Lookup(arg_in key, arg_out winrt_impl_result) noexcept final try { clear_abi(winrt_impl_result); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().Lookup(*reinterpret_cast(&key))); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall get_Size(uint32_t* winrt_impl_result) noexcept final try { typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().Size()); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall HasKey(arg_in key, bool* winrt_impl_result) noexcept final try { typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().HasKey(*reinterpret_cast(&key))); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall Split(void** first, void** second) noexcept final try { clear_abi(first); clear_abi(second); typename D::abi_guard guard(this->shim()); this->shim().Split(*reinterpret_cast*>(first), *reinterpret_cast*>(second)); return 0; } catch (...) { return to_hresult(); } }; template struct produce> : produce_base> { int32_t __stdcall Lookup(arg_in key, arg_out winrt_impl_result) noexcept final try { clear_abi(winrt_impl_result); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().Lookup(*reinterpret_cast(&key))); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall get_Size(uint32_t* winrt_impl_result) noexcept final try { typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().Size()); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall HasKey(arg_in key, bool* winrt_impl_result) noexcept final try { typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().HasKey(*reinterpret_cast(&key))); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall GetView(void** winrt_impl_result) noexcept final try { clear_abi(winrt_impl_result); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from>(this->shim().GetView()); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall Insert(arg_in key, arg_in value, bool* winrt_impl_result) noexcept final try { typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().Insert(*reinterpret_cast(&key), *reinterpret_cast(&value))); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall Remove(arg_in key) noexcept final try { typename D::abi_guard guard(this->shim()); this->shim().Remove(*reinterpret_cast(&key)); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall Clear() noexcept final try { typename D::abi_guard guard(this->shim()); this->shim().Clear(); return 0; } catch (...) { return to_hresult(); } }; template struct produce> : produce_base> { int32_t __stdcall add_MapChanged(void* vhnd, winrt::event_token* winrt_impl_result) noexcept final try { zero_abi(winrt_impl_result); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().MapChanged(*reinterpret_cast const*>(&vhnd))); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall remove_MapChanged(winrt::event_token token) noexcept final { typename D::abi_guard guard(this->shim()); this->shim().MapChanged(*reinterpret_cast(&token)); return 0; } }; template struct produce> : produce_base> { int32_t __stdcall add_VectorChanged(void* vhnd, winrt::event_token* winrt_impl_result) noexcept final try { zero_abi(winrt_impl_result); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().VectorChanged(*reinterpret_cast const*>(&vhnd))); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall remove_VectorChanged(winrt::event_token token) noexcept final { typename D::abi_guard guard(this->shim()); this->shim().VectorChanged(*reinterpret_cast(&token)); return 0; } }; template struct produce : produce_base { }; template struct produce : produce_base { int32_t __stdcall get_CollectionChange(int32_t* value) noexcept final try { typename D::abi_guard guard(this->shim()); *value = detach_from(this->shim().CollectionChange()); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall get_Index(uint32_t* value) noexcept final try { typename D::abi_guard guard(this->shim()); *value = detach_from(this->shim().Index()); return 0; } catch (...) { return to_hresult(); } }; template struct produce> : produce_base> { int32_t __stdcall GetAt(uint32_t index, arg_out winrt_impl_result) noexcept final try { clear_abi(winrt_impl_result); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().GetAt(index)); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall get_Size(uint32_t* winrt_impl_result) noexcept final try { typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().Size()); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall IndexOf(arg_in value, uint32_t* index, bool* winrt_impl_result) noexcept final try { typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().IndexOf(*reinterpret_cast(&value), *index)); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall GetMany(uint32_t startIndex, uint32_t __itemsSize, arg_out items, uint32_t* winrt_impl_result) noexcept final try { zero_abi(items, __itemsSize); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().GetMany(startIndex, array_view(reinterpret_cast(items), reinterpret_cast(items) + __itemsSize))); return 0; } catch (...) { return to_hresult(); } }; template struct produce> : produce_base> { int32_t __stdcall GetAt(uint32_t index, arg_out winrt_impl_result) noexcept final try { clear_abi(winrt_impl_result); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().GetAt(index)); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall get_Size(uint32_t* winrt_impl_result) noexcept final try { typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().Size()); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall GetView(void** winrt_impl_result) noexcept final try { clear_abi(winrt_impl_result); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from>(this->shim().GetView()); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall IndexOf(arg_in value, uint32_t* index, bool* winrt_impl_result) noexcept final try { typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().IndexOf(*reinterpret_cast(&value), *index)); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall SetAt(uint32_t index, arg_in value) noexcept final try { typename D::abi_guard guard(this->shim()); this->shim().SetAt(index, *reinterpret_cast(&value)); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall InsertAt(uint32_t index, arg_in value) noexcept final try { typename D::abi_guard guard(this->shim()); this->shim().InsertAt(index, *reinterpret_cast(&value)); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall RemoveAt(uint32_t index) noexcept final try { typename D::abi_guard guard(this->shim()); this->shim().RemoveAt(index); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall Append(arg_in value) noexcept final try { typename D::abi_guard guard(this->shim()); this->shim().Append(*reinterpret_cast(&value)); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall RemoveAtEnd() noexcept final try { typename D::abi_guard guard(this->shim()); this->shim().RemoveAtEnd(); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall Clear() noexcept final try { typename D::abi_guard guard(this->shim()); this->shim().Clear(); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall GetMany(uint32_t startIndex, uint32_t __itemsSize, arg_out items, uint32_t* winrt_impl_result) noexcept final try { zero_abi(items, __itemsSize); typename D::abi_guard guard(this->shim()); *winrt_impl_result = detach_from(this->shim().GetMany(startIndex, array_view(reinterpret_cast(items), reinterpret_cast(items) + __itemsSize))); return 0; } catch (...) { return to_hresult(); } int32_t __stdcall ReplaceAll(uint32_t __itemsSize, arg_out items) noexcept final try { typename D::abi_guard guard(this->shim()); this->shim().ReplaceAll(array_view(reinterpret_cast(items), reinterpret_cast(items) + __itemsSize)); return 0; } catch (...) { return to_hresult(); } }; } WINRT_EXPORT namespace winrt::Windows::Foundation::Collections { inline PropertySet::PropertySet() : PropertySet(impl::call_factory_cast([](winrt::Windows::Foundation::IActivationFactory const& f) { return f.template ActivateInstance(); })) { } inline StringMap::StringMap() : StringMap(impl::call_factory_cast([](winrt::Windows::Foundation::IActivationFactory const& f) { return f.template ActivateInstance(); })) { } inline ValueSet::ValueSet() : ValueSet(impl::call_factory_cast([](winrt::Windows::Foundation::IActivationFactory const& f) { return f.template ActivateInstance(); })) { } template template MapChangedEventHandler::MapChangedEventHandler(L handler) : MapChangedEventHandler(impl::make_delegate>(std::forward(handler))) { } template template MapChangedEventHandler::MapChangedEventHandler(F* handler) : MapChangedEventHandler([=](auto&&... args) { return handler(args...); }) { } template template MapChangedEventHandler::MapChangedEventHandler(O* object, M method) : MapChangedEventHandler([=](auto&&... args) { return ((*object).*(method))(args...); }) { } template template MapChangedEventHandler::MapChangedEventHandler(com_ptr&& object, M method) : MapChangedEventHandler([o = std::move(object), method](auto&&... args) { return ((*o).*(method))(args...); }) { } template template MapChangedEventHandler::MapChangedEventHandler(weak_ref&& object, LM&& lambda_or_method) : MapChangedEventHandler([o = std::move(object), lm = std::forward(lambda_or_method)](auto&&... args) { if (auto s = o.get()) { if constexpr (std::is_member_function_pointer_v) ((*s).*(lm))(args...); else lm(args...); } }) { } template template MapChangedEventHandler::MapChangedEventHandler(std::shared_ptr&& object, M method) : MapChangedEventHandler([o = std::move(object), method](auto&&... args) { return ((*o).*(method))(args...); }) { } template template MapChangedEventHandler::MapChangedEventHandler(std::weak_ptr&& object, LM&& lambda_or_method) : MapChangedEventHandler([o = std::move(object), lm = std::forward(lambda_or_method)](auto&&... args) { if (auto s = o.lock()) { if constexpr (std::is_member_function_pointer_v) ((*s).*(lm))(args...); else lm(args...); } }) { } template auto MapChangedEventHandler::operator()(winrt::Windows::Foundation::Collections::IObservableMap const& sender, winrt::Windows::Foundation::Collections::IMapChangedEventArgs const& event) const { check_hresult((*(impl::abi_t>**)this)->Invoke(*(void**)(&sender), *(void**)(&event))); } template template VectorChangedEventHandler::VectorChangedEventHandler(L handler) : VectorChangedEventHandler(impl::make_delegate>(std::forward(handler))) { } template template VectorChangedEventHandler::VectorChangedEventHandler(F* handler) : VectorChangedEventHandler([=](auto&&... args) { return handler(args...); }) { } template template VectorChangedEventHandler::VectorChangedEventHandler(O* object, M method) : VectorChangedEventHandler([=](auto&&... args) { return ((*object).*(method))(args...); }) { } template template VectorChangedEventHandler::VectorChangedEventHandler(com_ptr&& object, M method) : VectorChangedEventHandler([o = std::move(object), method](auto&&... args) { return ((*o).*(method))(args...); }) { } template template VectorChangedEventHandler::VectorChangedEventHandler(weak_ref&& object, LM&& lambda_or_method) : VectorChangedEventHandler([o = std::move(object), lm = std::forward(lambda_or_method)](auto&&... args) { if (auto s = o.get()) { if constexpr (std::is_member_function_pointer_v) ((*s).*(lm))(args...); else lm(args...); } }) { } template template VectorChangedEventHandler::VectorChangedEventHandler(std::shared_ptr&& object, M method) : VectorChangedEventHandler([o = std::move(object), method](auto&&... args) { return ((*o).*(method))(args...); }) { } template template VectorChangedEventHandler::VectorChangedEventHandler(std::weak_ptr&& object, LM&& lambda_or_method) : VectorChangedEventHandler([o = std::move(object), lm = std::forward(lambda_or_method)](auto&&... args) { if (auto s = o.lock()) { if constexpr (std::is_member_function_pointer_v) ((*s).*(lm))(args...); else lm(args...); } }) { } template auto VectorChangedEventHandler::operator()(winrt::Windows::Foundation::Collections::IObservableVector const& sender, winrt::Windows::Foundation::Collections::IVectorChangedEventArgs const& event) const { check_hresult((*(impl::abi_t>**)this)->Invoke(*(void**)(&sender), *(void**)(&event))); } } namespace std { #ifndef WINRT_LEAN_AND_MEAN template struct hash> : winrt::impl::hash_base {}; template struct hash> : winrt::impl::hash_base {}; template struct hash> : winrt::impl::hash_base {}; template struct hash> : winrt::impl::hash_base {}; template struct hash> : winrt::impl::hash_base {}; template struct hash> : winrt::impl::hash_base {}; template struct hash> : winrt::impl::hash_base {}; template struct hash> : winrt::impl::hash_base {}; template<> struct hash : winrt::impl::hash_base {}; template<> struct hash : winrt::impl::hash_base {}; template struct hash> : winrt::impl::hash_base {}; template struct hash> : winrt::impl::hash_base {}; template<> struct hash : winrt::impl::hash_base {}; template<> struct hash : winrt::impl::hash_base {}; template<> struct hash : winrt::impl::hash_base {}; #endif #ifdef __cpp_lib_format #endif } namespace winrt::impl { namespace wfc = Windows::Foundation::Collections; template auto consume_Windows_Foundation_Collections_IIterable::begin() const { return get_begin_iterator(static_cast(*this)); } template auto consume_Windows_Foundation_Collections_IIterable::end() const { return get_end_iterator(static_cast(*this)); } template struct key_value_pair; template struct key_value_pair> : implements>, wfc::IKeyValuePair> { key_value_pair(K key, V value) : m_key(std::move(key)), m_value(std::move(value)) { } K Key() const { return m_key; } V Value() const { return m_value; } private: K const m_key; V const m_value; }; template struct is_key_value_pair : std::false_type {}; template struct is_key_value_pair> : std::true_type {}; struct input_scope { void invalidate_scope() noexcept { m_invalid = true; } void check_scope() const { if (m_invalid) { throw hresult_illegal_method_call(); } } private: bool m_invalid{}; }; struct no_collection_version { struct iterator_type { iterator_type(no_collection_version const&) noexcept { } void check_version(no_collection_version const&) const noexcept { } }; }; struct collection_version { struct iterator_type { iterator_type(collection_version const& version) noexcept : m_snapshot(version.get_version()) { } void check_version(collection_version const& version) const { if (version.get_version() != m_snapshot) { throw hresult_changed_state(); } } private: uint32_t const m_snapshot; }; uint32_t get_version() const noexcept { return m_version; } void increment_version() noexcept { ++m_version; } private: std::atomic m_version{}; }; template struct range_container { T const first; T const last; auto begin() const noexcept { return first; } auto end() const noexcept { return last; } }; } namespace winrt::impl { struct nop_lock_guard {}; struct single_threaded_collection_base { [[nodiscard]] auto acquire_exclusive() const { return nop_lock_guard{}; } [[nodiscard]] auto acquire_shared() const { return nop_lock_guard(); } }; struct multi_threaded_collection_base { [[nodiscard]] auto acquire_exclusive() const { return slim_lock_guard{m_mutex}; } [[nodiscard]] auto acquire_shared() const { return slim_shared_lock_guard{m_mutex}; } private: mutable slim_mutex m_mutex; }; template using container_type_t = std::decay_t().get_container())>; template struct removed_values { void assign(container_type_t& value) { // Trivially destructible; okay to run destructors under lock and clearing allows potential re-use of buffers value.clear(); } }; template struct removed_values::value_type>>> { container_type_t m_value; void assign(container_type_t& value) { m_value.swap(value); } }; template struct removed_value { // Trivially destructible; okay to run destructor under lock template void assign(U&&) {} }; template struct removed_value && !std::is_trivially_destructible_v>> { std::optional m_value; template void assign(U&& value) { m_value.emplace(std::move(value)); } }; } WINRT_EXPORT namespace winrt { template struct iterable_base : Version { template static constexpr auto const& wrap_value(U const& value) noexcept { return value; } template static constexpr auto const& unwrap_value(U const& value) noexcept { return value; } auto acquire_exclusive() const { return impl::nop_lock_guard{}; } auto acquire_shared() const { // Support for concurrent "shared" operations is optional return static_cast(*this).acquire_exclusive(); } auto First() { // NOTE: iterator's constructor requires shared access auto guard = static_cast(*this).acquire_shared(); return make(static_cast(this)); } protected: template auto copy_n(InputIt first, Size count, OutputIt result) const { if constexpr (std::is_same_v().get_container().begin())>> && !impl::is_key_value_pair::value) { std::copy_n(first, count, result); } else { return std::transform(first, std::next(first, count), result, [&](auto&& value) { if constexpr (!impl::is_key_value_pair::value) { return static_cast(*this).unwrap_value(value); } else { return make>(static_cast(*this).unwrap_value(value.first), static_cast(*this).unwrap_value(value.second)); } }); } } private: struct iterator : Version::iterator_type, implements> { void abi_enter() { m_owner->abi_enter(); } void abi_exit() { m_owner->abi_exit(); } explicit iterator(D* const owner) noexcept : Version::iterator_type(*owner), m_current(owner->get_container().begin()), m_end(owner->get_container().end()) { m_owner.copy_from(owner); } T Current() const { auto guard = m_owner->acquire_shared(); this->check_version(*m_owner); if (m_current == m_end) { throw hresult_out_of_bounds(); } return current_value_withlock(); } bool HasCurrent() const { auto guard = m_owner->acquire_shared(); this->check_version(*m_owner); return m_current != m_end; } bool MoveNext() { auto guard = m_owner->acquire_exclusive(); this->check_version(*m_owner); if (m_current != m_end) { ++m_current; } return m_current != m_end; } uint32_t GetMany(array_view values) { auto guard = m_owner->acquire_exclusive(); this->check_version(*m_owner); return GetMany(values, typename std::iterator_traits::iterator_category()); } private: T current_value_withlock() const { WINRT_ASSERT(m_current != m_end); if constexpr (!impl::is_key_value_pair::value) { return m_owner->unwrap_value(*m_current); } else { return make>(m_owner->unwrap_value(m_current->first), m_owner->unwrap_value(m_current->second)); } } uint32_t GetMany(array_view values, std::random_access_iterator_tag) { uint32_t const actual = (std::min)(static_cast(m_end - m_current), values.size()); m_owner->copy_n(m_current, actual, values.begin()); m_current += actual; return actual; } uint32_t GetMany(array_view values, std::input_iterator_tag) { auto output = values.begin(); while (output < values.end() && m_current != m_end) { *output = current_value_withlock(); ++output; ++m_current; } return static_cast(output - values.begin()); } using iterator_type = decltype(std::declval().get_container().begin()); com_ptr m_owner; iterator_type m_current; iterator_type const m_end; }; }; template struct vector_view_base : iterable_base { T GetAt(uint32_t const index) const { auto guard = static_cast(*this).acquire_shared(); if (index >= container_size()) { throw hresult_out_of_bounds(); } return static_cast(*this).unwrap_value(*std::next(static_cast(*this).get_container().begin(), index)); } uint32_t Size() const noexcept { auto guard = static_cast(*this).acquire_shared(); return container_size(); } bool IndexOf(T const& value, uint32_t& index) const noexcept { auto guard = static_cast(*this).acquire_shared(); auto first = std::find_if(static_cast(*this).get_container().begin(), static_cast(*this).get_container().end(), [&](auto&& match) { return value == static_cast(*this).unwrap_value(match); }); index = static_cast(first - static_cast(*this).get_container().begin()); return index < container_size(); } uint32_t GetMany(uint32_t const startIndex, array_view values) const { auto guard = static_cast(*this).acquire_shared(); if (startIndex >= container_size()) { return 0; } uint32_t const actual = (std::min)(container_size() - startIndex, values.size()); this->copy_n(static_cast(*this).get_container().begin() + startIndex, actual, values.begin()); return actual; } private: uint32_t container_size() const noexcept { return static_cast(std::distance(static_cast(*this).get_container().begin(), static_cast(*this).get_container().end())); } }; template struct vector_base : vector_view_base { Windows::Foundation::Collections::IVectorView GetView() const noexcept { return static_cast(*this); } void SetAt(uint32_t const index, T const& value) { impl::removed_value::value_type> oldValue; auto guard = static_cast(*this).acquire_exclusive(); if (index >= static_cast(*this).get_container().size()) { throw hresult_out_of_bounds(); } this->increment_version(); auto&& pos = static_cast(*this).get_container()[index]; oldValue.assign(pos); pos = static_cast(*this).wrap_value(value); } void InsertAt(uint32_t const index, T const& value) { auto guard = static_cast(*this).acquire_exclusive(); if (index > static_cast(*this).get_container().size()) { throw hresult_out_of_bounds(); } this->increment_version(); static_cast(*this).get_container().insert(static_cast(*this).get_container().begin() + index, static_cast(*this).wrap_value(value)); } void RemoveAt(uint32_t const index) { impl::removed_value::value_type> removedValue; auto guard = static_cast(*this).acquire_exclusive(); if (index >= static_cast(*this).get_container().size()) { throw hresult_out_of_bounds(); } this->increment_version(); auto itr = static_cast(*this).get_container().begin() + index; removedValue.assign(*itr); static_cast(*this).get_container().erase(itr); } void Append(T const& value) { auto guard = static_cast(*this).acquire_exclusive(); this->increment_version(); static_cast(*this).get_container().push_back(static_cast(*this).wrap_value(value)); } void RemoveAtEnd() { impl::removed_value::value_type> removedValue; auto guard = static_cast(*this).acquire_exclusive(); if (static_cast(*this).get_container().empty()) { throw hresult_out_of_bounds(); } this->increment_version(); removedValue.assign(static_cast(*this).get_container().back()); static_cast(*this).get_container().pop_back(); } void Clear() noexcept { impl::removed_values oldContainer; auto guard = static_cast(*this).acquire_exclusive(); this->increment_version(); oldContainer.assign(static_cast(*this).get_container()); } void ReplaceAll(array_view value) { impl::removed_values oldContainer; auto guard = static_cast(*this).acquire_exclusive(); this->increment_version(); oldContainer.assign(static_cast(*this).get_container()); assign(value.begin(), value.end()); } private: template void assign(InputIt first, InputIt last) { if constexpr (std::is_same_v::value_type>) { static_cast(*this).get_container().assign(first, last); } else { auto& container = static_cast(*this).get_container(); WINRT_ASSERT(container.empty()); container.reserve(std::distance(first, last)); std::transform(first, last, std::back_inserter(container), [&](auto&& value) { return static_cast(*this).wrap_value(value); }); } } }; template struct observable_vector_base : vector_base { event_token VectorChanged(Windows::Foundation::Collections::VectorChangedEventHandler const& handler) { return m_changed.add(handler); } void VectorChanged(event_token const cookie) { m_changed.remove(cookie); } void SetAt(uint32_t const index, T const& value) { vector_base::SetAt(index, value); call_changed(Windows::Foundation::Collections::CollectionChange::ItemChanged, index); } void InsertAt(uint32_t const index, T const& value) { vector_base::InsertAt(index, value); call_changed(Windows::Foundation::Collections::CollectionChange::ItemInserted, index); } void RemoveAt(uint32_t const index) { vector_base::RemoveAt(index); call_changed(Windows::Foundation::Collections::CollectionChange::ItemRemoved, index); } void Append(T const& value) { vector_base::Append(value); call_changed(Windows::Foundation::Collections::CollectionChange::ItemInserted, this->Size() - 1); } void RemoveAtEnd() { vector_base::RemoveAtEnd(); call_changed(Windows::Foundation::Collections::CollectionChange::ItemRemoved, this->Size()); } void Clear() { vector_base::Clear(); call_changed(Windows::Foundation::Collections::CollectionChange::Reset, 0); } void ReplaceAll(array_view value) { vector_base::ReplaceAll(value); call_changed(Windows::Foundation::Collections::CollectionChange::Reset, 0); } protected: void call_changed(Windows::Foundation::Collections::CollectionChange const change, uint32_t const index) { m_changed(static_cast(*this), make(change, index)); } private: event> m_changed; struct args : implements { args(Windows::Foundation::Collections::CollectionChange const change, uint32_t const index) noexcept : m_change(change), m_index(index) { } Windows::Foundation::Collections::CollectionChange CollectionChange() const noexcept { return m_change; } uint32_t Index() const noexcept { return m_index; } private: Windows::Foundation::Collections::CollectionChange const m_change; uint32_t const m_index; }; }; template struct map_view_base : iterable_base, Version> { V Lookup(K const& key) const { auto guard = static_cast(*this).acquire_shared(); auto pair = static_cast(*this).get_container().find(static_cast(*this).wrap_value(key)); if (pair == static_cast(*this).get_container().end()) { throw hresult_out_of_bounds(); } return static_cast(*this).unwrap_value(pair->second); } uint32_t Size() const noexcept { auto guard = static_cast(*this).acquire_shared(); return static_cast(static_cast(*this).get_container().size()); } bool HasKey(K const& key) const noexcept { auto guard = static_cast(*this).acquire_shared(); return static_cast(*this).get_container().find(static_cast(*this).wrap_value(key)) != static_cast(*this).get_container().end(); } void Split(Windows::Foundation::Collections::IMapView& first, Windows::Foundation::Collections::IMapView& second) const noexcept { first = nullptr; second = nullptr; } }; template struct map_base : map_view_base { Windows::Foundation::Collections::IMapView GetView() const { return static_cast(*this); } bool Insert(K const& key, V const& value) { impl::removed_value::mapped_type> oldValue; auto guard = static_cast(*this).acquire_exclusive(); this->increment_version(); auto [itr, added] = static_cast(*this).get_container().emplace(static_cast(*this).wrap_value(key), static_cast(*this).wrap_value(value)); if (!added) { oldValue.assign(itr->second); itr->second = static_cast(*this).wrap_value(value); } return !added; } void Remove(K const& key) { typename impl::container_type_t::node_type removedNode; auto guard = static_cast(*this).acquire_exclusive(); auto& container = static_cast(*this).get_container(); auto found = container.find(static_cast(*this).wrap_value(key)); if (found == container.end()) { throw hresult_out_of_bounds(); } this->increment_version(); removedNode = container.extract(found); } void Clear() noexcept { impl::removed_values oldContainer; auto guard = static_cast(*this).acquire_exclusive(); this->increment_version(); oldContainer.assign(static_cast(*this).get_container()); } }; template struct observable_map_base : map_base { event_token MapChanged(Windows::Foundation::Collections::MapChangedEventHandler const& handler) { return m_changed.add(handler); } void MapChanged(event_token const cookie) { m_changed.remove(cookie); } bool Insert(K const& key, V const& value) { bool const result = map_base::Insert(key, value); call_changed(Windows::Foundation::Collections::CollectionChange::ItemInserted, key); return result; } void Remove(K const& key) { map_base::Remove(key); call_changed(Windows::Foundation::Collections::CollectionChange::ItemRemoved, key); } void Clear() noexcept { map_base::Clear(); call_changed(Windows::Foundation::Collections::CollectionChange::Reset, impl::empty_value()); } private: event> m_changed; void call_changed(Windows::Foundation::Collections::CollectionChange const change, K const& key) { m_changed(static_cast(*this), make(change, key)); } struct args : implements> { args(Windows::Foundation::Collections::CollectionChange const change, K const& key) noexcept : m_change(change), m_key(key) { } Windows::Foundation::Collections::CollectionChange CollectionChange() const noexcept { return m_change; } K Key() const noexcept { return m_key; } private: Windows::Foundation::Collections::CollectionChange const m_change; K const m_key; }; }; } namespace winrt::impl { template struct input_iterable : implements, non_agile, no_weak_ref, wfc::IIterable>, iterable_base, T> { static_assert(std::is_same_v>, "Must be constructed with rvalue."); explicit input_iterable(Container&& values) : m_values(std::forward(values)) { } auto& get_container() const noexcept { return m_values; } private: Container const m_values; }; template struct scoped_input_iterable : input_scope, implements, non_agile, no_weak_ref, wfc::IIterable>, iterable_base, T> { void abi_enter() const { check_scope(); } scoped_input_iterable(InputIt first, InputIt last) : m_begin(first), m_end(last) { } auto get_container() const noexcept { return range_container{ m_begin, m_end }; } #if defined(_DEBUG) && !defined(WINRT_NO_MAKE_DETECTION) void use_make_function_to_create_this_object() final { } #endif private: InputIt const m_begin; InputIt const m_end; }; template auto make_input_iterable(Container&& values) { return make>(std::forward(values)); } template auto make_scoped_input_iterable(InputIt first, InputIt last) { using interface_type = wfc::IIterable; std::pair result; auto ptr = new scoped_input_iterable(first, last); *put_abi(result.first) = to_abi(ptr); result.second = ptr; return result; } } WINRT_EXPORT namespace winrt::param { template struct iterable { using value_type = T; using interface_type = Windows::Foundation::Collections::IIterable; iterable(std::nullptr_t) noexcept { } iterable(iterable const& values) = delete; iterable& operator=(iterable const& values) = delete; iterable(interface_type const& values) noexcept : m_owned(false) { attach_abi(m_pair.first, winrt::get_abi(values)); } template , int> = 0> iterable(Collection const& values) noexcept { m_pair.first = values; } template iterable(std::vector&& values) : m_pair(impl::make_input_iterable(std::move(values)), nullptr) { } template iterable(std::vector const& values) : m_pair(impl::make_scoped_input_iterable(values.begin(), values.end())) { } iterable(std::initializer_list values) : m_pair(impl::make_scoped_input_iterable(values.begin(), values.end())) { } template , int> = 0> iterable(std::initializer_list values) : m_pair(impl::make_scoped_input_iterable(values.begin(), values.end())) { } template iterable(InputIt first, InputIt last) : m_pair(impl::make_scoped_input_iterable(first, last)) { } ~iterable() noexcept { if (m_pair.second) { m_pair.second->invalidate_scope(); } if (!m_owned) { detach_abi(m_pair.first); } } operator interface_type const& () const noexcept { return m_pair.first; } private: std::pair m_pair; bool m_owned{ true }; }; template struct iterable> { using value_type = Windows::Foundation::Collections::IKeyValuePair; using interface_type = Windows::Foundation::Collections::IIterable; iterable(std::nullptr_t) noexcept { } iterable(iterable const& values) = delete; iterable& operator=(iterable const& values) = delete; iterable(interface_type const& values) noexcept : m_owned(false) { attach_abi(m_pair.first, winrt::get_abi(values)); } template , int> = 0> iterable(Collection const& values) noexcept { m_pair.first = values; } template iterable(std::map&& values) : m_pair(impl::make_input_iterable(std::move(values)), nullptr) { } template iterable(std::map const& values) : m_pair(impl::make_scoped_input_iterable(values.begin(), values.end())) { } template iterable(std::unordered_map&& values) : m_pair(impl::make_input_iterable(std::move(values)), nullptr) { } template iterable(std::unordered_map const& values) : m_pair(impl::make_scoped_input_iterable(values.begin(), values.end())) { } iterable(std::initializer_list> values) : m_pair(impl::make_scoped_input_iterable(values.begin(), values.end())) { } template iterable(InputIt first, InputIt last) : m_pair(impl::make_scoped_input_iterable(first, last)) { } ~iterable() noexcept { if (m_pair.second) { m_pair.second->invalidate_scope(); } if (!m_owned) { detach_abi(m_pair.first); } } operator interface_type const& () const noexcept { return m_pair.first; } private: std::pair m_pair; bool m_owned{ true }; }; template auto get_abi(iterable const& object) noexcept { return *(void**)(&object); } template struct async_iterable { using value_type = T; using interface_type = Windows::Foundation::Collections::IIterable; async_iterable(std::nullptr_t) noexcept { } async_iterable(async_iterable const& values) = delete; async_iterable& operator=(async_iterable const& values) = delete; async_iterable(interface_type const& values) noexcept : m_owned(false) { attach_abi(m_interface, winrt::get_abi(values)); } template , int> = 0> async_iterable(Collection const& values) noexcept { m_interface = values; } template async_iterable(std::vector&& values) : m_interface(impl::make_input_iterable(std::move(values))) { } async_iterable(std::initializer_list values) : m_interface(impl::make_input_iterable(std::vector(values))) { } ~async_iterable() noexcept { if (!m_owned) { detach_abi(m_interface); } } operator interface_type const& () const noexcept { return m_interface; } private: interface_type m_interface; bool m_owned{ true }; }; template struct async_iterable> { using value_type = Windows::Foundation::Collections::IKeyValuePair; using interface_type = Windows::Foundation::Collections::IIterable; async_iterable(std::nullptr_t) noexcept { } async_iterable(async_iterable const& values) = delete; async_iterable& operator=(async_iterable const& values) = delete; async_iterable(interface_type const& values) noexcept : m_owned(false) { attach_abi(m_interface, winrt::get_abi(values)); } template , int> = 0> async_iterable(Collection const& values) noexcept { m_interface = values; } template async_iterable(std::map&& values) : m_interface(impl::make_input_iterable(std::move(values))) { } template async_iterable(std::unordered_map&& values) : m_interface(impl::make_input_iterable(std::move(values))) { } async_iterable(std::initializer_list> values) : m_interface(impl::make_input_iterable(std::map(values))) { } ~async_iterable() noexcept { if (!m_owned) { detach_abi(m_interface); } } operator interface_type const& () const noexcept { return m_interface; } private: interface_type m_interface; bool m_owned{ true }; }; template auto get_abi(async_iterable const& object) noexcept { return *(void**)(&object); } } namespace winrt::impl { template struct input_vector_view : implements, non_agile, no_weak_ref, wfc::IVectorView, wfc::IIterable>, vector_view_base, T> { static_assert(std::is_same_v>, "Must be constructed with rvalue."); explicit input_vector_view(Container&& values) : m_values(std::forward(values)) { } auto& get_container() const noexcept { return m_values; } private: Container const m_values; }; template struct scoped_input_vector_view : input_scope, implements, non_agile, no_weak_ref, wfc::IVectorView, wfc::IIterable>, vector_view_base, T> { void abi_enter() const { check_scope(); } scoped_input_vector_view(InputIt first, InputIt last) : m_begin(first), m_end(last) { } auto get_container() const noexcept { return range_container{ m_begin, m_end }; } #if defined(_DEBUG) && !defined(WINRT_NO_MAKE_DETECTION) void use_make_function_to_create_this_object() final { } #endif private: InputIt const m_begin; InputIt const m_end; }; template auto make_scoped_input_vector_view(InputIt first, InputIt last) { using interface_type = wfc::IVectorView; std::pair result; auto ptr = new scoped_input_vector_view(first, last); *put_abi(result.first) = to_abi(ptr); result.second = ptr; return result; } } WINRT_EXPORT namespace winrt::param { template struct vector_view { using value_type = T; using interface_type = Windows::Foundation::Collections::IVectorView; vector_view(std::nullptr_t) noexcept { } vector_view(vector_view const& values) = delete; vector_view& operator=(vector_view const& values) = delete; vector_view(interface_type const& values) noexcept : m_owned(false) { attach_abi(m_pair.first, winrt::get_abi(values)); } template , int> = 0> vector_view(Collection const& values) noexcept { m_pair.first = values; } template vector_view(std::vector&& values) : m_pair(make>>(std::move(values)), nullptr) { } template vector_view(std::vector const& values) : m_pair(impl::make_scoped_input_vector_view(values.begin(), values.end())) { } vector_view(std::initializer_list values) : m_pair(impl::make_scoped_input_vector_view(values.begin(), values.end())) { } template , int> = 0> vector_view(std::initializer_list values) : m_pair(impl::make_scoped_input_vector_view(values.begin(), values.end())) { } template vector_view(InputIt first, InputIt last) : m_pair(impl::make_scoped_input_vector_view(first, last)) { } ~vector_view() noexcept { if (m_pair.second) { m_pair.second->invalidate_scope(); } if (!m_owned) { detach_abi(m_pair.first); } } operator interface_type const& () const noexcept { return m_pair.first; } private: std::pair m_pair; bool m_owned{ true }; }; template auto get_abi(vector_view const& object) noexcept { return *(void**)(&object); } template struct async_vector_view { using value_type = T; using interface_type = Windows::Foundation::Collections::IVectorView; async_vector_view(std::nullptr_t) noexcept { } async_vector_view(async_vector_view const& values) = delete; async_vector_view& operator=(async_vector_view const& values) = delete; async_vector_view(interface_type const& values) noexcept : m_owned(false) { attach_abi(m_interface, winrt::get_abi(values)); } template , int> = 0> async_vector_view(Collection const& values) noexcept { m_interface = values; } template async_vector_view(std::vector&& values) : m_interface(make>>(std::move(values))) { } async_vector_view(std::initializer_list values) : m_interface(make>>(values)) { } ~async_vector_view() noexcept { if (!m_owned) { detach_abi(m_interface); } } operator interface_type const& () const noexcept { return m_interface; } private: interface_type m_interface; bool m_owned{ true }; }; template auto get_abi(async_vector_view const& object) noexcept { return *(void**)(&object); } } namespace winrt::impl { template struct input_map_view : implements, non_agile, no_weak_ref, wfc::IMapView, wfc::IIterable>>, map_view_base, K, V> { static_assert(std::is_same_v>, "Must be constructed with rvalue."); explicit input_map_view(Container&& values) : m_values(std::forward(values)) { } auto& get_container() const noexcept { return m_values; } private: Container const m_values; }; template struct scoped_input_map_view : input_scope, implements, non_agile, no_weak_ref, wfc::IMapView, wfc::IIterable>>, map_view_base, K, V> { void abi_enter() const { check_scope(); } explicit scoped_input_map_view(Container const& values) : m_values(values) { } auto& get_container() const noexcept { return m_values; } #if defined(_DEBUG) && !defined(WINRT_NO_MAKE_DETECTION) void use_make_function_to_create_this_object() final { } #endif private: Container const& m_values; }; template auto make_input_map_view(Container&& values) { return make>(std::forward(values)); } template auto make_scoped_input_map_view(Container const& values) { using interface_type = wfc::IMapView; std::pair result; auto ptr = new scoped_input_map_view(values); *put_abi(result.first) = to_abi(ptr); result.second = ptr; return result; } } WINRT_EXPORT namespace winrt::param { template struct map_view { using value_type = Windows::Foundation::Collections::IKeyValuePair; using interface_type = Windows::Foundation::Collections::IMapView; map_view(std::nullptr_t) noexcept { } map_view(map_view const& values) = delete; map_view& operator=(map_view const& values) = delete; map_view(interface_type const& values) noexcept : m_owned(false) { attach_abi(m_pair.first, winrt::get_abi(values)); } template , int> = 0> map_view(Collection const& values) noexcept { m_pair.first = values; } template map_view(std::map&& values) : m_pair(impl::make_input_map_view(std::move(values)), nullptr) { } template map_view(std::map const& values) : m_pair(impl::make_scoped_input_map_view(values)) { } template map_view(std::unordered_map&& values) : m_pair(impl::make_input_map_view(std::move(values)), nullptr) { } template map_view(std::unordered_map const& values) : m_pair(impl::make_scoped_input_map_view(values)) { } map_view(std::initializer_list> values) : m_pair(impl::make_input_map_view(std::map(values)), nullptr) { } ~map_view() noexcept { if (m_pair.second) { m_pair.second->invalidate_scope(); } if (!m_owned) { detach_abi(m_pair.first); } } operator interface_type const& () const noexcept { return m_pair.first; } private: std::pair m_pair; bool m_owned{ true }; }; template auto get_abi(map_view const& object) noexcept { return *(void**)(&object); } template struct async_map_view { using value_type = Windows::Foundation::Collections::IKeyValuePair; using interface_type = Windows::Foundation::Collections::IMapView; async_map_view(std::nullptr_t) noexcept { } async_map_view(async_map_view const& values) = delete; async_map_view& operator=(async_map_view const& values) = delete; async_map_view(interface_type const& values) noexcept : m_owned(false) { attach_abi(m_interface, winrt::get_abi(values)); } template , int> = 0> async_map_view(Collection const& values) noexcept { m_interface = values; } template async_map_view(std::map&& values) : m_interface(impl::make_input_map_view(std::move(values))) { } template async_map_view(std::unordered_map&& values) : m_interface(impl::make_input_map_view(std::move(values))) { } async_map_view(std::initializer_list> values) : m_interface(impl::make_input_map_view(std::map(values))) { } ~async_map_view() noexcept { if (!m_owned) { detach_abi(m_interface); } } operator interface_type const& () const noexcept { return m_interface; } private: interface_type m_interface; bool m_owned{ true }; }; template auto get_abi(async_map_view const& object) noexcept { return *(void**)(&object); } } namespace winrt::impl { template struct vector_impl : implements, wfc::IVector, wfc::IVectorView, wfc::IIterable>, vector_base, T>, ThreadingBase { static_assert(std::is_same_v>, "Must be constructed with rvalue."); explicit vector_impl(Container&& values) : m_values(std::forward(values)) { } auto& get_container() noexcept { return m_values; } auto& get_container() const noexcept { return m_values; } using ThreadingBase::acquire_shared; using ThreadingBase::acquire_exclusive; private: Container m_values; }; template using input_vector = vector_impl; } WINRT_EXPORT namespace winrt::param { template struct vector { using value_type = T; using interface_type = Windows::Foundation::Collections::IVector; vector(std::nullptr_t) noexcept { } vector(vector const& values) = delete; vector& operator=(vector const& values) = delete; vector(interface_type const& values) noexcept : m_owned(false) { attach_abi(m_interface, winrt::get_abi(values)); } template , int> = 0> vector(Collection const& values) noexcept { m_interface = values; } template vector(std::vector&& values) : m_interface(make>>(std::move(values))) { } vector(std::initializer_list values) : m_interface(make>>(values)) { } ~vector() noexcept { if (!m_owned) { detach_abi(m_interface); } } operator interface_type const& () const noexcept { return m_interface; } private: interface_type m_interface; bool m_owned = true; }; template auto get_abi(vector const& object) noexcept { return *(void**)(&object); } } namespace winrt::impl { template struct map_impl : implements, wfc::IMap, wfc::IMapView, wfc::IIterable>>, map_base, K, V>, ThreadingBase { static_assert(std::is_same_v>, "Must be constructed with rvalue."); explicit map_impl(Container&& values) : m_values(std::forward(values)) { } auto& get_container() noexcept { return m_values; } auto& get_container() const noexcept { return m_values; } using ThreadingBase::acquire_shared; using ThreadingBase::acquire_exclusive; private: Container m_values; }; template using input_map = map_impl; template auto make_input_map(Container&& values) { return make>(std::forward(values)); } } WINRT_EXPORT namespace winrt::param { template struct map { using value_type = Windows::Foundation::Collections::IKeyValuePair; using interface_type = Windows::Foundation::Collections::IMap; map(std::nullptr_t) noexcept { } map(map const& values) = delete; map& operator=(map const& values) = delete; map(interface_type const& values) noexcept : m_owned(false) { attach_abi(m_interface, winrt::get_abi(values)); } template , int> = 0> map(Collection const& values) noexcept { m_interface = values; } template map(std::map&& values) : m_interface(impl::make_input_map(std::move(values))) { } template map(std::unordered_map&& values) : m_interface(impl::make_input_map(std::move(values))) { } map(std::initializer_list> values) : m_interface(impl::make_input_map(std::map(values))) { } ~map() noexcept { if (!m_owned) { detach_abi(m_interface); } } operator interface_type const& () const noexcept { return m_interface; } private: interface_type m_interface; bool m_owned{ true }; }; template auto get_abi(map const& object) noexcept { return *(void**)(&object); } } namespace winrt::impl { template using multi_threaded_vector = vector_impl; template struct inspectable_observable_vector : observable_vector_base, Windows::Foundation::IInspectable>, implements, wfc::IObservableVector, wfc::IVector, wfc::IVectorView, wfc::IIterable>, ThreadingBase { static_assert(std::is_same_v>, "Must be constructed with rvalue."); explicit inspectable_observable_vector(Container&& values) : m_values(std::forward(values)) { } auto& get_container() noexcept { return m_values; } auto& get_container() const noexcept { return m_values; } using ThreadingBase::acquire_shared; using ThreadingBase::acquire_exclusive; private: Container m_values; }; template using multi_threaded_inspectable_observable_vector = inspectable_observable_vector; template struct convertible_observable_vector : observable_vector_base, T>, implements, wfc::IObservableVector, wfc::IVector, wfc::IVectorView, wfc::IIterable, wfc::IObservableVector, wfc::IVector, wfc::IVectorView, wfc::IIterable>, ThreadingBase { static_assert(!std::is_same_v); static_assert(std::is_same_v>, "Must be constructed with rvalue."); using container_type = convertible_observable_vector; using base_type = observable_vector_base, T>; explicit convertible_observable_vector(Container&& values) : m_values(std::forward(values)) { } auto& get_container() noexcept { return m_values; } auto& get_container() const noexcept { return m_values; } using ThreadingBase::acquire_shared; using ThreadingBase::acquire_exclusive; auto First() { struct result { container_type* container; operator wfc::IIterator() { return static_cast(container)->First(); } operator wfc::IIterator() { auto guard = container->acquire_shared(); return make(container); } }; return result{ this }; } auto GetAt(uint32_t const index) const { struct result { base_type const* container; uint32_t const index; operator T() const { return container->GetAt(index); } operator Windows::Foundation::IInspectable() const { return box_value(container->GetAt(index)); } }; return result{ this, index }; } using base_type::IndexOf; bool IndexOf(Windows::Foundation::IInspectable const& value, uint32_t& index) const { if constexpr (is_com_interface_v) { if (!value) { return base_type::IndexOf(nullptr, index); } else if (auto as = value.try_as()) { return base_type::IndexOf(as, index); } } else { if (auto as = value.try_as()) { return base_type::IndexOf(as.value(), index); } } return false; } using base_type::GetMany; uint32_t GetMany(uint32_t const startIndex, array_view values) const { auto guard = this->acquire_shared(); if (startIndex >= m_values.size()) { return 0; } uint32_t const actual = (std::min)(static_cast(m_values.size() - startIndex), values.size()); std::transform(m_values.begin() + startIndex, m_values.begin() + startIndex + actual, values.begin(), [&](auto && value) { return box_value(value); }); return actual; } auto GetView() const noexcept { struct result { container_type const* container; operator wfc::IVectorView() const { return *container; } operator wfc::IVectorView() const { return *container; } }; return result{ this }; } using base_type::SetAt; void SetAt(uint32_t const index, Windows::Foundation::IInspectable const& value) { SetAt(index, unbox_value(value)); } using base_type::InsertAt; void InsertAt(uint32_t const index, Windows::Foundation::IInspectable const& value) { InsertAt(index, unbox_value(value)); } using base_type::Append; void Append(Windows::Foundation::IInspectable const& value) { Append(unbox_value(value)); } using base_type::ReplaceAll; void ReplaceAll(array_view values) { Container new_values; new_values.reserve(values.size()); std::transform(values.begin(), values.end(), std::back_inserter(new_values), [&](auto && value) { return unbox_value(value); }); base_type::ReplaceAll(std::move(new_values)); } using base_type::VectorChanged; event_token VectorChanged(wfc::VectorChangedEventHandler const& handler) { return base_type::VectorChanged([handler](auto && sender, auto && args) { handler(sender.template try_as>(), args); }); } private: struct iterator : impl::collection_version::iterator_type, implements> { explicit iterator(container_type* const container) noexcept : impl::collection_version::iterator_type(*container), m_current(container->get_container().begin()), m_end(container->get_container().end()) { m_owner.copy_from(container); } Windows::Foundation::IInspectable Current() const { auto guard = m_owner->acquire_shared(); check_version(*m_owner); if (m_current == m_end) { throw hresult_out_of_bounds(); } return box_value(*m_current); } bool HasCurrent() const { auto guard = m_owner->acquire_shared(); check_version(*m_owner); return m_current != m_end; } bool MoveNext() { auto guard = m_owner->acquire_exclusive(); check_version(*m_owner); if (m_current != m_end) { ++m_current; } return m_current != m_end; } uint32_t GetMany(array_view values) { auto guard = m_owner->acquire_exclusive(); check_version(*m_owner); uint32_t const actual = (std::min)(static_cast(std::distance(m_current, m_end)), values.size()); std::transform(m_current, m_current + actual, values.begin(), [&](auto && value) { return box_value(value); }); std::advance(m_current, actual); return actual; } private: com_ptr m_owner; decltype(m_owner->get_container().begin()) m_current; decltype(m_owner->get_container().end()) const m_end; }; Container m_values; }; template using multi_threaded_convertible_observable_vector = convertible_observable_vector; } WINRT_EXPORT namespace winrt { template > Windows::Foundation::Collections::IVector single_threaded_vector(std::vector&& values = {}) { return make>>(std::move(values)); } template > Windows::Foundation::Collections::IVector multi_threaded_vector(std::vector&& values = {}) { return make>>(std::move(values)); } template > Windows::Foundation::Collections::IObservableVector single_threaded_observable_vector(std::vector&& values = {}) { if constexpr (std::is_same_v) { return make>>(std::move(values)); } else { return make>>(std::move(values)); } } template > Windows::Foundation::Collections::IObservableVector multi_threaded_observable_vector(std::vector&& values = {}) { if constexpr (std::is_same_v) { return make>>(std::move(values)); } else { return make>>(std::move(values)); } } } namespace winrt::impl { template using multi_threaded_map = map_impl; template struct observable_map_impl : implements, wfc::IObservableMap, wfc::IMap, wfc::IMapView, wfc::IIterable>>, observable_map_base, K, V>, ThreadingBase { static_assert(std::is_same_v>, "Must be constructed with rvalue."); explicit observable_map_impl(Container&& values) : m_values(std::forward(values)) { } auto& get_container() noexcept { return m_values; } auto& get_container() const noexcept { return m_values; } using ThreadingBase::acquire_shared; using ThreadingBase::acquire_exclusive; private: Container m_values; }; template using observable_map = observable_map_impl; template using multi_threaded_observable_map = observable_map_impl; } WINRT_EXPORT namespace winrt { template , typename Allocator = std::allocator>> Windows::Foundation::Collections::IMap single_threaded_map() { return make>>(std::map{}); } template , typename Allocator = std::allocator>> Windows::Foundation::Collections::IMap single_threaded_map(std::map&& values) { return make>>(std::move(values)); } template , typename KeyEqual = std::equal_to, typename Allocator = std::allocator>> Windows::Foundation::Collections::IMap single_threaded_map(std::unordered_map&& values) { return make>>(std::move(values)); } template , typename Allocator = std::allocator>> Windows::Foundation::Collections::IMap multi_threaded_map() { return make>>(std::map{}); } template , typename Allocator = std::allocator>> Windows::Foundation::Collections::IMap multi_threaded_map(std::map&& values) { return make>>(std::move(values)); } template , typename KeyEqual = std::equal_to, typename Allocator = std::allocator>> Windows::Foundation::Collections::IMap multi_threaded_map(std::unordered_map&& values) { return make>>(std::move(values)); } template , typename Allocator = std::allocator>> Windows::Foundation::Collections::IObservableMap single_threaded_observable_map() { return make>>(std::map{}); } template , typename Allocator = std::allocator>> Windows::Foundation::Collections::IObservableMap single_threaded_observable_map(std::map&& values) { return make>>(std::move(values)); } template , typename KeyEqual = std::equal_to, typename Allocator = std::allocator>> Windows::Foundation::Collections::IObservableMap single_threaded_observable_map(std::unordered_map&& values) { return make>>(std::move(values)); } template , typename Allocator = std::allocator>> Windows::Foundation::Collections::IObservableMap multi_threaded_observable_map() { return make>>(std::map{}); } template , typename Allocator = std::allocator>> Windows::Foundation::Collections::IObservableMap multi_threaded_observable_map(std::map&& values) { return make>>(std::move(values)); } template , typename KeyEqual = std::equal_to, typename Allocator = std::allocator>> Windows::Foundation::Collections::IObservableMap multi_threaded_observable_map(std::unordered_map&& values) { return make>>(std::move(values)); } } namespace std { template struct tuple_size> : integral_constant { }; template struct tuple_element> { static_assert(Idx < 2, "key-value pair index out of bounds"); using type = conditional_t; }; } namespace winrt::Windows::Foundation::Collections { template std::tuple_element_t> get(IKeyValuePair const& kvp) { static_assert(Idx < 2, "key-value pair index out of bounds"); if constexpr (Idx == 0) { return kvp.Key(); } else { return kvp.Value(); } } } #endif