| 12
 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
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 
 | // -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_EXPERIMENTAL_COROUTINE
#define _LIBCPP_EXPERIMENTAL_COROUTINE
/**
    experimental/coroutine synopsis
// C++next
namespace std {
namespace experimental {
inline namespace coroutines_v1 {
  // 18.11.1 coroutine traits
template <typename R, typename... ArgTypes>
class coroutine_traits;
// 18.11.2 coroutine handle
template <typename Promise = void>
class coroutine_handle;
// 18.11.2.7 comparison operators:
bool operator==(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
bool operator!=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
bool operator<(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
bool operator<=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
bool operator>=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
bool operator>(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT;
// 18.11.3 trivial awaitables
struct suspend_never;
struct suspend_always;
// 18.11.2.8 hash support:
template <class T> struct hash;
template <class P> struct hash<coroutine_handle<P>>;
} // namespace coroutines_v1
} // namespace experimental
} // namespace std
 */
#include <__assert> // all public C++ headers provide the assertion handler
#include <__functional/hash.h>
#include <__functional/operations.h>
#include <cstddef>
#include <experimental/__config>
#include <new>
#include <type_traits>
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
#  include <atomic>
#  include <climits>
#  include <cmath>
#  include <compare>
#  include <concepts>
#  include <ctime>
#  include <initializer_list>
#  include <iosfwd>
#  include <iterator>
#  include <memory>
#  include <ratio>
#  include <stdexcept>
#  include <tuple>
#  include <typeinfo>
#  include <utility>
#  include <variant>
#endif
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif
#ifndef _LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_COROUTINES
template <class _Tp, class = void>
struct __coroutine_traits_sfinae {};
template <class _Tp>
struct __coroutine_traits_sfinae<_Tp, __void_t<typename _Tp::promise_type> >
{
  using promise_type = typename _Tp::promise_type;
};
template <typename _Ret, typename... _Args>
struct coroutine_traits
    : public __coroutine_traits_sfinae<_Ret>
{
};
template <typename _Promise = void>
class _LIBCPP_TEMPLATE_VIS coroutine_handle;
template <>
class _LIBCPP_TEMPLATE_VIS coroutine_handle<void> {
public:
    _LIBCPP_INLINE_VISIBILITY
    _LIBCPP_CONSTEXPR coroutine_handle() _NOEXCEPT : __handle_(nullptr) {}
    _LIBCPP_INLINE_VISIBILITY
    _LIBCPP_CONSTEXPR coroutine_handle(nullptr_t) _NOEXCEPT : __handle_(nullptr) {}
    _LIBCPP_INLINE_VISIBILITY
    coroutine_handle& operator=(nullptr_t) _NOEXCEPT {
        __handle_ = nullptr;
        return *this;
    }
    _LIBCPP_INLINE_VISIBILITY
    _LIBCPP_CONSTEXPR void* address() const _NOEXCEPT { return __handle_; }
    _LIBCPP_INLINE_VISIBILITY
    _LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return __handle_; }
    _LIBCPP_INLINE_VISIBILITY
    void operator()() { resume(); }
    _LIBCPP_INLINE_VISIBILITY
    void resume() {
      _LIBCPP_ASSERT(__is_suspended(),
                     "resume() can only be called on suspended coroutines");
      _LIBCPP_ASSERT(!done(),
                "resume() has undefined behavior when the coroutine is done");
      __builtin_coro_resume(__handle_);
    }
    _LIBCPP_INLINE_VISIBILITY
    void destroy() {
      _LIBCPP_ASSERT(__is_suspended(),
                     "destroy() can only be called on suspended coroutines");
      __builtin_coro_destroy(__handle_);
    }
    _LIBCPP_INLINE_VISIBILITY
    bool done() const {
      _LIBCPP_ASSERT(__is_suspended(),
                     "done() can only be called on suspended coroutines");
      return __builtin_coro_done(__handle_);
    }
public:
    _LIBCPP_INLINE_VISIBILITY
    static coroutine_handle from_address(void* __addr) _NOEXCEPT {
        coroutine_handle __tmp;
        __tmp.__handle_ = __addr;
        return __tmp;
    }
    // FIXME: Should from_address(nullptr) be allowed?
    _LIBCPP_INLINE_VISIBILITY
    static coroutine_handle from_address(nullptr_t) _NOEXCEPT {
      return coroutine_handle(nullptr);
    }
    template <class _Tp, bool _CallIsValid = false>
    static coroutine_handle from_address(_Tp*) {
      static_assert(_CallIsValid,
       "coroutine_handle<void>::from_address cannot be called with "
        "non-void pointers");
    }
