1 // (C) Copyright 2008-10 Anthony Williams
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
12 #include <boost/test/unit_test.hpp>
14 #include <boost/fiber/all.hpp>
18 struct my_exception
: public std::runtime_error
{
20 std::runtime_error("my_exception") {
27 A( A
const&) = delete;
30 A
& operator=( A
const&) = delete;
31 A
& operator=( A
&&) = default;
36 void fn1( boost::fibers::promise
< int > * p
, int i
) {
37 boost::this_fiber::yield();
42 boost::fibers::promise
< int > p
;
43 boost::fibers::future
< int > f( p
.get_future() );
44 boost::this_fiber::yield();
45 boost::fibers::fiber( boost::fibers::launch::dispatch
, fn1
, & p
, 7).detach();
46 boost::this_fiber::yield();
47 BOOST_CHECK( 7 == f
.get() );
58 boost::throw_exception( my_exception() );
63 boost::throw_exception( my_exception() );
81 boost::throw_exception( my_exception() );
86 void test_promise_create() {
87 // use std::allocator<> as default
88 boost::fibers::promise
< int > p1
;
90 // use std::allocator<> as user defined
91 std::allocator
< boost::fibers::promise
< int > > alloc
;
92 boost::fibers::promise
< int > p2( std::allocator_arg
, alloc
);
95 void test_promise_create_ref() {
96 // use std::allocator<> as default
97 boost::fibers::promise
< int& > p1
;
99 // use std::allocator<> as user defined
100 std::allocator
< boost::fibers::promise
< int& > > alloc
;
101 boost::fibers::promise
< int& > p2( std::allocator_arg
, alloc
);
104 void test_promise_create_void() {
105 // use std::allocator<> as default
106 boost::fibers::promise
< void > p1
;
108 // use std::allocator<> as user defined
109 std::allocator
< boost::fibers::promise
< void > > alloc
;
110 boost::fibers::promise
< void > p2( std::allocator_arg
, alloc
);
113 void test_promise_move() {
114 boost::fibers::promise
< int > p1
;
117 boost::fibers::promise
< int > p2( std::move( p1
) );
123 void test_promise_move_ref() {
124 boost::fibers::promise
< int& > p1
;
127 boost::fibers::promise
< int& > p2( std::move( p1
) );
133 void test_promise_move_void() {
134 boost::fibers::promise
< void > p1
;
137 boost::fibers::promise
< void > p2( std::move( p1
) );
143 void test_promise_swap() {
144 boost::fibers::promise
< int > p1
;
147 boost::fibers::promise
< int > p2( std::move( p1
) );
153 void test_promise_swap_ref() {
154 boost::fibers::promise
< int& > p1
;
157 boost::fibers::promise
< int& > p2( std::move( p1
) );
163 void test_promise_swap_void() {
164 boost::fibers::promise
< void > p1
;
167 boost::fibers::promise
< void > p2( std::move( p1
) );
173 void test_promise_get_future() {
174 boost::fibers::promise
< int > p1
;
177 boost::fibers::future
< int > f1
= p1
.get_future();
178 BOOST_CHECK( f1
.valid() );
180 // retrieve future a second time
183 f1
= p1
.get_future();
184 } catch ( boost::fibers::future_already_retrieved
const&) {
187 BOOST_CHECK( thrown
);
190 boost::fibers::promise
< int > p2( std::move( p1
) );
192 // retrieve future from uninitialized
195 f1
= p1
.get_future();
196 } catch ( boost::fibers::promise_uninitialized
const&) {
199 BOOST_CHECK( thrown
);
202 void test_promise_get_future_ref() {
203 boost::fibers::promise
< int& > p1
;
206 boost::fibers::future
< int& > f1
= p1
.get_future();
207 BOOST_CHECK( f1
.valid() );
209 // retrieve future a second time
212 f1
= p1
.get_future();
213 } catch ( boost::fibers::future_already_retrieved
const&) {
216 BOOST_CHECK( thrown
);
219 boost::fibers::promise
< int& > p2( std::move( p1
) );
221 // retrieve future from uninitialized
224 f1
= p1
.get_future();
225 } catch ( boost::fibers::promise_uninitialized
const&) {
228 BOOST_CHECK( thrown
);
231 void test_promise_get_future_void() {
232 boost::fibers::promise
< void > p1
;
235 boost::fibers::future
< void > f1
= p1
.get_future();
236 BOOST_CHECK( f1
.valid() );
238 // retrieve future a second time
241 f1
= p1
.get_future();
242 } catch ( boost::fibers::future_already_retrieved
const&) {
245 BOOST_CHECK( thrown
);
248 boost::fibers::promise
< void > p2( std::move( p1
) );
250 // retrieve future from uninitialized
253 f1
= p1
.get_future();
254 } catch ( boost::fibers::promise_uninitialized
const&) {
257 BOOST_CHECK( thrown
);
260 void test_promise_set_value() {
261 // promise takes a copyable as return type
262 boost::fibers::promise
< int > p1
;
263 boost::fibers::future
< int > f1
= p1
.get_future();
264 BOOST_CHECK( f1
.valid() );
268 BOOST_CHECK( 7 == f1
.get() );
270 // set value a second time
274 } catch ( boost::fibers::promise_already_satisfied
const&) {
277 BOOST_CHECK( thrown
);
280 void test_promise_set_value_move() {
281 // promise takes a copyable as return type
282 boost::fibers::promise
< A
> p1
;
283 boost::fibers::future
< A
> f1
= p1
.get_future();
284 BOOST_CHECK( f1
.valid() );
288 p1
.set_value( std::move( a1
) );
290 BOOST_CHECK( 7 == a2
.value
);
292 // set value a second time
296 p1
.set_value( std::move( a
) );
297 } catch ( boost::fibers::promise_already_satisfied
const&) {
300 BOOST_CHECK( thrown
);
303 void test_promise_set_value_ref() {
304 // promise takes a reference as return type
305 boost::fibers::promise
< int& > p1
;
306 boost::fibers::future
< int& > f1
= p1
.get_future();
307 BOOST_CHECK( f1
.valid() );
313 BOOST_CHECK( &i
== &j
);
315 // set value a second time
319 } catch ( boost::fibers::promise_already_satisfied
const&) {
322 BOOST_CHECK( thrown
);
325 void test_promise_set_value_void() {
326 // promise takes a copyable as return type
327 boost::fibers::promise
< void > p1
;
328 boost::fibers::future
< void > f1
= p1
.get_future();
329 BOOST_CHECK( f1
.valid() );
335 // set value a second time
339 } catch ( boost::fibers::promise_already_satisfied
const&) {
342 BOOST_CHECK( thrown
);
345 void test_promise_set_exception() {
346 boost::fibers::promise
< int > p1
;
347 boost::fibers::future
< int > f1
= p1
.get_future();
348 BOOST_CHECK( f1
.valid() );
349 p1
.set_exception( std::make_exception_ptr( my_exception() ) );
351 // set exception a second time
354 p1
.set_exception( std::make_exception_ptr( my_exception() ) );
355 } catch ( boost::fibers::promise_already_satisfied
const&) {
358 BOOST_CHECK( thrown
);
363 { p1
.set_value( 11); }
364 catch ( boost::fibers::promise_already_satisfied
const&)
366 BOOST_CHECK( thrown
);
369 void test_promise_set_exception_ref() {
370 boost::fibers::promise
< int& > p1
;
371 boost::fibers::future
< int& > f1
= p1
.get_future();
372 BOOST_CHECK( f1
.valid() );
373 p1
.set_exception( std::make_exception_ptr( my_exception() ) );
375 // set exception a second time
378 p1
.set_exception( std::make_exception_ptr( my_exception() ) );
379 } catch ( boost::fibers::promise_already_satisfied
const&) {
382 BOOST_CHECK( thrown
);
389 } catch ( boost::fibers::promise_already_satisfied
const&) {
392 BOOST_CHECK( thrown
);
395 void test_promise_set_exception_void() {
396 boost::fibers::promise
< void > p1
;
397 boost::fibers::future
< void > f1
= p1
.get_future();
398 BOOST_CHECK( f1
.valid() );
399 p1
.set_exception( std::make_exception_ptr( my_exception() ) );
401 // set exception a second time
404 p1
.set_exception( std::make_exception_ptr( my_exception() ) );
405 } catch ( boost::fibers::promise_already_satisfied
const&) {
408 BOOST_CHECK( thrown
);
414 } catch ( boost::fibers::promise_already_satisfied
const&) {
417 BOOST_CHECK( thrown
);
420 boost::unit_test_framework::test_suite
* init_unit_test_suite(int, char*[]) {
421 boost::unit_test_framework::test_suite
* test
=
422 BOOST_TEST_SUITE("Boost.Fiber: promise test suite");
424 test
->add(BOOST_TEST_CASE(test_promise_create
));
425 test
->add(BOOST_TEST_CASE(test_promise_create_ref
));
426 test
->add(BOOST_TEST_CASE(test_promise_create_void
));
427 test
->add(BOOST_TEST_CASE(test_promise_move
));
428 test
->add(BOOST_TEST_CASE(test_promise_move_ref
));
429 test
->add(BOOST_TEST_CASE(test_promise_move_void
));
430 test
->add(BOOST_TEST_CASE(test_promise_swap
));
431 test
->add(BOOST_TEST_CASE(test_promise_swap_ref
));
432 test
->add(BOOST_TEST_CASE(test_promise_swap_void
));
433 test
->add(BOOST_TEST_CASE(test_promise_get_future
));
434 test
->add(BOOST_TEST_CASE(test_promise_get_future_ref
));
435 test
->add(BOOST_TEST_CASE(test_promise_get_future_void
));
436 test
->add(BOOST_TEST_CASE(test_promise_set_value
));
437 test
->add(BOOST_TEST_CASE(test_promise_set_value_move
));
438 test
->add(BOOST_TEST_CASE(test_promise_set_value_ref
));
439 test
->add(BOOST_TEST_CASE(test_promise_set_value_void
));
440 test
->add(BOOST_TEST_CASE(test_promise_set_exception
));
441 test
->add(BOOST_TEST_CASE(test_promise_set_exception_ref
));
442 test
->add(BOOST_TEST_CASE(test_promise_set_exception_void
));