1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
#include <QObject>
#include <QTest>
#include "qcoro/coroutine.h"
#include "qcoro/qcorotask.h"
#include "qcoro/qcorolazytask.h"
namespace helper {
template<QCoro::Awaitable T>
struct is_awaitable {
static constexpr bool value = true;
};
template<QCoro::Awaitable T>
static constexpr bool is_awaitable_v = is_awaitable<T>::value;
} // namespace helper
struct TestAwaitable {
bool await_ready() const { return true; }
void await_suspend(std::coroutine_handle<>);
void await_resume() const;
};
struct TestAwaitableWithOperatorCoAwait {
TestAwaitable operator co_await() {
return TestAwaitable{};
}
};
namespace TestNS {
struct TestAwaitableWithNonmemberOperatorCoAwait {};
#if !defined(_MSC_VER) || defined(__clang__)
// This is how it's supposed to work: the operator must be defined in the same namespace
// as the argument type and is discovered via ADL.
auto operator co_await(TestAwaitableWithNonmemberOperatorCoAwait &&) {
return TestAwaitable{};
}
#endif
} // namespace TestNS
#if defined(_MSC_VER) && !defined(__clang__)
// Unfortunately, MSVC is only able to find the operator in global namespace :(
// This is most likely a bug in MSVC.
auto operator co_await(TestNS::TestAwaitableWithNonmemberOperatorCoAwait &&) {
return TestAwaitable{};
}
#endif
class TestConstraints : public QObject {
Q_OBJECT
private Q_SLOTS:
void testAwaitableConcept() {
static_assert(helper::is_awaitable_v<QCoro::Task<void>>,
"Awaitable concept doesn't accept Task<void>, although it should.");
static_assert(helper::is_awaitable_v<QCoro::Task<int>>,
"Awaitable concept doesn't accept Task<T>, although it should.");
static_assert(helper::is_awaitable_v<QCoro::LazyTask<void>>,
"Awaitable concept doesn't accept LazyTask<void>, although it should.");
static_assert(helper::is_awaitable_v<QCoro::LazyTask<void>>,
"Awaitable concept doesn't accept LazyTask<T>, although it should.");
static_assert(helper::is_awaitable_v<TestAwaitable>,
"Awaitable concept doesn't accept an awaitable with await member functions.");
static_assert(helper::is_awaitable_v<TestAwaitableWithOperatorCoAwait>,
"Awaitable concept doesn't accept an awaitable with member operator co_await.");
static_assert(helper::is_awaitable_v<TestNS::TestAwaitableWithNonmemberOperatorCoAwait>,
"Awaitable concept doesn't accept an awaitable with non-member operator co_await.");
}
};
QTEST_GUILESS_MAIN(TestConstraints)
#include "testconstraints.moc"
|