winrt_foundation_helpers.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_WIN_WINRT_FOUNDATION_HELPERS_H_
  5. #define BASE_WIN_WINRT_FOUNDATION_HELPERS_H_
  6. #include <windows.foundation.h>
  7. #include <wrl/client.h>
  8. #include <vector>
  9. #include "base/optional.h"
  10. #include "base/win/hstring_compare.h"
  11. // This file provides helpers for WinRT types.
  12. namespace base {
  13. namespace win {
  14. namespace internal {
  15. // Template tricks needed to dispatch to the correct implementation.
  16. //
  17. // For all types which are neither InterfaceGroups nor RuntimeClasses, the
  18. // following three typedefs are synonyms for a single C++ type. But for
  19. // InterfaceGroups and RuntimeClasses, they are different types:
  20. // LogicalT: The C++ Type for the InterfaceGroup or RuntimeClass, when
  21. // used as a template parameter. Eg "RCFoo*"
  22. // AbiT: The C++ type for the default interface used to represent the
  23. // InterfaceGroup or RuntimeClass when passed as a method parameter.
  24. // Eg "IFoo*"
  25. // ComplexT: An instantiation of the Internal "AggregateType" template that
  26. // combines LogicalT with AbiT. Eg "AggregateType<RCFoo*,IFoo*>".
  27. // ComplexT is tightly coupled to the interface being implemented,
  28. // hence defined in headers which include this file.
  29. // For instance base/win/async_operation.h or
  30. // base/win/collection_helpers.h
  31. //
  32. // windows.foundation.collections.h defines the following template and
  33. // semantics in Windows::Foundation::Internal:
  34. //
  35. // template <class LogicalType, class AbiType>
  36. // struct AggregateType;
  37. //
  38. // LogicalType - the Windows Runtime type (eg, runtime class, interface group,
  39. // etc) being provided as an argument to an _impl template, when
  40. // that type cannot be represented at the ABI.
  41. // AbiType - the type used for marshalling, ie "at the ABI", for the
  42. // logical type.
  43. template <typename TComplex>
  44. using AbiType =
  45. typename ABI::Windows::Foundation::Internal::GetAbiType<TComplex>::type;
  46. template <typename TComplex>
  47. using LogicalType =
  48. typename ABI::Windows::Foundation::Internal::GetLogicalType<TComplex>::type;
  49. // Compile time switch to decide what container to use for |TComplex|.
  50. // Depends on whether the underlying Abi type is a pointer to IUnknown or not.
  51. // It queries the internals of Windows::Foundation to obtain this information.
  52. template <typename TComplex>
  53. using StorageType = std::conditional_t<
  54. std::is_convertible<AbiType<TComplex>, IUnknown*>::value,
  55. Microsoft::WRL::ComPtr<std::remove_pointer_t<AbiType<TComplex>>>,
  56. AbiType<TComplex>>;
  57. // Similar to StorageType, but returns a base::Optional in case underlying Abi
  58. // type is not a pointer to IUnknown.
  59. template <typename TComplex>
  60. using OptionalStorageType = std::conditional_t<
  61. std::is_convertible<AbiType<TComplex>, IUnknown*>::value,
  62. Microsoft::WRL::ComPtr<std::remove_pointer_t<AbiType<TComplex>>>,
  63. base::Optional<AbiType<TComplex>>>;
  64. template <typename T>
  65. HRESULT CopyTo(const T& value, T* ptr) {
  66. *ptr = value;
  67. return S_OK;
  68. }
  69. template <typename T>
  70. HRESULT CopyTo(const Microsoft::WRL::ComPtr<T>& value, T** ptr) {
  71. return value.CopyTo(ptr);
  72. }
  73. template <typename T>
  74. HRESULT CopyTo(const base::Optional<T>& value, T* ptr) {
  75. *ptr = *value;
  76. return S_OK;
  77. }
  78. template <typename T>
  79. HRESULT CopyN(typename std::vector<T>::const_iterator first,
  80. unsigned count,
  81. T* result) {
  82. std::copy_n(first, count, result);
  83. return S_OK;
  84. }
  85. template <typename T>
  86. HRESULT CopyN(
  87. typename std::vector<Microsoft::WRL::ComPtr<T>>::const_iterator first,
  88. unsigned count,
  89. T** result) {
  90. for (unsigned i = 0; i < count; ++i)
  91. CopyTo(*first++, result++);
  92. return S_OK;
  93. }
  94. inline bool IsEqual(const HSTRING& lhs, const HSTRING& rhs) {
  95. INT32 result;
  96. HRESULT hr = HStringCompare(lhs, rhs, &result);
  97. DCHECK(SUCCEEDED(hr));
  98. return result == 0;
  99. }
  100. template <typename T>
  101. bool IsEqual(const T& lhs, const T& rhs) {
  102. return lhs == rhs;
  103. }
  104. template <typename T>
  105. bool IsEqual(const Microsoft::WRL::ComPtr<T>& com_ptr, const T* ptr) {
  106. return com_ptr.Get() == ptr;
  107. }
  108. struct Less {
  109. bool operator()(const HSTRING& lhs, const HSTRING& rhs) const {
  110. INT32 result;
  111. HRESULT hr = HStringCompare(lhs, rhs, &result);
  112. DCHECK(SUCCEEDED(hr));
  113. return result < 0;
  114. }
  115. template <typename T>
  116. bool operator()(const Microsoft::WRL::ComPtr<T>& com_ptr,
  117. const T* ptr) const {
  118. return com_ptr.Get() < ptr;
  119. }
  120. template <typename T>
  121. constexpr bool operator()(const T& lhs, const T& rhs) const {
  122. return lhs < rhs;
  123. }
  124. };
  125. } // namespace internal
  126. } // namespace win
  127. } // namespace base
  128. #endif // BASE_WIN_WINRT_FOUNDATION_HELPERS_H_