1//
2// Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8#include <boost/cobalt/promise.hpp>
9#include <boost/cobalt/op.hpp>
10
11#include <boost/test/unit_test.hpp>
12#include "test.hpp"
13#include <boost/asio/detached.hpp>
14#include <boost/asio/steady_timer.hpp>
15#include <boost/asio/awaitable.hpp>
16
17#include <boost/asio/bind_cancellation_slot.hpp>
18
19using namespace boost;
20
21BOOST_AUTO_TEST_SUITE(promise);
22
23cobalt::promise<void> test0()
24{
25 co_return;
26}
27
28cobalt::promise<double> test2(int i)
29{
30 co_await test0();
31 co_return i;
32}
33
34
35cobalt::promise<int> test1(asio::any_io_executor exec)
36{
37 co_await test2(i: 42);
38 co_await test2(i: 42);
39
40 BOOST_CHECK(test2(42).get() == 42);
41
42 co_await asio::post(ex: exec, token: cobalt::use_op);
43 co_return 452;
44}
45
46
47CO_TEST_CASE(cobalt_1)
48{
49 co_await test1(exec: co_await asio::this_coro::executor);
50 co_return;
51}
52
53
54cobalt::promise<void> should_unwind(asio::io_context & ctx)
55{
56 co_await asio::post(ctx, token: cobalt::use_op);
57}
58
59BOOST_AUTO_TEST_CASE(unwind)
60{
61 asio::io_context ctx;
62 boost::cobalt::this_thread::set_executor(ctx.get_executor());
63 +should_unwind(ctx);
64}
65
66cobalt::promise<int> return_(std::size_t ms)
67{
68 co_return 1234u;
69}
70
71cobalt::promise<int> return_(std::size_t ms, asio::executor_arg_t,
72 boost::cobalt::executor )
73{
74 co_return 1234u;
75}
76
77cobalt::promise<std::size_t> delay_r(asio::io_context &ctx, std::size_t ms,
78 asio::executor_arg_t, asio::any_io_executor )
79{
80 auto tim = cobalt::use_op.as_default_on(object: asio::steady_timer(ctx, std::chrono::milliseconds{ms}));
81 co_await tim.async_wait();
82 co_return ms;
83}
84
85
86cobalt::promise<std::size_t> delay_r(asio::any_io_executor exec, std::size_t ms)
87{
88 auto tim = cobalt::use_op.as_default_on(object: asio::steady_timer(exec, std::chrono::milliseconds{ms}));
89 co_await tim.async_wait();
90 co_return ms;
91}
92
93cobalt::promise<void> throw_()
94{
95 throw std::runtime_error("throw_");
96 co_return ;
97}
98
99cobalt::promise<void> throw_post()
100{
101 co_await asio::post(ex: cobalt::this_thread::get_executor(), token: cobalt::use_op);
102 throw std::runtime_error("throw_");
103 co_return ;
104}
105
106
107BOOST_AUTO_TEST_CASE(get)
108{
109 BOOST_CHECK_THROW(throw_().get(), std::exception);
110}
111
112cobalt::promise<void> delay_v(asio::io_context &ctx, std::size_t ms)
113{
114 asio::steady_timer tim(ctx, std::chrono::milliseconds{ms});
115 co_await tim.async_wait(token: boost::cobalt::use_op);
116}
117
118
119CO_TEST_CASE(cancel_int)
120{
121 BOOST_CHECK_THROW(co_await throw_(), std::exception);
122}
123
124
125
126CO_TEST_CASE(throw_cpl_delay)
127{
128 BOOST_CHECK_THROW(co_await throw_post(), std::exception);
129}
130
131CO_TEST_CASE(stop_)
132try
133{
134 BOOST_CHECK_THROW(
135 co_await
136 []() -> cobalt::promise<void>
137 {
138 co_await stop();
139 }(), boost::system::system_error);
140}
141catch(...)
142{
143}
144
145struct promise_move_only
146{
147 promise_move_only() = default;
148 promise_move_only(promise_move_only &&) = default;
149 promise_move_only & operator=(promise_move_only &&) = delete;
150};
151
152cobalt::promise<promise_move_only> pro_move_only_test()
153{
154 co_return promise_move_only{};
155}
156
157CO_TEST_CASE(move_only)
158{
159 co_await pro_move_only_test();
160}
161
162BOOST_AUTO_TEST_SUITE_END();

source code of boost/libs/cobalt/test/promise.cpp