Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions strings/base_coroutine_threadpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,15 @@ namespace winrt::impl
template <typename T>
class awaiter_finder
{
template <typename U, typename = decltype(std::declval<U>().await_ready())> static constexpr bool find_awaitable_member(int) { return true; }
template <typename> static constexpr bool find_awaitable_member(...) { return false; }

template <typename U, typename = decltype(std::declval<U>().operator co_await())> static constexpr bool find_co_await_member(int) { return true; }
template <typename> static constexpr bool find_co_await_member(...) { return false; }
template <typename> static constexpr bool find_co_await_free(...) { return false; }

#ifdef WINRT_IMPL_COROUTINES
template <typename U, typename = decltype(std::declval<U>().await_ready())> static constexpr bool find_awaitable_member(int) { return true; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one doesn't mention operator co_await and could stay in its original location, I think.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was just cleaner to group the trues and falses together.

template <typename U, typename = decltype(std::declval<U>().operator co_await())> static constexpr bool find_co_await_member(int) { return true; }
template <typename U, typename = decltype(operator co_await(std::declval<U>()))> static constexpr bool find_co_await_free(int) { return true; }
template <typename> static constexpr bool find_co_await_free(...) { return false; }
#endif

public:

Expand Down Expand Up @@ -202,6 +203,7 @@ namespace winrt::impl
template <typename T>
decltype(auto) get_awaiter(T&& value) noexcept
{
#ifdef WINRT_IMPL_COROUTINES
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need this #ifdef any more. has_co_await_member and has_co_await_free will always be false if WINRT_IMPL_COROUTINES is not defined, so we fall through to the last case, which requires the type to be its own awaiter (and if we move the find_awaitable_member outside the #ifdef it will work), it will look for an await_ready which is fine.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, Clang currently looks inside the if constexpr regardless and fails to compile.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yeah, forgot about that. Even though it's if constexpr'd out, it still has to compile.

if constexpr (awaiter_finder<T>::has_co_await_member)
{
static_assert(!awaiter_finder<T>::has_co_await_free, "Ambiguous operator co_await (as both member and free function).");
Expand All @@ -216,6 +218,9 @@ namespace winrt::impl
static_assert(awaiter_finder<T>::has_awaitable_member, "Not an awaitable type");
return static_cast<T&&>(value);
}
#else
return static_cast<T&&>(value);
#endif
}

template <typename T>
Expand Down
16 changes: 8 additions & 8 deletions strings/base_reference_produce.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,24 +274,24 @@ namespace winrt::impl
}
if constexpr (std::is_enum_v<T>)
{
if (auto temp = value.try_as<Windows::Foundation::IReference<T>>())
if (auto temp = value.template try_as<Windows::Foundation::IReference<T>>())
{
return temp.Value();
}
else
{
return static_cast<T>(value.as<Windows::Foundation::IReference<std::underlying_type_t<T>>>().Value());
return static_cast<T>(value.template as<Windows::Foundation::IReference<std::underlying_type_t<T>>>().Value());
}
}
#ifdef WINRT_IMPL_IUNKNOWN_DEFINED
else if constexpr (std::is_same_v<T, GUID>)
{
return value.as<Windows::Foundation::IReference<guid>>().Value();
return value.template as<Windows::Foundation::IReference<guid>>().Value();
}
#endif
else
{
return value.as<Windows::Foundation::IReference<T>>().Value();
return value.template as<Windows::Foundation::IReference<T>>().Value();
}
}

Expand All @@ -300,28 +300,28 @@ namespace winrt::impl
{
if constexpr (std::is_enum_v<T>)
{
if (auto temp = value.try_as<Windows::Foundation::IReference<T>>())
if (auto temp = value.template try_as<Windows::Foundation::IReference<T>>())
{
return temp.Value();
}

if (auto temp = value.try_as<Windows::Foundation::IReference<std::underlying_type_t<T>>>())
if (auto temp = value.template try_as<Windows::Foundation::IReference<std::underlying_type_t<T>>>())
{
return static_cast<T>(temp.Value());
}
}
#ifdef WINRT_IMPL_IUNKNOWN_DEFINED
else if constexpr (std::is_same_v<T, GUID>)
{
if (auto temp = value.try_as<Windows::Foundation::IReference<guid>>())
if (auto temp = value.template try_as<Windows::Foundation::IReference<guid>>())
{
return temp.Value();
}
}
#endif
else
{
if (auto temp = value.try_as<Windows::Foundation::IReference<T>>())
if (auto temp = value.template try_as<Windows::Foundation::IReference<T>>())
{
return temp.Value();
}
Expand Down