Console Library 8.0.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
coroutine.h
Go to the documentation of this file.
1
11
12/*
13Copyright (c) 2026 MrXie1109
14
15Permission is hereby granted, free of charge, to any person obtaining a copy
16of this software and associated documentation files (the "Software"), to deal
17in the Software without restriction, including without limitation the rights
18to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19copies of the Software, and to permit persons to whom the Software is
20furnished to do so, subject to the following conditions:
21
22The above copyright notice and this permission notice shall be included in all
23copies or substantial portions of the Software.
24
25THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31SOFTWARE.
32*/
33
34#pragma once
35#include <functional>
36#include <memory>
37#include <utility>
38
39#include "../core/csexc.h"
40
41// clang-format off
42
52#define cr_begin(type, ...) \
53 int _state = 0; \
54 return [=](__VA_ARGS__) mutable -> type { \
55 switch (_state) { \
56 case 0:
57
66#define cr_yield(value) \
67 do { \
68 _state = __LINE__; \
69 return value; \
70 case __LINE__:; \
71 } while (false)
72
81#define cr_return(value) \
82 do { \
83 _state = __LINE__; \
84 return value; \
85 case __LINE__: \
86 throw console::StopIteration("StopIteration"); \
87 } while (false)
88
97#define cr_throw(exception) \
98 do { \
99 _state = __LINE__; \
100 throw exception; \
101 case __LINE__: \
102 throw console::StopIteration("StopIteration"); \
103 } while (false)
104
112#define cr_end \
113 _state = __LINE__; \
114 case __LINE__:; \
115 break; \
116 } \
117 throw console::StopIteration("StopIteration"); \
118 }
119
120// clang-format on
121
122namespace console {
130 template <class>
132
142 template <class Ret>
143 class Coroutine<Ret()> {
145 std::shared_ptr<std::function<Ret()>> coro;
147 std::shared_ptr<Ret> ptr;
148
149 public:
154 template <class F>
156 coro(std::make_shared<std::function<Ret()>>(std::move(f))) {}
157
163 Ret operator()() { return (*coro)(); }
164
166 using value_type = Ret;
168 using difference_type = ptrdiff_t;
174 using iterator_category = std::input_iterator_tag;
175
183 if (!ptr) ++(*this);
184 if (!ptr) throw StopIteration("StopIteration");
185 return *ptr;
186 }
187
193 try {
194 if (ptr)
195 *ptr = (*coro)();
196 else
197 ptr.reset(new Ret((*coro)()));
198 } catch (const StopIteration &) {
199 ptr.reset();
200 }
201 return *this;
202 }
203
209 Coroutine old = *this;
210 ++(*this);
211 return old;
212 }
213
219 bool operator==(const Coroutine &) {
220 if (!ptr) ++(*this);
221 return !ptr;
222 }
223
228 bool operator!=(const Coroutine &) {
229 if (!ptr) ++(*this);
230 return !!ptr;
231 }
232
234 Coroutine begin() { return *this; }
236 Coroutine end() { return *this; }
237 };
238
248 template <class Ret>
249 class Coroutine<Ret &()> {
251 std::shared_ptr<std::function<Ret &()>> coro;
253 Ret *ptr = nullptr;
254
255 public:
260 template <class F>
262 coro(std::make_shared<std::function<Ret &()>>(std::move(f))) {}
263
269 Ret &operator()() { return (*coro)(); }
270
272 using value_type = Ret;
274 using difference_type = ptrdiff_t;
276 using pointer = Ret *;
278 using reference = Ret &;
280 using iterator_category = std::input_iterator_tag;
281
289 if (!ptr) ++(*this);
290 if (!ptr) throw StopIteration("StopIteration");
291 return *ptr;
292 }
293
299 try {
300 ptr = &(*coro)();
301 } catch (const StopIteration &) {
302 ptr = nullptr;
303 }
304 return *this;
305 }
306
312 Coroutine old = *this;
313 ++(*this);
314 return old;
315 }
316
322 bool operator==(const Coroutine &) {
323 if (!ptr) ++(*this);
324 return !ptr;
325 }
326
331 bool operator!=(const Coroutine &) {
332 if (!ptr) ++(*this);
333 return !!ptr;
334 }
335
337 Coroutine begin() { return *this; }
339 Coroutine end() { return *this; }
340 };
341
349 template <class Ret, class... Args>
350 class Coroutine<Ret(Args...)> {
352 std::function<Ret(Args...)> coro;
353
354 public:
359 template <class F>
360 Coroutine(F &&f) : coro(std::forward<F>(f)) {}
361
368 template <class... Args_>
369 Ret operator()(Args_ &&...args) {
370 return coro(std::forward<Args_>(args)...);
371 }
372 };
373}
374
std::shared_ptr< std::function< Ret &()> > coro
底层协程函数 (由宏生成的 lambda)。
Definition coroutine.h:251
reference operator*()
解引用操作符,返回当前缓存值。
Definition coroutine.h:288
Coroutine end()
返回自身作为范围 for 的结束哨兵迭代器。
Definition coroutine.h:339
bool operator==(const Coroutine &)
相等比较。
Definition coroutine.h:322
std::input_iterator_tag iterator_category
迭代器类别 (输入迭代器)。
Definition coroutine.h:280
Ret * ptr
引用位置,结束后为 nullptr。
Definition coroutine.h:253
Coroutine operator++(int)
后置自增,推进协程。
Definition coroutine.h:311
Ret * pointer
指针类型。
Definition coroutine.h:276
bool operator!=(const Coroutine &)
不相等比较。
Definition coroutine.h:331
Ret & reference
引用类型。
Definition coroutine.h:278
ptrdiff_t difference_type
差值类型。
Definition coroutine.h:274
Ret value_type
值类型。
Definition coroutine.h:272
Ret & operator()()
直接调用协程,取下一个产出值。
Definition coroutine.h:269
Coroutine & operator++()
前置自增,推进协程。
Definition coroutine.h:298
Coroutine(F f)
从可调用对象构造协程迭代器。
Definition coroutine.h:261
Coroutine begin()
返回自身作为范围 for 的起始迭代器。
Definition coroutine.h:337
Coroutine & operator++()
前置自增,推进协程。
Definition coroutine.h:192
std::shared_ptr< std::function< Ret()> > coro
底层协程函数 (由宏生成的 lambda)。
Definition coroutine.h:145
Coroutine(F f)
从可调用对象构造协程迭代器。
Definition coroutine.h:155
Ret operator()()
直接调用协程,取下一个产出值。
Definition coroutine.h:163
bool operator!=(const Coroutine &)
不相等比较。
Definition coroutine.h:228
Coroutine begin()
返回自身作为范围 for 的起始迭代器。
Definition coroutine.h:234
Coroutine operator++(int)
后置自增,推进协程。
Definition coroutine.h:208
Ret value_type
值类型。
Definition coroutine.h:166
value_type reference
引用类型 (事实上是值类型)。
Definition coroutine.h:172
value_type * pointer
指针类型。
Definition coroutine.h:170
bool operator==(const Coroutine &)
相等比较。
Definition coroutine.h:219
std::input_iterator_tag iterator_category
迭代器类别 (输入迭代器)。
Definition coroutine.h:174
ptrdiff_t difference_type
差值类型。
Definition coroutine.h:168
value_type operator*()
解引用操作符,返回当前缓存值。
Definition coroutine.h:182
std::shared_ptr< Ret > ptr
缓存当前产出值;协程结束后为 nullptr。
Definition coroutine.h:147
Coroutine end()
返回自身作为范围 for 的结束哨兵迭代器。
Definition coroutine.h:236
Ret operator()(Args_ &&...args)
调用协程并获取产出值。
Definition coroutine.h:369
Coroutine(F &&f)
从可调用对象构造带参协程。
Definition coroutine.h:360
std::function< Ret(Args...)> coro
底层协程函数 (由宏生成的 lambda)。
Definition coroutine.h:352
协程/生成器包装器。
Definition coroutine.h:131
表示试图对已结束的生成器调用 next()。
Definition csexc.h:174
StopIteration(const std::string &msg)
构造 StopIteration。
Definition csexc.h:180
定义 console 库使用的自定义异常类层次结构。
本库所有组件所在的顶层命名空间。