105 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify -std=c++20 -I%S/Inputs -Wno-unused -Wno-uninitialized -Wunsequenced %s2 3// expected-no-diagnostics4 5#include "std-coroutine.h"6 7typedef __PTRDIFF_TYPE__ ptrdiff_t;8 9using namespace std;10 11template<class T>12struct Task {13 struct promise_type {14 Task<T> get_return_object() noexcept;15 suspend_always initial_suspend() noexcept;16 suspend_always final_suspend() noexcept;17 void return_value(T);18 void unhandled_exception();19 auto yield_value(Task<T>) noexcept { return final_suspend(); }20 };21 bool await_ready() noexcept { return false; }22 void await_suspend(coroutine_handle<>) noexcept {}23 T await_resume();24};25 26template<>27struct Task<void> {28 struct promise_type {29 Task<void> get_return_object() noexcept;30 suspend_always initial_suspend() noexcept;31 suspend_always final_suspend() noexcept;32 void return_void() noexcept;33 void unhandled_exception() noexcept;34 auto yield_value(Task<void>) noexcept { return final_suspend(); }35 };36 bool await_ready() noexcept { return false; }37 void await_suspend(coroutine_handle<>) noexcept {}38 void await_resume() noexcept {}39};40 41template <typename T>42class generator43{44 struct Promise45 {46 auto get_return_object() { return generator{*this}; }47 auto initial_suspend() { return suspend_never{}; }48 auto final_suspend() noexcept { return suspend_always{}; }49 void unhandled_exception() {}50 void return_void() {}51 52 auto yield_value(T value)53 {54 value_ = std::move(value);55 return suspend_always{};56 }57 58 T value_;59 };60 61 using Handle = coroutine_handle<Promise>;62 63 struct sentinel{};64 struct iterator65 {66 using iterator_category = input_iterator_tag;67 using value_type = T;68 using difference_type = ptrdiff_t;69 using reference = T &;70 using const_reference = const T &;71 using pointer = T *;72 73 iterator &operator++()74 {75 h_.resume();76 return *this;77 }78 const_reference &operator*() const { return h_.promise().value_; }79 bool operator!=(sentinel) { return !h_.done(); }80 81 Handle h_;82 };83 84 explicit generator(Promise &p) : h_(Handle::from_promise(p)) {}85 Handle h_;86public:87 using promise_type = Promise;88 auto begin() { return iterator{h_}; }89 auto end() { return sentinel{}; }90};91 92Task<void> c(int i) {93 co_await (i = 0, std::suspend_always{});94}95 96generator<int> range(int start, int end)97{98 while (start < end)99 co_yield start++;100}101 102Task<int> go(int const& val);103Task<int> go1(int x) {104 co_return co_await go(++x);105}