private:
  bool __is_suspended() const _NOEXCEPT  {
    // FIXME actually implement a check for if the coro is suspended.
    return __handle_;
  }
  template <class _PromiseT> friend class coroutine_handle;
  void* __handle_;
};
// 18.11.2.7 comparison operators:
inline _LIBCPP_INLINE_VISIBILITY
bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
    return __x.address() == __y.address();
}
inline _LIBCPP_INLINE_VISIBILITY
bool operator!=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
    return !(__x == __y);
}
inline _LIBCPP_INLINE_VISIBILITY
bool operator<(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
    return less<void*>()(__x.address(), __y.address());
}
inline _LIBCPP_INLINE_VISIBILITY
bool operator>(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
    return __y < __x;
}
inline _LIBCPP_INLINE_VISIBILITY
bool operator<=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
    return !(__x > __y);
}
inline _LIBCPP_INLINE_VISIBILITY
bool operator>=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT {
    return !(__x < __y);
}
template <typename _Promise>
class _LIBCPP_TEMPLATE_VIS coroutine_handle : public coroutine_handle<> {
    using _Base = coroutine_handle<>;
public:
#ifndef _LIBCPP_CXX03_LANG
    // 18.11.2.1 construct/reset
    using coroutine_handle<>::coroutine_handle;
#else
    _LIBCPP_INLINE_VISIBILITY coroutine_handle() _NOEXCEPT : _Base() {}
    _LIBCPP_INLINE_VISIBILITY coroutine_handle(nullptr_t) _NOEXCEPT : _Base(nullptr) {}
#endif
    _LIBCPP_INLINE_VISIBILITY
    coroutine_handle& operator=(nullptr_t) _NOEXCEPT {
        _Base::operator=(nullptr);
        return *this;
    }
    _LIBCPP_INLINE_VISIBILITY
    _Promise& promise() const {
        return *static_cast<_Promise*>(
            __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false));
    }
public:
    _LIBCPP_INLINE_VISIBILITY
    static coroutine_handle from_address(void* __addr) _NOEXCEPT {
        coroutine_handle __tmp;
        __tmp.__handle_ = __addr;
        return __tmp;
    }
    // NOTE: this overload isn't required by the standard but is needed so
    // the deleted _Promise* overload doesn't make from_address(nullptr)
    // ambiguous.
    // FIXME: should from_address work with nullptr?
    _LIBCPP_INLINE_VISIBILITY
    static coroutine_handle from_address(nullptr_t) _NOEXCEPT {
      return coroutine_handle(nullptr);
    }
    template <class _Tp, bool _CallIsValid = false>
    static coroutine_handle from_address(_Tp*) {
      static_assert(_CallIsValid,
       "coroutine_handle<promise_type>::from_address cannot be called with "
        "non-void pointers");
    }
    template <bool _CallIsValid = false>
    static coroutine_handle from_address(_Promise*) {
      static_assert(_CallIsValid,
       "coroutine_handle<promise_type>::from_address cannot be used with "
        "pointers to the coroutine's promise type; use 'from_promise' instead");
    }
    _LIBCPP_INLINE_VISIBILITY
    static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT {
        typedef __remove_cv_t<_Promise> _RawPromise;
        coroutine_handle __tmp;
        __tmp.__handle_ = __builtin_coro_promise(
            _VSTD::addressof(const_cast<_RawPromise&>(__promise)),
             _LIBCPP_ALIGNOF(_Promise), true);
        return __tmp;
    }
};
#if __has_builtin(__builtin_coro_noop)
struct noop_coroutine_promise {};
template <>
class _LIBCPP_TEMPLATE_VIS coroutine_handle<noop_coroutine_promise>
    : public coroutine_handle<> {
  using _Base = coroutine_handle<>;
  using _Promise = noop_coroutine_promise;
public:
  _LIBCPP_INLINE_VISIBILITY
  _Promise& promise() const {
    return *static_cast<_Promise*>(
      __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false));
  }
  _LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return true; }
  _LIBCPP_CONSTEXPR bool done() const _NOEXCEPT { return false; }
  _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()() const _NOEXCEPT {}
  _LIBCPP_CONSTEXPR_SINCE_CXX20 void resume() const _NOEXCEPT {}
  _LIBCPP_CONSTEXPR_SINCE_CXX20 void destroy() const _NOEXCEPT {}
private:
  _LIBCPP_INLINE_VISIBILITY
  friend coroutine_handle<noop_coroutine_promise> noop_coroutine() _NOEXCEPT;
  _LIBCPP_INLINE_VISIBILITY coroutine_handle() _NOEXCEPT {
    this->__handle_ = __builtin_coro_noop();
  }
};
using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
inline _LIBCPP_INLINE_VISIBILITY
noop_coroutine_handle noop_coroutine() _NOEXCEPT {
  return noop_coroutine_handle();
}
#endif // __has_builtin(__builtin_coro_noop)
struct suspend_never {
  _LIBCPP_INLINE_VISIBILITY
  bool await_ready() const _NOEXCEPT { return true; }
  _LIBCPP_INLINE_VISIBILITY
  void await_suspend(coroutine_handle<>) const _NOEXCEPT {}
  _LIBCPP_INLINE_VISIBILITY
  void await_resume() const _NOEXCEPT {}
};
struct suspend_always {
  _LIBCPP_INLINE_VISIBILITY
  bool await_ready() const _NOEXCEPT { return false; }
  _LIBCPP_INLINE_VISIBILITY
  void await_suspend(coroutine_handle<>) const _NOEXCEPT {}
  _LIBCPP_INLINE_VISIBILITY
  void await_resume() const _NOEXCEPT {}
};
_LIBCPP_END_NAMESPACE_EXPERIMENTAL_COROUTINES
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
struct hash<_VSTD_CORO::coroutine_handle<_Tp> > {
    using __arg_type = _VSTD_CORO::coroutine_handle<_Tp>;
    _LIBCPP_INLINE_VISIBILITY
    size_t operator()(__arg_type const& __v) const _NOEXCEPT
    {return hash<void*>()(__v.address());}
};
_LIBCPP_END_NAMESPACE_STD
#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES)
#endif /* _LIBCPP_EXPERIMENTAL_COROUTINE */
 |