|
|
@ -186,6 +186,21 @@ class Poll<Pending>; |
|
|
|
template <class T> |
|
|
|
template <class T> |
|
|
|
class Poll<Poll<T>>; |
|
|
|
class Poll<Poll<T>>; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// PollTraits tells us whether a type is Poll<> or some other type, and is
|
|
|
|
|
|
|
|
// leveraged in the PromiseLike/PromiseFactory machinery to select the
|
|
|
|
|
|
|
|
// appropriate implementation of those concepts based upon the return type of a
|
|
|
|
|
|
|
|
// lambda, for example (via enable_if).
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
|
|
|
|
struct PollTraits { |
|
|
|
|
|
|
|
static constexpr bool is_poll() { return false; } |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
|
|
|
|
struct PollTraits<Poll<T>> { |
|
|
|
|
|
|
|
using Type = T; |
|
|
|
|
|
|
|
static constexpr bool is_poll() { return true; } |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
template <typename T> |
|
|
|
bool operator==(const Poll<T>& a, const Poll<T>& b) { |
|
|
|
bool operator==(const Poll<T>& a, const Poll<T>& b) { |
|
|
|
if (a.pending() && b.pending()) return true; |
|
|
|
if (a.pending() && b.pending()) return true; |
|
|
@ -193,27 +208,37 @@ bool operator==(const Poll<T>& a, const Poll<T>& b) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T, typename U, typename SfinaeVoid = void> |
|
|
|
|
|
|
|
struct PollCastImpl; |
|
|
|
|
|
|
|
|
|
|
|
template <typename T, typename U> |
|
|
|
template <typename T, typename U> |
|
|
|
Poll<T> poll_cast(Poll<U> poll) { |
|
|
|
struct PollCastImpl<T, Poll<U>> { |
|
|
|
|
|
|
|
static Poll<T> Cast(Poll<U>&& poll) { |
|
|
|
if (poll.pending()) return Pending{}; |
|
|
|
if (poll.pending()) return Pending{}; |
|
|
|
return static_cast<T>(std::move(poll.value())); |
|
|
|
return static_cast<T>(std::move(poll.value())); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T, typename U> |
|
|
|
|
|
|
|
struct PollCastImpl<T, U, std::enable_if<!PollTraits<U>::is_poll()>> { |
|
|
|
|
|
|
|
static Poll<T> Cast(U&& poll) { return Poll<T>(T(std::move(poll))); } |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// PollTraits tells us whether a type is Poll<> or some other type, and is
|
|
|
|
|
|
|
|
// leveraged in the PromiseLike/PromiseFactory machinery to select the
|
|
|
|
|
|
|
|
// appropriate implementation of those concepts based upon the return type of a
|
|
|
|
|
|
|
|
// lambda, for example (via enable_if).
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
template <typename T> |
|
|
|
struct PollTraits { |
|
|
|
struct PollCastImpl<T, T> { |
|
|
|
static constexpr bool is_poll() { return false; } |
|
|
|
static Poll<T> Cast(T&& poll) { return Poll<T>(std::move(poll)); } |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
template <typename T> |
|
|
|
struct PollTraits<Poll<T>> { |
|
|
|
struct PollCastImpl<T, Poll<T>> { |
|
|
|
using Type = T; |
|
|
|
static Poll<T> Cast(Poll<T>&& poll) { return std::move(poll); } |
|
|
|
static constexpr bool is_poll() { return true; } |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T, typename U> |
|
|
|
|
|
|
|
Poll<T> poll_cast(U poll) { |
|
|
|
|
|
|
|
return PollCastImpl<T, U>::Cast(std::move(poll)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Convert a poll to a string
|
|
|
|
// Convert a poll to a string
|
|
|
|
template <typename T, typename F> |
|
|
|
template <typename T, typename F> |
|
|
|
std::string PollToString( |
|
|
|
std::string PollToString( |
|
|
|