diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-06-01 20:59:10 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-06-01 20:59:10 +0000 |
commit | edb11085302f80f38c9d976f003aa1c9002c7abb (patch) | |
tree | edfe9dcac670e9f47ee7fdee893130fcf86ba196 /test/std/experimental/language.support/support.coroutines/end.to.end/oneshot_func.pass.cpp | |
parent | 10a0bef720b6882fce588a10b07b0584d62eac76 (diff) | |
download | src-edb11085302f80f38c9d976f003aa1c9002c7abb.tar.gz src-edb11085302f80f38c9d976f003aa1c9002c7abb.zip |
Vendor import of libc++ trunk r304460:vendor/libc++/libc++-trunk-r304460
Notes
Notes:
svn path=/vendor/libc++/dist/; revision=319467
svn path=/vendor/libc++/libc++-trunk-r304460/; revision=319468; tag=vendor/libc++/libc++-trunk-r304460
Diffstat (limited to 'test/std/experimental/language.support/support.coroutines/end.to.end/oneshot_func.pass.cpp')
-rw-r--r-- | test/std/experimental/language.support/support.coroutines/end.to.end/oneshot_func.pass.cpp | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/test/std/experimental/language.support/support.coroutines/end.to.end/oneshot_func.pass.cpp b/test/std/experimental/language.support/support.coroutines/end.to.end/oneshot_func.pass.cpp new file mode 100644 index 000000000000..d5f2c40e2a79 --- /dev/null +++ b/test/std/experimental/language.support/support.coroutines/end.to.end/oneshot_func.pass.cpp @@ -0,0 +1,83 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +#include <experimental/coroutine> +#include <vector> +#include <cassert> + +using namespace std::experimental; + +// This file tests, one shot, movable std::function like thing using coroutine +// for compile-time type erasure and unerasure. + +template <typename R> struct func { + struct promise_type { + R result; + func get_return_object() { return {this}; } + suspend_always initial_suspend() { return {}; } + suspend_always final_suspend() { return {}; } + void return_value(R v) { result = v; } + void unhandled_exception() {} + }; + + R operator()() { + h.resume(); + R result = h.promise().result; + h.destroy(); + h = nullptr; + return result; + }; + + func() {} + func(func &&rhs) : h(rhs.h) { rhs.h = nullptr; } + func(func const &) = delete; + + func &operator=(func &&rhs) { + if (this != &rhs) { + if (h) + h.destroy(); + h = rhs.h; + rhs.h = nullptr; + } + return *this; + } + + template <typename F> static func Create(F f) { co_return f(); } + + template <typename F> func(F f) : func(Create(f)) {} + + ~func() { + if (h) + h.destroy(); + } + +private: + func(promise_type *promise) + : h(coroutine_handle<promise_type>::from_promise(*promise)) {} + coroutine_handle<promise_type> h; +}; + +std::vector<int> yielded_values = {}; +int yield(int x) { yielded_values.push_back(x); return x + 1; } +float fyield(int x) { yielded_values.push_back(x); return x + 2; } + +void Do1(func<int> f) { yield(f()); } +void Do2(func<double> f) { yield(f()); } + +int main() { + Do1([] { return yield(43); }); + assert((yielded_values == std::vector<int>{43, 44})); + + yielded_values = {}; + Do2([] { return fyield(44); }); + assert((yielded_values == std::vector<int>{44, 46})); +} |