coroutine.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #pragma once
  2. namespace std { namespace experimental { inline namespace coroutines_v1 {
  3. template <typename R, typename...> struct coroutine_traits {
  4. using promise_type = typename R::promise_type;
  5. };
  6. template <typename Promise = void> struct coroutine_handle;
  7. template <> struct coroutine_handle<void> {
  8. static coroutine_handle from_address(void *addr) noexcept {
  9. coroutine_handle me;
  10. me.ptr = addr;
  11. return me;
  12. }
  13. void operator()() { resume(); }
  14. void *address() const { return ptr; }
  15. void resume() const { __builtin_coro_resume(ptr); }
  16. void destroy() const { __builtin_coro_destroy(ptr); }
  17. bool done() const { return __builtin_coro_done(ptr); }
  18. coroutine_handle &operator=(decltype(nullptr)) {
  19. ptr = nullptr;
  20. return *this;
  21. }
  22. coroutine_handle(decltype(nullptr)) : ptr(nullptr) {}
  23. coroutine_handle() : ptr(nullptr) {}
  24. // void reset() { ptr = nullptr; } // add to P0057?
  25. explicit operator bool() const { return ptr; }
  26. protected:
  27. void *ptr;
  28. };
  29. template <typename Promise> struct coroutine_handle : coroutine_handle<> {
  30. using coroutine_handle<>::operator=;
  31. static coroutine_handle from_address(void *addr) noexcept {
  32. coroutine_handle me;
  33. me.ptr = addr;
  34. return me;
  35. }
  36. Promise &promise() const {
  37. return *reinterpret_cast<Promise *>(
  38. __builtin_coro_promise(ptr, alignof(Promise), false));
  39. }
  40. static coroutine_handle from_promise(Promise &promise) {
  41. coroutine_handle p;
  42. p.ptr = __builtin_coro_promise(&promise, alignof(Promise), true);
  43. return p;
  44. }
  45. };
  46. template <typename _PromiseT>
  47. bool operator==(coroutine_handle<_PromiseT> const& _Left,
  48. coroutine_handle<_PromiseT> const& _Right) noexcept
  49. {
  50. return _Left.address() == _Right.address();
  51. }
  52. template <typename _PromiseT>
  53. bool operator!=(coroutine_handle<_PromiseT> const& _Left,
  54. coroutine_handle<_PromiseT> const& _Right) noexcept
  55. {
  56. return !(_Left == _Right);
  57. }
  58. struct suspend_always {
  59. bool await_ready() { return false; }
  60. void await_suspend(coroutine_handle<>) {}
  61. void await_resume() {}
  62. };
  63. struct suspend_never {
  64. bool await_ready() { return true; }
  65. void await_suspend(coroutine_handle<>) {}
  66. void await_resume() {}
  67. };
  68. }}}