File: testconstraints.cpp

package info (click to toggle)
qcoro 0.12.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,700 kB
  • sloc: cpp: 8,573; python: 32; xml: 26; makefile: 23; sh: 15
file content (78 lines) | stat: -rw-r--r-- 2,674 bytes parent folder | download | duplicates (2)
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"