1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14, c++17
10
11#include <coroutine>
12#include <vector>
13#include <cassert>
14
15#include "test_macros.h"
16
17// This file tests, one shot, movable std::function like thing using coroutine
18// for compile-time type erasure and unerasure.
19
20template <typename R> struct func {
21 struct promise_type {
22 R result;
23 func get_return_object() { return {this}; }
24 std::suspend_always initial_suspend() { return {}; }
25 std::suspend_always final_suspend() noexcept { return {}; }
26 void return_value(R v) { result = v; }
27 void unhandled_exception() {}
28 };
29
30 R operator()() {
31 h.resume();
32 R result = h.promise().result;
33 h.destroy();
34 h = nullptr;
35 return result;
36 };
37
38 func() {}
39 func(func &&rhs) : h(rhs.h) { rhs.h = nullptr; }
40 func(func const &) = delete;
41
42 func &operator=(func &&rhs) {
43 if (this != &rhs) {
44 if (h)
45 h.destroy();
46 h = rhs.h;
47 rhs.h = nullptr;
48 }
49 return *this;
50 }
51
52 template <typename F> static func Create(F f) { co_return f(); }
53
54 template <typename F> func(F f) : func(Create(f)) {}
55
56 ~func() {
57 if (h)
58 h.destroy();
59 }
60
61private:
62 func(promise_type *promise)
63 : h(std::coroutine_handle<promise_type>::from_promise(*promise)) {}
64 std::coroutine_handle<promise_type> h;
65};
66
67int main(int, char**) {
68 func<int> f = func<int>::Create([]() { return 44; });
69 assert(f() == 44);
70
71 return 0;
72}
73

source code of libcxx/test/std/language.support/support.coroutines/end.to.end/oneshot_func.pass.cpp