Skip to content

Commit

Permalink
Fix build with apple-clang
Browse files Browse the repository at this point in the history
libc++ doesn't implement any concepts yet, use variable templates
instead.
  • Loading branch information
danvratil committed May 2, 2022
1 parent afa8824 commit b4abc58
Showing 1 changed file with 5 additions and 5 deletions.
10 changes: 5 additions & 5 deletions qcoro/task.h
Expand Up @@ -554,27 +554,27 @@ class Task {
* returns an awaitable (Task<R>) then the result of then is the awaitable.
*/
template<typename ThenCallback>
requires (std::invocable<ThenCallback> || (!std::is_void_v<T> && std::invocable<ThenCallback, T>))
requires (std::is_invocable_v<ThenCallback> || (!std::is_void_v<T> && std::is_invocable_v<ThenCallback, T>))

This comment has been minimized.

Copy link
@adriaandegroot

adriaandegroot May 5, 2022

There's concepts_p.h in qcoro which does something similar, but for constructible_from. It's at least partly wrong, conflating "Clang" with Apple's released versions of libc++ (and Clang's own versions thereof). For instance, this version of Clang + libc++ will build qcoro without the patch:

FreeBSD clang version 13.0.0 (git@github.com:llvm/llvm-project.git llvmorg-13.0.0-0-gd7b669b3a303)

It can also #if 0 out the Clang part of concepts_p.h without any problem. So the code is much more sensitive to variations in the standard library. Apparently FreeBSD 13.0 needs this patch as well, and FreeBSD 12.3 still has Clang 10 by default. Anyway, flat-out Clang-no-concepts isn't right, even if the code isn't wrong like this.

This comment has been minimized.

Copy link
@danvratil

danvratil May 17, 2022

Author Owner

Right, thanks for the explanation (and sorry for the delay in response, haven't noticed the notification).

You are right that the issue is tight to libc++ rather than clang itself. Right now I'm targeting primarily gnu's libstdc++, libc++ is supported mostly for apple. I'll come back to reviewing the #ifdefs in the future :)

auto then(ThenCallback &&callback) {
return thenImpl(std::forward<ThenCallback>(callback));
}

template<typename ThenCallback, typename ErrorCallback>
requires ((std::invocable<ThenCallback> || (!std::is_void_v<T> && std::invocable<ThenCallback, T>)) &&
std::invocable<ErrorCallback, const std::exception &>)
requires ((std::is_invocable_v<ThenCallback> || (!std::is_void_v<T> && std::is_invocable_v<ThenCallback, T>)) &&
std::is_invocable_v<ErrorCallback, const std::exception &>)
auto then(ThenCallback &&callback, ErrorCallback &&errorCallback) {
return thenImpl(std::forward<ThenCallback>(callback), std::forward<ErrorCallback>(errorCallback));
}

private:
template<typename ThenCallback, typename ... Args>
requires (std::invocable<ThenCallback>)
requires (std::is_invocable_v<ThenCallback>)
auto invoke(ThenCallback &&callback, Args && ...) {
return callback();
}

template<typename ThenCallback, typename Arg>
requires (std::invocable<ThenCallback, Arg>)
requires (std::is_invocable_v<ThenCallback, Arg>)
auto invoke(ThenCallback &&callback, Arg && arg) {
return callback(std::forward<Arg>(arg));
}
Expand Down

0 comments on commit b4abc58

Please sign in to comment.