summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/fiber/test/test_promise_dispatch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/fiber/test/test_promise_dispatch.cpp')
-rw-r--r--src/boost/libs/fiber/test/test_promise_dispatch.cpp445
1 files changed, 445 insertions, 0 deletions
diff --git a/src/boost/libs/fiber/test/test_promise_dispatch.cpp b/src/boost/libs/fiber/test/test_promise_dispatch.cpp
new file mode 100644
index 000000000..d3f90f220
--- /dev/null
+++ b/src/boost/libs/fiber/test/test_promise_dispatch.cpp
@@ -0,0 +1,445 @@
+// (C) Copyright 2008-10 Anthony Williams
+//
+// 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)
+
+#include <utility>
+#include <memory>
+#include <stdexcept>
+#include <string>
+
+#include <boost/test/unit_test.hpp>
+
+#include <boost/fiber/all.hpp>
+
+int gi = 7;
+
+struct my_exception : public std::runtime_error {
+ my_exception() :
+ std::runtime_error("my_exception") {
+ }
+};
+
+struct A {
+ A() = default;
+
+ A( A const&) = delete;
+ A( A &&) = default;
+
+ A & operator=( A const&) = delete;
+ A & operator=( A &&) = default;
+
+ int value{ 0 };
+};
+
+void fn1( boost::fibers::promise< int > * p, int i) {
+ boost::this_fiber::yield();
+ p->set_value( i);
+}
+
+void fn2() {
+ boost::fibers::promise< int > p;
+ boost::fibers::future< int > f( p.get_future() );
+ boost::this_fiber::yield();
+ boost::fibers::fiber( boost::fibers::launch::dispatch, fn1, & p, 7).detach();
+ boost::this_fiber::yield();
+ BOOST_CHECK( 7 == f.get() );
+}
+
+int fn3() {
+ return 3;
+}
+
+void fn4() {
+}
+
+int fn5() {
+ boost::throw_exception( my_exception() );
+ return 3;
+}
+
+void fn6() {
+ boost::throw_exception( my_exception() );
+}
+
+int & fn7() {
+ return gi;
+}
+
+int fn8( int i) {
+ return i;
+}
+
+A fn9() {
+ A a;
+ a.value = 3;
+ return a;
+}
+
+A fn10() {
+ boost::throw_exception( my_exception() );
+ return A();
+}
+
+// promise
+void test_promise_create() {
+ // use std::allocator<> as default
+ boost::fibers::promise< int > p1;
+
+ // use std::allocator<> as user defined
+ std::allocator< boost::fibers::promise< int > > alloc;
+ boost::fibers::promise< int > p2( std::allocator_arg, alloc);
+}
+
+void test_promise_create_ref() {
+ // use std::allocator<> as default
+ boost::fibers::promise< int& > p1;
+
+ // use std::allocator<> as user defined
+ std::allocator< boost::fibers::promise< int& > > alloc;
+ boost::fibers::promise< int& > p2( std::allocator_arg, alloc);
+}
+
+void test_promise_create_void() {
+ // use std::allocator<> as default
+ boost::fibers::promise< void > p1;
+
+ // use std::allocator<> as user defined
+ std::allocator< boost::fibers::promise< void > > alloc;
+ boost::fibers::promise< void > p2( std::allocator_arg, alloc);
+}
+
+void test_promise_move() {
+ boost::fibers::promise< int > p1;
+
+ // move construction
+ boost::fibers::promise< int > p2( std::move( p1) );
+
+ // move assigment
+ p1 = std::move( p2);
+}
+
+void test_promise_move_ref() {
+ boost::fibers::promise< int& > p1;
+
+ // move construction
+ boost::fibers::promise< int& > p2( std::move( p1) );
+
+ // move assigment
+ p1 = std::move( p2);
+}
+
+void test_promise_move_void() {
+ boost::fibers::promise< void > p1;
+
+ // move construction
+ boost::fibers::promise< void > p2( std::move( p1) );
+
+ // move assigment
+ p1 = std::move( p2);
+}
+
+void test_promise_swap() {
+ boost::fibers::promise< int > p1;
+
+ // move construction
+ boost::fibers::promise< int > p2( std::move( p1) );
+
+ // swap
+ p1.swap( p2);
+}
+
+void test_promise_swap_ref() {
+ boost::fibers::promise< int& > p1;
+
+ // move construction
+ boost::fibers::promise< int& > p2( std::move( p1) );
+
+ // swap
+ p1.swap( p2);
+}
+
+void test_promise_swap_void() {
+ boost::fibers::promise< void > p1;
+
+ // move construction
+ boost::fibers::promise< void > p2( std::move( p1) );
+
+ // swap
+ p1.swap( p2);
+}
+
+void test_promise_get_future() {
+ boost::fibers::promise< int > p1;
+
+ // retrieve future
+ boost::fibers::future< int > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // retrieve future a second time
+ bool thrown = false;
+ try {
+ f1 = p1.get_future();
+ } catch ( boost::fibers::future_already_retrieved const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+
+ // move construction
+ boost::fibers::promise< int > p2( std::move( p1) );
+
+ // retrieve future from uninitialized
+ thrown = false;
+ try {
+ f1 = p1.get_future();
+ } catch ( boost::fibers::promise_uninitialized const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+}
+
+void test_promise_get_future_ref() {
+ boost::fibers::promise< int& > p1;
+
+ // retrieve future
+ boost::fibers::future< int& > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // retrieve future a second time
+ bool thrown = false;
+ try {
+ f1 = p1.get_future();
+ } catch ( boost::fibers::future_already_retrieved const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+
+ // move construction
+ boost::fibers::promise< int& > p2( std::move( p1) );
+
+ // retrieve future from uninitialized
+ thrown = false;
+ try {
+ f1 = p1.get_future();
+ } catch ( boost::fibers::promise_uninitialized const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+}
+
+void test_promise_get_future_void() {
+ boost::fibers::promise< void > p1;
+
+ // retrieve future
+ boost::fibers::future< void > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // retrieve future a second time
+ bool thrown = false;
+ try {
+ f1 = p1.get_future();
+ } catch ( boost::fibers::future_already_retrieved const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+
+ // move construction
+ boost::fibers::promise< void > p2( std::move( p1) );
+
+ // retrieve future from uninitialized
+ thrown = false;
+ try {
+ f1 = p1.get_future();
+ } catch ( boost::fibers::promise_uninitialized const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+}
+
+void test_promise_set_value() {
+ // promise takes a copyable as return type
+ boost::fibers::promise< int > p1;
+ boost::fibers::future< int > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // copy value
+ p1.set_value( 7);
+ BOOST_CHECK( 7 == f1.get() );
+
+ // set value a second time
+ bool thrown = false;
+ try {
+ p1.set_value( 11);
+ } catch ( boost::fibers::promise_already_satisfied const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+}
+
+void test_promise_set_value_move() {
+ // promise takes a copyable as return type
+ boost::fibers::promise< A > p1;
+ boost::fibers::future< A > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // move value
+ A a1; a1.value = 7;
+ p1.set_value( std::move( a1) );
+ A a2 = f1.get();
+ BOOST_CHECK( 7 == a2.value);
+
+ // set value a second time
+ bool thrown = false;
+ try {
+ A a;
+ p1.set_value( std::move( a) );
+ } catch ( boost::fibers::promise_already_satisfied const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+}
+
+void test_promise_set_value_ref() {
+ // promise takes a reference as return type
+ boost::fibers::promise< int& > p1;
+ boost::fibers::future< int& > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // copy value
+ int i = 7;
+ p1.set_value( i);
+ int & j = f1.get();
+ BOOST_CHECK( &i == &j);
+
+ // set value a second time
+ bool thrown = false;
+ try {
+ p1.set_value( i);
+ } catch ( boost::fibers::promise_already_satisfied const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+}
+
+void test_promise_set_value_void() {
+ // promise takes a copyable as return type
+ boost::fibers::promise< void > p1;
+ boost::fibers::future< void > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+
+ // set void
+ p1.set_value();
+ f1.get();
+
+ // set value a second time
+ bool thrown = false;
+ try {
+ p1.set_value();
+ } catch ( boost::fibers::promise_already_satisfied const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+}
+
+void test_promise_set_exception() {
+ boost::fibers::promise< int > p1;
+ boost::fibers::future< int > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+ p1.set_exception( std::make_exception_ptr( my_exception() ) );
+
+ // set exception a second time
+ bool thrown = false;
+ try {
+ p1.set_exception( std::make_exception_ptr( my_exception() ) );
+ } catch ( boost::fibers::promise_already_satisfied const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+
+ // set value
+ thrown = false;
+ try
+ { p1.set_value( 11); }
+ catch ( boost::fibers::promise_already_satisfied const&)
+ { thrown = true; }
+ BOOST_CHECK( thrown);
+}
+
+void test_promise_set_exception_ref() {
+ boost::fibers::promise< int& > p1;
+ boost::fibers::future< int& > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+ p1.set_exception( std::make_exception_ptr( my_exception() ) );
+
+ // set exception a second time
+ bool thrown = false;
+ try {
+ p1.set_exception( std::make_exception_ptr( my_exception() ) );
+ } catch ( boost::fibers::promise_already_satisfied const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+
+ // set value
+ thrown = false;
+ int i = 11;
+ try {
+ p1.set_value( i);
+ } catch ( boost::fibers::promise_already_satisfied const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+}
+
+void test_promise_set_exception_void() {
+ boost::fibers::promise< void > p1;
+ boost::fibers::future< void > f1 = p1.get_future();
+ BOOST_CHECK( f1.valid() );
+ p1.set_exception( std::make_exception_ptr( my_exception() ) );
+
+ // set exception a second time
+ bool thrown = false;
+ try {
+ p1.set_exception( std::make_exception_ptr( my_exception() ) );
+ } catch ( boost::fibers::promise_already_satisfied const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+
+ // set value
+ thrown = false;
+ try {
+ p1.set_value();
+ } catch ( boost::fibers::promise_already_satisfied const&) {
+ thrown = true;
+ }
+ BOOST_CHECK( thrown);
+}
+
+boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[]) {
+ boost::unit_test_framework::test_suite* test =
+ BOOST_TEST_SUITE("Boost.Fiber: promise test suite");
+
+ test->add(BOOST_TEST_CASE(test_promise_create));
+ test->add(BOOST_TEST_CASE(test_promise_create_ref));
+ test->add(BOOST_TEST_CASE(test_promise_create_void));
+ test->add(BOOST_TEST_CASE(test_promise_move));
+ test->add(BOOST_TEST_CASE(test_promise_move_ref));
+ test->add(BOOST_TEST_CASE(test_promise_move_void));
+ test->add(BOOST_TEST_CASE(test_promise_swap));
+ test->add(BOOST_TEST_CASE(test_promise_swap_ref));
+ test->add(BOOST_TEST_CASE(test_promise_swap_void));
+ test->add(BOOST_TEST_CASE(test_promise_get_future));
+ test->add(BOOST_TEST_CASE(test_promise_get_future_ref));
+ test->add(BOOST_TEST_CASE(test_promise_get_future_void));
+ test->add(BOOST_TEST_CASE(test_promise_set_value));
+ test->add(BOOST_TEST_CASE(test_promise_set_value_move));
+ test->add(BOOST_TEST_CASE(test_promise_set_value_ref));
+ test->add(BOOST_TEST_CASE(test_promise_set_value_void));
+ test->add(BOOST_TEST_CASE(test_promise_set_exception));
+ test->add(BOOST_TEST_CASE(test_promise_set_exception_ref));
+ test->add(BOOST_TEST_CASE(test_promise_set_exception_void));
+
+ return test;
+}