summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asio/src/tests/unit/experimental/coro/simple_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asio/src/tests/unit/experimental/coro/simple_test.cpp')
-rw-r--r--3rdparty/asio/src/tests/unit/experimental/coro/simple_test.cpp264
1 files changed, 264 insertions, 0 deletions
diff --git a/3rdparty/asio/src/tests/unit/experimental/coro/simple_test.cpp b/3rdparty/asio/src/tests/unit/experimental/coro/simple_test.cpp
new file mode 100644
index 00000000000..92eecd1d95a
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/experimental/coro/simple_test.cpp
@@ -0,0 +1,264 @@
+//
+// experimental/coro/simple_test.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2021 Klemens D. Morgenstern
+// (klemens dot morgenstern at gmx dot net)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/experimental/coro.hpp"
+
+#include "asio/co_spawn.hpp"
+#include "asio/detached.hpp"
+#include "asio/io_context.hpp"
+#include "asio/use_awaitable.hpp"
+#include <iostream>
+#include <vector>
+#include "../../unit_test.hpp"
+
+using namespace asio::experimental;
+
+namespace asio {
+namespace experimental {
+
+template struct coro<void(), void, any_io_executor>;
+template struct coro<int(), void, any_io_executor>;
+template struct coro<void(), int, any_io_executor>;
+template struct coro<int(int), void, any_io_executor>;
+template struct coro<int(), int, any_io_executor>;
+template struct coro<int(int), int, any_io_executor>;
+
+template struct coro<void() noexcept, void, any_io_executor>;
+template struct coro<int() noexcept, void, any_io_executor>;
+template struct coro<void() noexcept, int, any_io_executor>;
+template struct coro<int(int) noexcept, void, any_io_executor>;
+template struct coro<int() noexcept, int, any_io_executor>;
+template struct coro<int(int) noexcept, int, any_io_executor>;
+
+} // namespace experimental
+} // namespace asio
+
+namespace coro {
+
+template <typename Func>
+struct on_scope_exit
+{
+ Func func;
+
+ static_assert(noexcept(func()));
+
+ on_scope_exit(const Func &f)
+ : func(static_cast< Func && >(f))
+ {
+ }
+
+ on_scope_exit(Func &&f)
+ : func(f)
+ {
+ }
+
+ on_scope_exit(const on_scope_exit &) = delete;
+
+ ~on_scope_exit()
+ {
+ func();
+ }
+};
+
+asio::experimental::coro<int> generator_impl(
+ asio::any_io_executor, int& last, bool& destroyed)
+{
+ on_scope_exit x = [&]() noexcept { destroyed = true; };
+ (void)x;
+
+ int i = 0;
+ while (true)
+ co_yield last = ++i;
+}
+
+asio::awaitable<void> generator_test()
+{
+ int val = 0;
+ bool destr = false;
+ {
+ auto gi = generator_impl(
+ co_await asio::this_coro::executor, val, destr);
+
+ for (int i = 0; i < 10; i++)
+ {
+ ASIO_CHECK(val == i);
+ const auto next = co_await gi.async_resume(asio::use_awaitable);
+ ASIO_CHECK(next);
+ ASIO_CHECK(val == *next);
+ ASIO_CHECK(val == i + 1);
+ }
+
+ ASIO_CHECK(!destr);
+ }
+ ASIO_CHECK(destr);
+};
+
+void run_generator_test()
+{
+ asio::io_context ctx;
+ asio::co_spawn(ctx, generator_test, asio::detached);
+ ctx.run();
+}
+
+asio::experimental::coro<void, int> task_test(asio::io_context&)
+{
+ co_return 42;
+}
+
+asio::experimental::coro<void, int> task_throw(asio::io_context&)
+{
+ throw std::logic_error(__func__);
+ co_return 42;
+}
+
+void run_task_test()
+{
+ asio::io_context ctx;
+
+ bool tt1 = false;
+ bool tt2 = false;
+ bool tt3 = false;
+ bool tt4 = false;
+ auto tt = task_test(ctx);
+ tt.async_resume(
+ [&](std::exception_ptr pt, int i)
+ {
+ tt1 = true;
+ ASIO_CHECK(!pt);
+ ASIO_CHECK(i == 42);
+ tt.async_resume(
+ [&](std::exception_ptr pt, int)
+ {
+ tt2 = true;
+ ASIO_CHECK(pt);
+ });
+ });
+
+ auto tt_2 = task_throw(ctx);
+
+ tt_2.async_resume(
+ [&](std::exception_ptr pt, int)
+ {
+ tt3 = true;
+ ASIO_CHECK(pt);
+ tt.async_resume(
+ [&](std::exception_ptr pt, int)
+ {
+ tt4 = true;
+ ASIO_CHECK(pt);
+ });
+ });
+
+ ctx.run();
+
+ ASIO_CHECK(tt1);
+ ASIO_CHECK(tt2);
+ ASIO_CHECK(tt3);
+ ASIO_CHECK(tt4);
+}
+
+asio::experimental::coro<char> completion_generator_test_impl(
+ asio::any_io_executor, int limit)
+{
+ for (int i = 0; i < limit; i++)
+ co_yield i;
+}
+
+asio::awaitable<void> completion_generator_test()
+{
+ std::vector<int> res;
+ auto g = completion_generator_test_impl(
+ co_await asio::this_coro::executor, 10);
+
+ ASIO_CHECK(g.is_open());
+ while (auto val = co_await g.async_resume(asio::use_awaitable))
+ res.push_back(*val);
+
+ ASIO_CHECK(!g.is_open());
+ ASIO_CHECK((res == std::vector{0,1,2,3,4,5,6,7,8,9}));
+};
+
+
+void run_completion_generator_test()
+{
+ asio::io_context ctx;
+ asio::co_spawn(ctx, completion_generator_test, asio::detached);
+ ctx.run();
+}
+
+asio::experimental::coro<int(int)>
+symmetrical_test_impl(asio::any_io_executor)
+{
+ int i = 0;
+ while (true)
+ i = (co_yield i) + i;
+}
+
+asio::awaitable<void> symmetrical_test()
+{
+ auto g = symmetrical_test_impl(co_await asio::this_coro::executor);
+
+ ASIO_CHECK(g.is_open());
+
+ ASIO_CHECK(0 == (co_await g.async_resume(0,
+ asio::use_awaitable)).value_or(-1));
+
+ ASIO_CHECK(1 == (co_await g.async_resume(1,
+ asio::use_awaitable)).value_or(-1));
+
+ ASIO_CHECK(3 == (co_await g.async_resume(2,
+ asio::use_awaitable)).value_or(-1));
+
+ ASIO_CHECK(6 == (co_await g.async_resume(3,
+ asio::use_awaitable)).value_or(-1));
+
+ ASIO_CHECK(10 == (co_await g.async_resume(4,
+ asio::use_awaitable)).value_or(-1));
+
+ ASIO_CHECK(15 == (co_await g.async_resume(5,
+ asio::use_awaitable)).value_or(-1));
+
+ ASIO_CHECK(21 == (co_await g.async_resume(6,
+ asio::use_awaitable)).value_or(-1));
+
+ ASIO_CHECK(28 == (co_await g.async_resume(7,
+ asio::use_awaitable)).value_or(-1));
+
+ ASIO_CHECK(36 == (co_await g.async_resume(8,
+ asio::use_awaitable)).value_or(-1));
+
+ ASIO_CHECK(45 == (co_await g.async_resume(9,
+ asio::use_awaitable)).value_or(-1));
+};
+
+void run_symmetrical_test()
+{
+ asio::io_context ctx;
+ asio::co_spawn(ctx, symmetrical_test, asio::detached);
+ ctx.run();
+}
+
+} // namespace coro
+
+ASIO_TEST_SUITE
+(
+ "coro/simple_test",
+ ASIO_TEST_CASE(::coro::run_generator_test)
+ ASIO_TEST_CASE(::coro::run_task_test)
+ ASIO_TEST_CASE(::coro::run_symmetrical_test)
+ ASIO_TEST_CASE(::coro::run_completion_generator_test)
+)