C++23時代のフィボナッチ数列 (ジェネレータを使う)

フィボナッチ数列は再帰により導出するのが定番だが,
C++23から使える**ジェネレータ**を使うと, 簡潔に書ける.
ジェネレータは遅延評価のため, リソース効率が良く, 無限列を生成することができる.

```cpp:C++23以降
#include <print>
#include <vector>
#include <generator>
using std::generator;

// フィボナッチ数列のジェネレータ
generator<long long> fibo_generator() {
  using std::exchange;

  for (long long a = 0, b = 1 ;; a = exchange(b, a + b)) {
    co_yield a;
  }
}

int main() {
  using std::views::take;
  using std::views::enumerate;
  using std::ranges::to;
  using std::vector;
  using std::println;

  // 90までのフィボナッチ数列を出力
  constexpr int N = 90;

  const auto fibo = fibo_generator() | take(N) | to<vector>();

  for (const auto &[i, n] : fibo | enumerate) {
    println("{}: {}", i, n);
  }
}
```

<details><summary> 出力結果 </summary>

```yaml
0: 0
1: 1
2: 1
3: 2
4: 3
5: 5
6: 8
7: 13
8: 21
9: 34
10: 55
11: 89
12: 144
13: 233
14: 377
15: 610
16: 987
17: 1597
18: 2584
19: 4181
20: 6765
21: 10946
22: 17711
23: 28657
24: 46368
25: 75025
26: 121393
27: 196418
28: 317811
29: 514229
30: 832040
31: 1346269
32: 2178309
33: 3524578
34: 5702887
35: 9227465
36: 14930352
37: 24157817
38: 39088169
39: 63245986
40: 102334155
41: 165580141
42: 267914296
43: 433494437
44: 701408733
45: 1134903170
46: 1836311903
47: 2971215073
48: 4807526976
49: 7778742049
50: 12586269025
51: 20365011074
52: 32951280099
53: 53316291173
54: 86267571272
55: 139583862445
56: 225851433717
57: 365435296162
58: 591286729879
59: 956722026041
60: 1548008755920
61: 2504730781961
62: 4052739537881
63: 6557470319842
64: 10610209857723
65: 17167680177565
66: 27777890035288
67: 44945570212853
68: 72723460248141
69: 117669030460994
70: 190392490709135
71: 308061521170129
72: 498454011879264
73: 806515533049393
74: 1304969544928657
75: 2111485077978050
76: 3416454622906707
77: 5527939700884757
78: 8944394323791464
79: 14472334024676221
80: 23416728348467685
81: 37889062373143906
82: 61305790721611591
83: 99194853094755497
84: 160500643816367088
85: 259695496911122585
86: 420196140727489673
87: 679891637638612258
88: 1100087778366101931
89: 1779979416004714189
```
</details>


# 参考

https://cpprefjp.github.io/reference/generator/generator.html

https://cpprefjp.github.io/reference/utility/exchange.html

https://qiita.com/skkzsh/items/c9ed21130a952ba549b3


# 確認環境
```console
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/15.1.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --enable-languages=ada,c,c++,d,fortran,go,lto,m2,objc,obj-c++,rust,cobol --enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://gitlab.archlinux.org/archlinux/packaging/packages/gcc/-/issues --with-build-config=bootstrap-lto --with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto --enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp --enable-gnu-indirect-function --enable-gnu-unique-object --enable-libstdcxx-backtrace --enable-link-serialization=1 --enable-linker-build-id --enable-lto --enable-multilib --enable-plugin --enable-shared --enable-threads=posix --disable-libssp --disable-libstdcxx-pch --disable-werror
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 15.1.1 20250425 (GCC) 
```