brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.6 KiB · 56d2edc Raw
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}