Skip to content

Commit 1f04c8e

Browse files
authored
Update README.md
1 parent 97bd4e3 commit 1f04c8e

File tree

1 file changed

+112
-4
lines changed

1 file changed

+112
-4
lines changed

README.md

+112-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,120 @@
1-
# lambda_coroutines
1+
# Lambda Coroutines
22

33
[![codecov](https://codecov.io/gh/lefticus/lambda_coroutines/branch/master/graph/badge.svg)](https://codecov.io/gh/lefticus/lambda_coroutines)
4+
![CMake](https://github.com/lefticus/lambda_coroutines/workflows/CMake/badge.svg)
45

5-
[![Build Status](https://travis-ci.org/lefticus/lambda_coroutines.svg?branch=master)](https://travis-ci.org/lefticus/lambda_coroutines)
6+
## Description
7+
8+
A lightweight macro-based coroutine / resumable / cooperative multitasking function utility designed for C++14 lambdas.
9+
10+
# Examples
11+
12+
## Rotating Infinite Sequence
13+
14+
```cpp
15+
// lambda must be mutable
16+
auto next_direction = [state=0]() mutable {
17+
// set up coroutine, needs a captured integral `state` value
18+
lambda_co_begin(state);
19+
20+
// for eternity yeild the next possible value
21+
while (true) {
22+
lambda_co_yield(directions::Left);
23+
lambda_co_yield(directions::Right);
24+
lambda_co_yield(directions::Up);
25+
lambda_co_yield(directions::Down);
26+
}
27+
28+
lambda_co_end();
29+
};
30+
31+
int main() {
32+
auto val1 = next_direction(); // returns Left
33+
auto val2 = next_direction(); // returns Right
34+
// etc
35+
}
36+
```
37+
38+
## Obligatory Fibonacci Sequence
39+
40+
```cpp
41+
// generates the set of all fibonacci numbers representable by a ull, returns
42+
// empty optional at end of list
43+
auto fib = [state = 0, fib_2 = 0ULL, fib_1 = 1ULL]() mutable -> std::optional<unsigned long long> {
44+
lambda_co_begin(state);
45+
46+
lambda_co_yield(0);
47+
lambda_co_yield(1);
48+
49+
while (fib_1 < std::numeric_limits<decltype(fib_1)>::max() / 2) {
50+
fib_2 = std::exchange(fib_1, fib_2 + fib_1);
51+
lambda_co_yield(fib_1);
52+
}
53+
54+
lambda_co_return({});
55+
};
56+
```
57+
58+
## Ranged `for` Statement With Coroutine
59+
60+
```cpp
61+
// Using the Obligatory Fibonacci Sequence
62+
fmt::print("All possible Fib numbers representable by 'unsigned long long'");
63+
for (const auto value : lambda_coroutines::while_has_value(fib)) {
64+
fmt::print("{}\n", value);
65+
}
66+
```
67+
68+
## CPU Instruction Decoding State Machine
69+
70+
[Compiler Explorer playground](https://godbolt.org/z/7dr8j7) for this example.
71+
72+
```cpp
73+
enum OpCodes : std::uint8_t {
74+
ADD = 0,
75+
STA = 1,
76+
NOP = 2
77+
};
78+
struct Machine {
79+
std::uint8_t PC{0};
80+
std::uint8_t A{0};
81+
std::array<uint8_t, 256> RAM{STA, 10, ADD, 15};
82+
};
83+
84+
Machine machine;
85+
86+
auto CPU = [state = 0, &machine, op = OpCodes::NOP]() mutable {
87+
lambda_co_begin(state);
88+
89+
while(true) {
90+
op = static_cast<OpCodes>(machine.RAM[machine.PC]);
91+
++machine.PC;
92+
if (op == OpCodes::STA) {
93+
lambda_co_yield();
94+
machine.A = machine.RAM[machine.PC++];
95+
lambda_co_yield();
96+
} else if (op == OpCodes::ADD) {
97+
lambda_co_yield();
98+
machine.A += machine.RAM[machine.PC++];
99+
lambda_co_yield();
100+
} else if (op == OpCodes::NOP) {
101+
lambda_co_yield();
102+
};
103+
}
104+
105+
lambda_co_end();
106+
};
107+
```
6108

7-
[![Build status](https://ci.appveyor.com/api/projects/status/ro4lbfoa7n0sy74c/branch/master?svg=true)](https://ci.appveyor.com/project/lefticus/cpp-starter-project/branch/master)
8109

9-
![CMake](https://github.com/lefticus/lambda_coroutines/workflows/CMake/badge.svg)
10110

111+
# Limitations
11112

113+
* Cannot use `switch` statements in coroutine code
114+
* Cannot declare variables in coroutine code
115+
* Anything you care about must be part of the lambda capture declaration
116+
117+
118+
# Using In Your Project
12119

120+
It is one VERY simple header file https://github.com/lefticus/lambda_coroutines/blob/main/include/lambda_coroutines/lambda_coroutines.hpp

0 commit comments

Comments
 (0)