Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/coroutine
1 // <coroutine> -*- C++ -*- 2 3 // Copyright (C) 2019-2025 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file include/coroutine 26 * This is a Standard C++ Library header. 27 */ 28 29 #ifndef _GLIBCXX_COROUTINE 30 #define _GLIBCXX_COROUTINE 1 31 32 #ifdef _GLIBCXX_SYSHDR 33 #pragma GCC system_header 34 #endif 35 36 #pragma GCC diagnostic push 37 #pragma GCC diagnostic ignored "-Wc++17-extensions" 38 39 #define __glibcxx_want_coroutine 40 #include <bits/version.h> 41 42 #if !__cpp_impl_coroutine 43 # error "the <coroutine> header requires -fcoroutines" 44 #endif 45 46 #ifdef __cpp_lib_coroutine // C++ >= 14 && impl_coroutine 47 48 #include <type_traits> 49 #if __cplusplus > 201703L 50 # include <compare> 51 #endif 52 53 #if !defined __cpp_lib_three_way_comparison 54 # include <bits/stl_function.h> // for std::less 55 #endif 56 57 /** 58 * @defgroup coroutines Coroutines 59 * 60 * Components for supporting coroutine implementations. 61 * 62 * @since C++20 (and since C++14 as a libstdc++ extension) 63 */ 64 65 namespace std _GLIBCXX_VISIBILITY (default) 66 { 67 _GLIBCXX_BEGIN_NAMESPACE_VERSION 68 69 inline namespace __n4861 { 70 71 // C++20 17.12.2 coroutine traits 72 /// [coroutine.traits] 73 /// [coroutine.traits.primary] 74 /// If _Result::promise_type is valid and denotes a type then the traits 75 /// have a single publicly accessible member, otherwise they are empty. 76 template <typename _Result, typename... _ArgTypes> 77 struct coroutine_traits; 78 79 template <typename _Result, typename = void> 80 struct __coroutine_traits_impl {}; 81 82 template <typename _Result> 83 #if __cpp_concepts 84 requires requires { typename _Result::promise_type; } 85 struct __coroutine_traits_impl<_Result, void> 86 #else 87 struct __coroutine_traits_impl<_Result, 88 __void_t<typename _Result::promise_type>> 89 #endif 90 { 91 using promise_type = typename _Result::promise_type; 92 }; 93 94 template <typename _Result, typename... _ArgTypes> 95 struct coroutine_traits : __coroutine_traits_impl<_Result> {}; 96 97 // C++20 17.12.3 Class template coroutine_handle 98 /// [coroutine.handle] 99 template <typename _Promise = void> 100 struct coroutine_handle; 101 102 template <> struct 103 coroutine_handle<void> 104 { 105 public: 106 // [coroutine.handle.con], construct/reset 107 constexpr coroutine_handle() noexcept : _M_fr_ptr(nullptr) {} 108 109 constexpr coroutine_handle(std::nullptr_t __h) noexcept 110 : _M_fr_ptr(__h) 111 {} 112 113 coroutine_handle& operator=(std::nullptr_t) noexcept 114 { 115 _M_fr_ptr = nullptr; 116 return *this; 117 } 118 119 public: 120 // [coroutine.handle.export.import], export/import 121 constexpr void* address() const noexcept { return _M_fr_ptr; } 122 123 constexpr static coroutine_handle from_address(void* __a) noexcept 124 { 125 coroutine_handle __self; 126 __self._M_fr_ptr = __a; 127 return __self; 128 } 129 130 public: 131 // [coroutine.handle.observers], observers 132 constexpr explicit operator bool() const noexcept 133 { 134 return bool(_M_fr_ptr); 135 } 136 137 bool done() const noexcept { return __builtin_coro_done(_M_fr_ptr); } 138 139 // [coroutine.handle.resumption], resumption 140 void operator()() const { resume(); } 141 142 void resume() const { __builtin_coro_resume(_M_fr_ptr); } 143 144 void destroy() const { __builtin_coro_destroy(_M_fr_ptr); } 145 146 protected: 147 void* _M_fr_ptr; 148 }; 149 150 // [coroutine.handle.compare], comparison operators 151 152 constexpr bool 153 operator==(coroutine_handle<> __a, coroutine_handle<> __b) noexcept 154 { 155 return __a.address() == __b.address(); 156 } 157 158 #ifdef __cpp_lib_three_way_comparison 159 constexpr strong_ordering 160 operator<=>(coroutine_handle<> __a, coroutine_handle<> __b) noexcept 161 { 162 return std::compare_three_way()(__a.address(), __b.address()); 163 } 164 #else 165 // These are to enable operation with std=c++14,17. 166 constexpr bool 167 operator!=(coroutine_handle<> __a, coroutine_handle<> __b) noexcept 168 { 169 return !(__a == __b); 170 } 171 172 constexpr bool 173 operator<(coroutine_handle<> __a, coroutine_handle<> __b) noexcept 174 { 175 return less<void*>()(__a.address(), __b.address()); 176 } 177 178 constexpr bool 179 operator>(coroutine_handle<> __a, coroutine_handle<> __b) noexcept 180 { 181 return __b < __a; 182 } 183 184 constexpr bool 185 operator<=(coroutine_handle<> __a, coroutine_handle<> __b) noexcept 186 { 187 return !(__a > __b); 188 } 189 190 constexpr bool 191 operator>=(coroutine_handle<> __a, coroutine_handle<> __b) noexcept 192 { 193 return !(__a < __b); 194 } 195 #endif 196 197 template <typename _Promise> 198 struct coroutine_handle 199 { 200 // [coroutine.handle.con], construct/reset 201 202 constexpr coroutine_handle() noexcept { } 203 204 constexpr coroutine_handle(nullptr_t) noexcept { } 205 206 static coroutine_handle 207 from_promise(_Promise& __p) 208 { 209 coroutine_handle __self; 210 __self._M_fr_ptr 211 = __builtin_coro_promise((char*) &__p, __alignof(_Promise), true); 212 return __self; 213 } 214 215 coroutine_handle& operator=(nullptr_t) noexcept 216 { 217 _M_fr_ptr = nullptr; 218 return *this; 219 } 220 221 // [coroutine.handle.export.import], export/import 222 223 constexpr void* address() const noexcept { return _M_fr_ptr; } 224 225 constexpr static coroutine_handle from_address(void* __a) noexcept 226 { 227 coroutine_handle __self; 228 __self._M_fr_ptr = __a; 229 return __self; 230 } 231 232 // [coroutine.handle.conv], conversion 233 constexpr operator coroutine_handle<>() const noexcept 234 { return coroutine_handle<>::from_address(address()); } 235 236 // [coroutine.handle.observers], observers 237 constexpr explicit operator bool() const noexcept 238 { 239 return bool(_M_fr_ptr); 240 } 241 242 bool done() const noexcept { return __builtin_coro_done(_M_fr_ptr); } 243 244 // [coroutine.handle.resumption], resumption 245 void operator()() const { resume(); } 246 247 void resume() const { __builtin_coro_resume(_M_fr_ptr); } 248 249 void destroy() const { __builtin_coro_destroy(_M_fr_ptr); } 250 251 // [coroutine.handle.promise], promise access 252 _Promise& promise() const 253 { 254 void* __t 255 = __builtin_coro_promise (_M_fr_ptr, __alignof(_Promise), false); 256 return *static_cast<_Promise*>(__t); 257 } 258 259 private: 260 void* _M_fr_ptr = nullptr; 261 }; 262 263 /// [coroutine.noop] 264 struct noop_coroutine_promise 265 { 266 }; 267 268 // 17.12.4.1 Class noop_coroutine_promise 269 /// [coroutine.promise.noop] 270 template <> 271 struct coroutine_handle<noop_coroutine_promise> 272 { 273 // _GLIBCXX_RESOLVE_LIB_DEFECTS 274 // 3460. Unimplementable noop_coroutine_handle guarantees 275 // [coroutine.handle.noop.conv], conversion 276 constexpr operator coroutine_handle<>() const noexcept 277 { return coroutine_handle<>::from_address(address()); } 278 279 // [coroutine.handle.noop.observers], observers 280 constexpr explicit operator bool() const noexcept { return true; } 281 282 constexpr bool done() const noexcept { return false; } 283 284 // [coroutine.handle.noop.resumption], resumption 285 void operator()() const noexcept {} 286 287 void resume() const noexcept {} 288 289 void destroy() const noexcept {} 290 291 // [coroutine.handle.noop.promise], promise access 292 noop_coroutine_promise& promise() const noexcept 293 { return _S_fr.__p; } 294 295 // [coroutine.handle.noop.address], address 296 constexpr void* address() const noexcept { return _M_fr_ptr; } 297 298 private: 299 friend coroutine_handle noop_coroutine() noexcept; 300 301 struct __frame 302 { 303 static void __dummy_resume_destroy() { } 304 305 void (*__r)() = __dummy_resume_destroy; 306 void (*__d)() = __dummy_resume_destroy; 307 struct noop_coroutine_promise __p; 308 }; 309 310 static __frame _S_fr; 311 312 explicit coroutine_handle() noexcept = default; 313 314 void* _M_fr_ptr = &_S_fr; 315 }; 316 317 using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>; 318 319 inline noop_coroutine_handle::__frame 320 noop_coroutine_handle::_S_fr{}; 321 322 inline noop_coroutine_handle noop_coroutine() noexcept 323 { 324 return noop_coroutine_handle(); 325 } 326 327 // 17.12.5 Trivial awaitables 328 /// [coroutine.trivial.awaitables] 329 struct suspend_always 330 { 331 constexpr bool await_ready() const noexcept { return false; } 332 333 constexpr void await_suspend(coroutine_handle<>) const noexcept {} 334 335 constexpr void await_resume() const noexcept {} 336 }; 337 338 struct suspend_never 339 { 340 constexpr bool await_ready() const noexcept { return true; } 341 342 constexpr void await_suspend(coroutine_handle<>) const noexcept {} 343 344 constexpr void await_resume() const noexcept {} 345 }; 346 347 } // namespace __n4861 348 349 template<typename _Tp> struct hash; 350 351 template<typename _Promise> 352 struct hash<coroutine_handle<_Promise>> 353 { 354 size_t 355 operator()(const coroutine_handle<_Promise>& __h) const noexcept 356 { 357 return reinterpret_cast<size_t>(__h.address()); 358 } 359 }; 360 361 _GLIBCXX_END_NAMESPACE_VERSION 362 } // namespace std 363 364 #endif // __cpp_lib_coroutine 365 366 #pragma GCC diagnostic pop 367 #endif // _GLIBCXX_COROUTINE