summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asio/src/tests/unit/experimental/coro/exception.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asio/src/tests/unit/experimental/coro/exception.cpp')
-rw-r--r--3rdparty/asio/src/tests/unit/experimental/coro/exception.cpp170
1 files changed, 170 insertions, 0 deletions
diff --git a/3rdparty/asio/src/tests/unit/experimental/coro/exception.cpp b/3rdparty/asio/src/tests/unit/experimental/coro/exception.cpp
new file mode 100644
index 00000000000..49a91dc32e2
--- /dev/null
+++ b/3rdparty/asio/src/tests/unit/experimental/coro/exception.cpp
@@ -0,0 +1,170 @@
+//
+// experimental/coro/exception.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 "asio/awaitable.hpp"
+#include "../../unit_test.hpp"
+
+using namespace asio::experimental;
+
+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> throwing_generator(
+ asio::any_io_executor, int &last, bool &destroyed)
+{
+ on_scope_exit x = [&]() noexcept { destroyed = true; };
+ (void)x;
+
+ int i = 0;
+ while (i < 3)
+ co_yield last = ++i;
+
+ throw std::runtime_error("throwing-generator");
+}
+
+asio::awaitable<void> throwing_generator_test()
+{
+ int val = 0;
+ bool destr = false;
+ {
+ auto gi = throwing_generator(
+ co_await asio::this_coro::executor,
+ val, destr);
+ bool caught = false;
+ try
+ {
+ 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);
+ }
+ }
+ catch (std::runtime_error &err)
+ {
+ caught = true;
+ using std::operator ""sv;
+ ASIO_CHECK(err.what() == "throwing-generator"sv);
+ }
+ ASIO_CHECK(val == 3);
+ ASIO_CHECK(caught);
+ }
+ ASIO_CHECK(destr);
+};
+
+void run_throwing_generator_test()
+{
+ asio::io_context ctx;
+ asio::co_spawn(ctx, throwing_generator_test(), asio::detached);
+ ctx.run();
+}
+
+asio::experimental::coro<int(int)> throwing_stacked(
+ asio::any_io_executor exec, int &val,
+ bool &destroyed_inner, bool &destroyed)
+{
+ on_scope_exit x = [&]() noexcept { destroyed = true; };
+ (void)x;
+
+ auto gen = throwing_generator(exec, val, destroyed_inner);
+ while (auto next = co_await gen) // 1, 2, 4, 8, ...
+ ASIO_CHECK(42 ==(co_yield *next)); // offset is delayed by one cycle
+}
+
+asio::awaitable<void> throwing_generator_stacked_test()
+{
+ int val = 0;
+ bool destr = false, destr_inner = false;
+ {
+ auto gi = throwing_stacked(
+ co_await asio::this_coro::executor,
+ val, destr, destr_inner);
+ bool caught = false;
+ try
+ {
+ for (int i = 0; i < 10; i++)
+ {
+ ASIO_CHECK(val == i);
+ const auto next =
+ co_await gi.async_resume(42, asio::use_awaitable);
+ ASIO_CHECK(next);
+ ASIO_CHECK(val == *next);
+ ASIO_CHECK(val == i + 1);
+ }
+ }
+ catch (std::runtime_error &err)
+ {
+ caught = true;
+ using std::operator ""sv;
+ ASIO_CHECK(err.what() == "throwing-generator"sv);
+ }
+ ASIO_CHECK(val == 3);
+ ASIO_CHECK(caught);
+ }
+ ASIO_CHECK(destr);
+ ASIO_CHECK(destr_inner);
+};
+
+void run_throwing_generator_stacked_test()
+{
+ asio::io_context ctx;
+ asio::co_spawn(ctx,
+ throwing_generator_stacked_test,
+ asio::detached);
+ ctx.run();
+}
+
+} // namespace coro
+
+ASIO_TEST_SUITE
+(
+ "coro/exception",
+ ASIO_TEST_CASE(::coro::run_throwing_generator_stacked_test)
+ ASIO_TEST_CASE(::coro::run_throwing_generator_test)
+)