File: warn-unsequenced-coro.cpp

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (105 lines) | stat: -rw-r--r-- 2,639 bytes parent folder | download | duplicates (10)
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify -std=c++20 -I%S/Inputs -Wno-unused -Wno-uninitialized -Wunsequenced %s

// expected-no-diagnostics

#include "std-coroutine.h"

typedef __PTRDIFF_TYPE__ ptrdiff_t;

using namespace std;

template<class T>
struct Task {
    struct promise_type {
        Task<T> get_return_object() noexcept;
        suspend_always initial_suspend() noexcept;
        suspend_always final_suspend() noexcept;
        void return_value(T);
        void unhandled_exception();
        auto yield_value(Task<T>) noexcept { return final_suspend(); }
    };
    bool await_ready() noexcept { return false; }
    void await_suspend(coroutine_handle<>) noexcept {}
    T await_resume();
};

template<>
struct Task<void> {
    struct promise_type {
        Task<void> get_return_object() noexcept;
        suspend_always initial_suspend() noexcept;
        suspend_always final_suspend() noexcept;
        void return_void() noexcept;
        void unhandled_exception() noexcept;
        auto yield_value(Task<void>) noexcept { return final_suspend(); }
    };
    bool await_ready() noexcept { return false; }
    void await_suspend(coroutine_handle<>) noexcept {}
    void await_resume() noexcept {}
};

template <typename T>
class generator
{
  struct Promise
  {
    auto get_return_object() { return generator{*this}; }
    auto initial_suspend() { return suspend_never{}; }
    auto final_suspend() noexcept { return suspend_always{}; }
    void unhandled_exception() {}
    void return_void() {}

    auto yield_value(T value)
    {
      value_ = std::move(value);
      return suspend_always{};
    }

    T value_;
  };

  using Handle = coroutine_handle<Promise>;

  struct sentinel{};
  struct iterator
  {
    using iterator_category = input_iterator_tag;
    using value_type = T;
    using difference_type = ptrdiff_t;
    using reference = T &;
    using const_reference = const T &;
    using pointer = T *;

    iterator &operator++()
    {
      h_.resume();
      return *this;
    }
    const_reference &operator*() const { return h_.promise().value_; }
    bool operator!=(sentinel) { return !h_.done(); }

    Handle h_;
  };

  explicit generator(Promise &p) : h_(Handle::from_promise(p)) {}
  Handle h_;
public:
  using promise_type = Promise;
  auto begin() { return iterator{h_}; }
  auto end() { return sentinel{}; }
};

Task<void> c(int i) {
  co_await (i = 0, std::suspend_always{});
}

generator<int> range(int start, int end)
{
  while (start < end)
    co_yield start++;
}

Task<int> go(int const& val);
Task<int> go1(int x) {
  co_return co_await go(++x);
}