diff options
Diffstat (limited to 'test/std/thread/futures')
78 files changed, 4937 insertions, 0 deletions
diff --git a/test/std/thread/futures/futures.async/async.pass.cpp b/test/std/thread/futures/futures.async/async.pass.cpp new file mode 100644 index 0000000000000..c8a742566d8f2 --- /dev/null +++ b/test/std/thread/futures/futures.async/async.pass.cpp @@ -0,0 +1,198 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// template <class F, class... Args> +// future<typename result_of<F(Args...)>::type> +// async(F&& f, Args&&... args); + +// template <class F, class... Args> +// future<typename result_of<F(Args...)>::type> +// async(launch policy, F&& f, Args&&... args); + +#include <future> +#include <memory> +#include <cassert> + +typedef std::chrono::high_resolution_clock Clock; +typedef std::chrono::milliseconds ms; + +int f0() +{ + std::this_thread::sleep_for(ms(200)); + return 3; +} + +int i = 0; + +int& f1() +{ + std::this_thread::sleep_for(ms(200)); + return i; +} + +void f2() +{ + std::this_thread::sleep_for(ms(200)); +} + +std::unique_ptr<int> f3(int i) +{ + std::this_thread::sleep_for(ms(200)); + return std::unique_ptr<int>(new int(i)); +} + +std::unique_ptr<int> f4(std::unique_ptr<int>&& p) +{ + std::this_thread::sleep_for(ms(200)); + return std::move(p); +} + +void f5(int i) +{ + std::this_thread::sleep_for(ms(200)); + throw i; +} + +int main() +{ + { + std::future<int> f = std::async(f0); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(f.get() == 3); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<int> f = std::async(std::launch::async, f0); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(f.get() == 3); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<int> f = std::async(std::launch::any, f0); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(f.get() == 3); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<int> f = std::async(std::launch::deferred, f0); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(f.get() == 3); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 > ms(100)); + } + + { + std::future<int&> f = std::async(f1); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(&f.get() == &i); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<int&> f = std::async(std::launch::async, f1); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(&f.get() == &i); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<int&> f = std::async(std::launch::any, f1); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(&f.get() == &i); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<int&> f = std::async(std::launch::deferred, f1); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(&f.get() == &i); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 > ms(100)); + } + + { + std::future<void> f = std::async(f2); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + f.get(); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<void> f = std::async(std::launch::async, f2); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + f.get(); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<void> f = std::async(std::launch::any, f2); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + f.get(); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + { + std::future<void> f = std::async(std::launch::deferred, f2); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + f.get(); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 > ms(100)); + } + + { + std::future<std::unique_ptr<int>> f = std::async(f3, 3); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(*f.get() == 3); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + + { + std::future<std::unique_ptr<int>> f = + std::async(f4, std::unique_ptr<int>(new int(3))); + std::this_thread::sleep_for(ms(300)); + Clock::time_point t0 = Clock::now(); + assert(*f.get() == 3); + Clock::time_point t1 = Clock::now(); + assert(t1-t0 < ms(100)); + } + + { + std::future<void> f = std::async(f5, 3); + std::this_thread::sleep_for(ms(300)); + try { f.get(); assert (false); } catch ( int ex ) {} + } + + { + std::future<void> f = std::async(std::launch::deferred, f5, 3); + std::this_thread::sleep_for(ms(300)); + try { f.get(); assert (false); } catch ( int ex ) {} + } + +} diff --git a/test/std/thread/futures/futures.async/async_race.pass.cpp b/test/std/thread/futures/futures.async/async_race.pass.cpp new file mode 100644 index 0000000000000..325a027132de9 --- /dev/null +++ b/test/std/thread/futures/futures.async/async_race.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// template <class F, class... Args> +// future<typename result_of<F(Args...)>::type> +// async(F&& f, Args&&... args); + +// template <class F, class... Args> +// future<typename result_of<F(Args...)>::type> +// async(launch policy, F&& f, Args&&... args); + +// This test is designed to cause and allow TSAN to detect the race condition +// reported in PR23293. (http://llvm.org/PR23293). + +#include <future> +#include <chrono> +#include <thread> +#include <memory> +#include <cassert> + +int f_async() { + typedef std::chrono::milliseconds ms; + std::this_thread::sleep_for(ms(200)); + return 42; +} + +bool ran = false; + +int f_deferred() { + ran = true; + return 42; +} + +void test_each() { + { + std::future<int> f = std::async(f_async); + int const result = f.get(); + assert(result == 42); + } + { + std::future<int> f = std::async(std::launch::async, f_async); + int const result = f.get(); + assert(result == 42); + } + { + ran = false; + std::future<int> f = std::async(std::launch::deferred, f_deferred); + assert(ran == false); + int const result = f.get(); + assert(ran == true); + assert(result == 42); + } +} + +int main() { + for (int i=0; i < 25; ++i) test_each(); +} diff --git a/test/std/thread/futures/futures.errors/default_error_condition.pass.cpp b/test/std/thread/futures/futures.errors/default_error_condition.pass.cpp new file mode 100644 index 0000000000000..7f28b8a23b810 --- /dev/null +++ b/test/std/thread/futures/futures.errors/default_error_condition.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// const error_category& future_category(); + +// virtual error_condition default_error_condition(int ev) const; + +#include <future> +#include <cassert> + +int main() +{ + const std::error_category& e_cat = std::future_category(); + std::error_condition e_cond = e_cat.default_error_condition(static_cast<int>(std::errc::not_a_directory)); + assert(e_cond.category() == e_cat); + assert(e_cond.value() == static_cast<int>(std::errc::not_a_directory)); +} diff --git a/test/std/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp b/test/std/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp new file mode 100644 index 0000000000000..cd0017657740f --- /dev/null +++ b/test/std/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// const error_category& future_category(); + +// virtual bool equivalent(const error_code& code, int condition) const; + +#include <future> +#include <cassert> + +int main() +{ + const std::error_category& e_cat = std::future_category(); + assert(e_cat.equivalent(std::error_code(5, e_cat), 5)); + assert(!e_cat.equivalent(std::error_code(5, e_cat), 6)); +} diff --git a/test/std/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp b/test/std/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp new file mode 100644 index 0000000000000..05ad1ec9c6f55 --- /dev/null +++ b/test/std/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// const error_category& future_category(); + +// virtual bool equivalent(int code, const error_condition& condition) const; + +#include <future> +#include <cassert> + +int main() +{ + const std::error_category& e_cat = std::future_category(); + std::error_condition e_cond = e_cat.default_error_condition(5); + assert(e_cat.equivalent(5, e_cond)); + assert(!e_cat.equivalent(6, e_cond)); +} diff --git a/test/std/thread/futures/futures.errors/future_category.pass.cpp b/test/std/thread/futures/futures.errors/future_category.pass.cpp new file mode 100644 index 0000000000000..7f407a061d954 --- /dev/null +++ b/test/std/thread/futures/futures.errors/future_category.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// const error_category& future_category(); + +#include <future> +#include <cstring> +#include <cassert> + +int main() +{ + const std::error_category& ec = std::future_category(); + assert(std::strcmp(ec.name(), "future") == 0); +} diff --git a/test/std/thread/futures/futures.errors/make_error_code.pass.cpp b/test/std/thread/futures/futures.errors/make_error_code.pass.cpp new file mode 100644 index 0000000000000..3c14addf309fb --- /dev/null +++ b/test/std/thread/futures/futures.errors/make_error_code.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class error_code + +// error_code make_error_code(future_errc e); + +#include <future> +#include <cassert> + +int main() +{ + { + std::error_code ec = make_error_code(std::future_errc::broken_promise); + assert(ec.value() == static_cast<int>(std::future_errc::broken_promise)); + assert(ec.category() == std::future_category()); + } +} diff --git a/test/std/thread/futures/futures.errors/make_error_condition.pass.cpp b/test/std/thread/futures/futures.errors/make_error_condition.pass.cpp new file mode 100644 index 0000000000000..52972aa373f58 --- /dev/null +++ b/test/std/thread/futures/futures.errors/make_error_condition.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class error_condition + +// error_condition make_error_condition(future_errc e); + +#include <future> +#include <cassert> + +int main() +{ + { + const std::error_condition ec1 = + std::make_error_condition(std::future_errc::future_already_retrieved); + assert(ec1.value() == + static_cast<int>(std::future_errc::future_already_retrieved)); + assert(ec1.category() == std::future_category()); + } +} diff --git a/test/std/thread/futures/futures.future_error/code.pass.cpp b/test/std/thread/futures/futures.future_error/code.pass.cpp new file mode 100644 index 0000000000000..e02af486fc39c --- /dev/null +++ b/test/std/thread/futures/futures.future_error/code.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class future_error + +// const error_code& code() const throw(); + +#include <future> +#include <cassert> + +int main() +{ + { + std::error_code ec = std::make_error_code(std::future_errc::broken_promise); + std::future_error f(ec); + assert(f.code() == ec); + } + { + std::error_code ec = std::make_error_code(std::future_errc::future_already_retrieved); + std::future_error f(ec); + assert(f.code() == ec); + } + { + std::error_code ec = std::make_error_code(std::future_errc::promise_already_satisfied); + std::future_error f(ec); + assert(f.code() == ec); + } + { + std::error_code ec = std::make_error_code(std::future_errc::no_state); + std::future_error f(ec); + assert(f.code() == ec); + } +} diff --git a/test/std/thread/futures/futures.future_error/types.pass.cpp b/test/std/thread/futures/futures.future_error/types.pass.cpp new file mode 100644 index 0000000000000..e741dd06e4b97 --- /dev/null +++ b/test/std/thread/futures/futures.future_error/types.pass.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class future_error : public logic_error {...}; + +#include <future> +#include <type_traits> + +int main() +{ + static_assert((std::is_convertible<std::future_error*, + std::logic_error*>::value), ""); +} diff --git a/test/std/thread/futures/futures.future_error/what.pass.cpp b/test/std/thread/futures/futures.future_error/what.pass.cpp new file mode 100644 index 0000000000000..52d2e944a684e --- /dev/null +++ b/test/std/thread/futures/futures.future_error/what.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// LWG 2056 changed the values of future_errc, so if we're using new headers +// with an old library we'll get incorrect messages. +// +// XFAIL: with_system_cxx_lib=x86_64-apple-darwin11 +// XFAIL: with_system_cxx_lib=x86_64-apple-darwin12 +// XFAIL: with_system_cxx_lib=x86_64-apple-darwin13 + +// <future> + +// class future_error + +// const char* what() const throw(); + +#include <future> +#include <cstring> +#include <cassert> + +int main() +{ + { + std::future_error f(std::make_error_code(std::future_errc::broken_promise)); + assert(std::strcmp(f.what(), "The associated promise has been destructed prior " + "to the associated state becoming ready.") == 0); + } + { + std::future_error f(std::make_error_code(std::future_errc::future_already_retrieved)); + assert(std::strcmp(f.what(), "The future has already been retrieved from " + "the promise or packaged_task.") == 0); + } + { + std::future_error f(std::make_error_code(std::future_errc::promise_already_satisfied)); + assert(std::strcmp(f.what(), "The state of the promise has already been set.") == 0); + } + { + std::future_error f(std::make_error_code(std::future_errc::no_state)); + assert(std::strcmp(f.what(), "Operation not permitted on an object without " + "an associated state.") == 0); + } +} diff --git a/test/std/thread/futures/futures.overview/future_errc.pass.cpp b/test/std/thread/futures/futures.overview/future_errc.pass.cpp new file mode 100644 index 0000000000000..1e6fcb76a0e73 --- /dev/null +++ b/test/std/thread/futures/futures.overview/future_errc.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// enum class future_errc +// { +// future_already_retrieved = 1, +// promise_already_satisfied, +// no_state +// broken_promise, +// }; + +#include <future> + +int main() +{ + static_assert(static_cast<int>(std::future_errc::future_already_retrieved) == 1, ""); + static_assert(static_cast<int>(std::future_errc::promise_already_satisfied) == 2, ""); + static_assert(static_cast<int>(std::future_errc::no_state) == 3, ""); + static_assert(static_cast<int>(std::future_errc::broken_promise) == 4, ""); +} diff --git a/test/std/thread/futures/futures.overview/future_status.pass.cpp b/test/std/thread/futures/futures.overview/future_status.pass.cpp new file mode 100644 index 0000000000000..2c196aaac56d1 --- /dev/null +++ b/test/std/thread/futures/futures.overview/future_status.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// enum class future_status +// { +// ready, +// timeout, +// deferred +// }; + +#include <future> + +int main() +{ + static_assert(static_cast<int>(std::future_status::ready) == 0, ""); + static_assert(static_cast<int>(std::future_status::timeout) == 1, ""); + static_assert(static_cast<int>(std::future_status::deferred) == 2, ""); +} diff --git a/test/std/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp b/test/std/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp new file mode 100644 index 0000000000000..499de52598b65 --- /dev/null +++ b/test/std/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// template <> struct is_error_code_enum<future_errc> : public true_type {}; + +#include <future> + +int main() +{ + static_assert(std::is_error_code_enum<std::future_errc>::value, ""); +} diff --git a/test/std/thread/futures/futures.overview/launch.pass.cpp b/test/std/thread/futures/futures.overview/launch.pass.cpp new file mode 100644 index 0000000000000..da54f7ee67329 --- /dev/null +++ b/test/std/thread/futures/futures.overview/launch.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// enum class launch +// { +// async = 1, +// deferred = 2, +// any = async | deferred +// }; + +#include <future> +#include <cassert> + +int main() +{ +#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS + static_assert(static_cast<int>(std::launch::any) == + (static_cast<int>(std::launch::async) | static_cast<int>(std::launch::deferred)), ""); +#else + static_assert(std::launch::any == (std::launch::async | std::launch::deferred), ""); + static_assert(std::launch(0) == (std::launch::async & std::launch::deferred), ""); + static_assert(std::launch::any == (std::launch::async ^ std::launch::deferred), ""); + static_assert(std::launch::deferred == ~std::launch::async, ""); + std::launch x = std::launch::async; + x &= std::launch::deferred; + assert(x == std::launch(0)); + x = std::launch::async; + x |= std::launch::deferred; + assert(x == std::launch::any); + x ^= std::launch::deferred; + assert(x == std::launch::async); +#endif + static_assert(static_cast<int>(std::launch::async) == 1, ""); + static_assert(static_cast<int>(std::launch::deferred) == 2, ""); +} diff --git a/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp b/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp new file mode 100644 index 0000000000000..70a4e00b0d6af --- /dev/null +++ b/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// template <class Allocator> +// promise(allocator_arg_t, const Allocator& a); + +#include <future> +#include <cassert> + +#include "../test_allocator.h" +#include "min_allocator.h" + +int main() +{ + assert(test_alloc_base::count == 0); + { + std::promise<int> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 1); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); + { + std::promise<int&> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 1); + std::future<int&> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); + { + std::promise<void> p(std::allocator_arg, test_allocator<void>()); + assert(test_alloc_base::count == 1); + std::future<void> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); + // Test with a minimal allocator + { + std::promise<int> p(std::allocator_arg, bare_allocator<void>()); + std::future<int> f = p.get_future(); + assert(f.valid()); + } + { + std::promise<int&> p(std::allocator_arg, bare_allocator<void>()); + std::future<int&> f = p.get_future(); + assert(f.valid()); + } + { + std::promise<void> p(std::allocator_arg, bare_allocator<void>()); + std::future<void> f = p.get_future(); + assert(f.valid()); + } + // Test with a minimal allocator that returns class-type pointers + { + std::promise<int> p(std::allocator_arg, min_allocator<void>()); + std::future<int> f = p.get_future(); + assert(f.valid()); + } + { + std::promise<int&> p(std::allocator_arg, min_allocator<void>()); + std::future<int&> f = p.get_future(); + assert(f.valid()); + } + { + std::promise<void> p(std::allocator_arg, min_allocator<void>()); + std::future<void> f = p.get_future(); + assert(f.valid()); + } +} diff --git a/test/std/thread/futures/futures.promise/copy_assign.fail.cpp b/test/std/thread/futures/futures.promise/copy_assign.fail.cpp new file mode 100644 index 0000000000000..c08278122225c --- /dev/null +++ b/test/std/thread/futures/futures.promise/copy_assign.fail.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class promise<R> + +// promise& operator=(const promise& rhs) = delete; + +#include <future> +#include <cassert> + +#include "../test_allocator.h" + +int main() +{ + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 2); + p = p0; + assert(test_alloc_base::count == 1); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<int&> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int&> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 2); + p = p0; + assert(test_alloc_base::count == 1); + std::future<int&> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<void> p0(std::allocator_arg, test_allocator<void>()); + std::promise<void> p(std::allocator_arg, test_allocator<void>()); + assert(test_alloc_base::count == 2); + p = p0; + assert(test_alloc_base::count == 1); + std::future<void> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); +} diff --git a/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp b/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp new file mode 100644 index 0000000000000..36a3555aed468 --- /dev/null +++ b/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class promise<R> + +// promise(const promise&) = delete; + +#include <future> +#include <cassert> + +#include "../test_allocator.h" + +int main() +{ + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p(p0); + assert(test_alloc_base::count == 1); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<int&> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int&> p(p0); + assert(test_alloc_base::count == 1); + std::future<int&> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<void> p0(std::allocator_arg, test_allocator<void>()); + std::promise<void> p(p0); + assert(test_alloc_base::count == 1); + std::future<void> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); +} diff --git a/test/std/thread/futures/futures.promise/default.pass.cpp b/test/std/thread/futures/futures.promise/default.pass.cpp new file mode 100644 index 0000000000000..95c9657c633e5 --- /dev/null +++ b/test/std/thread/futures/futures.promise/default.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// promise(); + +#include <future> +#include <cassert> + +int main() +{ + { + std::promise<int> p; + std::future<int> f = p.get_future(); + assert(f.valid()); + } + { + std::promise<int&> p; + std::future<int&> f = p.get_future(); + assert(f.valid()); + } + { + std::promise<void> p; + std::future<void> f = p.get_future(); + assert(f.valid()); + } +} diff --git a/test/std/thread/futures/futures.promise/dtor.pass.cpp b/test/std/thread/futures/futures.promise/dtor.pass.cpp new file mode 100644 index 0000000000000..78912f12adb98 --- /dev/null +++ b/test/std/thread/futures/futures.promise/dtor.pass.cpp @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// ~promise(); + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int T; + std::future<T> f; + { + std::promise<T> p; + f = p.get_future(); + p.set_value(3); + } + assert(f.get() == 3); + } + { + typedef int T; + std::future<T> f; + { + std::promise<T> p; + f = p.get_future(); + } + try + { + T i = f.get(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::broken_promise)); + } + } + + { + typedef int& T; + int i = 4; + std::future<T> f; + { + std::promise<T> p; + f = p.get_future(); + p.set_value(i); + } + assert(&f.get() == &i); + } + { + typedef int& T; + std::future<T> f; + { + std::promise<T> p; + f = p.get_future(); + } + try + { + T i = f.get(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::broken_promise)); + } + } + + { + typedef void T; + std::future<T> f; + { + std::promise<T> p; + f = p.get_future(); + p.set_value(); + } + f.get(); + assert(true); + } + { + typedef void T; + std::future<T> f; + { + std::promise<T> p; + f = p.get_future(); + } + try + { + f.get(); + assert(false); + } + catch (const std::future_error& e) + { + // LWG 2056 changed the values of future_errc, so if we're using new + // headers with an old library the error codes won't line up. + // + // Note that this particular check only applies to promise<void> + // since the other specializations happen to be implemented in the + // header rather than the library. + assert( + e.code() == make_error_code(std::future_errc::broken_promise) || + e.code() == std::error_code(0, std::future_category())); + } + } +} diff --git a/test/std/thread/futures/futures.promise/get_future.pass.cpp b/test/std/thread/futures/futures.promise/get_future.pass.cpp new file mode 100644 index 0000000000000..a7d084ee78730 --- /dev/null +++ b/test/std/thread/futures/futures.promise/get_future.pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// future<R> get_future(); + +#include <future> +#include <cassert> + +int main() +{ + { + std::promise<double> p; + std::future<double> f = p.get_future(); + p.set_value(105.5); + assert(f.get() == 105.5); + } + { + std::promise<double> p; + std::future<double> f = p.get_future(); + try + { + f = p.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::future_already_retrieved)); + } + } + { + std::promise<double> p; + std::promise<double> p0 = std::move(p); + try + { + std::future<double> f = p.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + } +} diff --git a/test/std/thread/futures/futures.promise/move_assign.pass.cpp b/test/std/thread/futures/futures.promise/move_assign.pass.cpp new file mode 100644 index 0000000000000..c3097df74990a --- /dev/null +++ b/test/std/thread/futures/futures.promise/move_assign.pass.cpp @@ -0,0 +1,91 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// promise& operator=(promise&& rhs); + +#include <future> +#include <cassert> + +#include "../test_allocator.h" + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 2); + p = std::move(p0); + assert(test_alloc_base::count == 1); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<int&> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int&> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 2); + p = std::move(p0); + assert(test_alloc_base::count == 1); + std::future<int&> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<void> p0(std::allocator_arg, test_allocator<void>()); + std::promise<void> p(std::allocator_arg, test_allocator<void>()); + assert(test_alloc_base::count == 2); + p = std::move(p0); + assert(test_alloc_base::count == 1); + std::future<void> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.promise/move_ctor.pass.cpp b/test/std/thread/futures/futures.promise/move_ctor.pass.cpp new file mode 100644 index 0000000000000..eeec4fb15b956 --- /dev/null +++ b/test/std/thread/futures/futures.promise/move_ctor.pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// promise(promise&& rhs); + +#include <future> +#include <cassert> + +#include "../test_allocator.h" + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p(std::move(p0)); + assert(test_alloc_base::count == 1); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<int&> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int&> p(std::move(p0)); + assert(test_alloc_base::count == 1); + std::future<int&> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<void> p0(std::allocator_arg, test_allocator<void>()); + std::promise<void> p(std::move(p0)); + assert(test_alloc_base::count == 1); + std::future<void> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + try + { + f = p0.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.promise/set_exception.pass.cpp b/test/std/thread/futures/futures.promise/set_exception.pass.cpp new file mode 100644 index 0000000000000..51c05eb803cb7 --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_exception.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// void set_exception(exception_ptr p); + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int T; + std::promise<T> p; + std::future<T> f = p.get_future(); + p.set_exception(std::make_exception_ptr(3)); + try + { + f.get(); + assert(false); + } + catch (int i) + { + assert(i == 3); + } + try + { + p.set_exception(std::make_exception_ptr(3)); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); + } + } +} diff --git a/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp new file mode 100644 index 0000000000000..5e57692563d88 --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// void promise::set_exception_at_thread_exit(exception_ptr p); + +#include <future> +#include <cassert> + +void func(std::promise<int> p) +{ + const int i = 5; + p.set_exception_at_thread_exit(std::make_exception_ptr(3)); +} + +int main() +{ + { + typedef int T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func, std::move(p)).detach(); + try + { + f.get(); + assert(false); + } + catch (int i) + { + assert(i == 3); + } + } +} diff --git a/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp b/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp new file mode 100644 index 0000000000000..cdc37775012ce --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// void promise<R&>::set_value(R& r); + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int& T; + int i = 3; + std::promise<T> p; + std::future<T> f = p.get_future(); + p.set_value(i); + int& j = f.get(); + assert(j == 3); + ++i; + assert(j == 4); + try + { + p.set_value(i); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); + } + } +} diff --git a/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp new file mode 100644 index 0000000000000..18f87c596a005 --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// void promise<R&>::set_value_at_thread_exit(R& r); + +#include <future> +#include <memory> +#include <cassert> + +int i = 0; + +void func(std::promise<int&> p) +{ + p.set_value_at_thread_exit(i); + i = 4; +} + +int main() +{ + { + std::promise<int&> p; + std::future<int&> f = p.get_future(); + std::thread(func, std::move(p)).detach(); + assert(f.get() == 4); + } +} diff --git a/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp b/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp new file mode 100644 index 0000000000000..dab4bf7e9c832 --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// void promise::set_value(R&& r); + +#include <future> +#include <memory> +#include <cassert> + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +struct A +{ + A() {} + A(const A&) = delete; + A(A&&) {throw 9;} +}; + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef std::unique_ptr<int> T; + T i(new int(3)); + std::promise<T> p; + std::future<T> f = p.get_future(); + p.set_value(std::move(i)); + assert(*f.get() == 3); + try + { + p.set_value(std::move(i)); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); + } + } + { + typedef A T; + T i; + std::promise<T> p; + std::future<T> f = p.get_future(); + try + { + p.set_value(std::move(i)); + assert(false); + } + catch (int j) + { + assert(j == 9); + } + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp new file mode 100644 index 0000000000000..8f3b76865e2a8 --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// void promise::set_value_at_thread_exit(R&& r); + +#include <future> +#include <memory> +#include <cassert> + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +void func(std::promise<std::unique_ptr<int>> p) +{ + p.set_value_at_thread_exit(std::unique_ptr<int>(new int(5))); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + std::promise<std::unique_ptr<int>> p; + std::future<std::unique_ptr<int>> f = p.get_future(); + std::thread(func, std::move(p)).detach(); + assert(*f.get() == 5); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp new file mode 100644 index 0000000000000..ec50cc3102983 --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// void promise::set_value_at_thread_exit(const R& r); + +#include <future> +#include <cassert> + +void func(std::promise<int> p) +{ + const int i = 5; + p.set_value_at_thread_exit(i); +} + +int main() +{ + { + std::promise<int> p; + std::future<int> f = p.get_future(); + std::thread(func, std::move(p)).detach(); + assert(f.get() == 5); + } +} diff --git a/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp new file mode 100644 index 0000000000000..8c092084668dd --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// void promise<void>::set_value_at_thread_exit(); + +#include <future> +#include <memory> +#include <cassert> + +int i = 0; + +void func(std::promise<void> p) +{ + p.set_value_at_thread_exit(); + i = 1; +} + +int main() +{ + { + std::promise<void> p; + std::future<void> f = p.get_future(); + std::thread(func, std::move(p)).detach(); + f.get(); + assert(i == 1); + } +} diff --git a/test/std/thread/futures/futures.promise/set_value_const.pass.cpp b/test/std/thread/futures/futures.promise/set_value_const.pass.cpp new file mode 100644 index 0000000000000..6673f63075791 --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_value_const.pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// void promise::set_value(const R& r); + +#include <future> +#include <cassert> + +struct A +{ + A() {} + A(const A&) {throw 10;} +}; + +int main() +{ + { + typedef int T; + T i = 3; + std::promise<T> p; + std::future<T> f = p.get_future(); + p.set_value(i); + ++i; + assert(f.get() == 3); + --i; + try + { + p.set_value(i); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); + } + } + { + typedef A T; + T i; + std::promise<T> p; + std::future<T> f = p.get_future(); + try + { + p.set_value(i); + assert(false); + } + catch (int j) + { + assert(j == 10); + } + } +} diff --git a/test/std/thread/futures/futures.promise/set_value_void.pass.cpp b/test/std/thread/futures/futures.promise/set_value_void.pass.cpp new file mode 100644 index 0000000000000..5012e0bfe5fd7 --- /dev/null +++ b/test/std/thread/futures/futures.promise/set_value_void.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// void promise<void>::set_value(); + +#include <future> +#include <cassert> + +int main() +{ + { + typedef void T; + std::promise<T> p; + std::future<T> f = p.get_future(); + p.set_value(); + f.get(); + try + { + p.set_value(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); + } + } +} diff --git a/test/std/thread/futures/futures.promise/swap.pass.cpp b/test/std/thread/futures/futures.promise/swap.pass.cpp new file mode 100644 index 0000000000000..1ed3e646813c3 --- /dev/null +++ b/test/std/thread/futures/futures.promise/swap.pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// void swap(promise& other); + +// template <class R> void swap(promise<R>& x, promise<R>& y); + +#include <future> +#include <cassert> + +#include "../test_allocator.h" + +int main() +{ + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 2); + p.swap(p0); + assert(test_alloc_base::count == 2); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 2); + assert(f.valid()); + f = p0.get_future(); + assert(f.valid()); + assert(test_alloc_base::count == 2); + } + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 2); + swap(p, p0); + assert(test_alloc_base::count == 2); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 2); + assert(f.valid()); + f = p0.get_future(); + assert(f.valid()); + assert(test_alloc_base::count == 2); + } + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p; + assert(test_alloc_base::count == 1); + p.swap(p0); + assert(test_alloc_base::count == 1); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + f = p0.get_future(); + assert(f.valid()); + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); + { + std::promise<int> p0(std::allocator_arg, test_allocator<int>()); + std::promise<int> p; + assert(test_alloc_base::count == 1); + swap(p, p0); + assert(test_alloc_base::count == 1); + std::future<int> f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + f = p0.get_future(); + assert(f.valid()); + assert(test_alloc_base::count == 1); + } + assert(test_alloc_base::count == 0); +} diff --git a/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp b/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp new file mode 100644 index 0000000000000..458826e956e12 --- /dev/null +++ b/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class promise<R> + +// template <class R, class Alloc> +// struct uses_allocator<promise<R>, Alloc> +// : true_type { }; + +#include <future> +#include "../test_allocator.h" + +int main() +{ + static_assert((std::uses_allocator<std::promise<int>, test_allocator<int> >::value), ""); + static_assert((std::uses_allocator<std::promise<int&>, test_allocator<int> >::value), ""); + static_assert((std::uses_allocator<std::promise<void>, test_allocator<void> >::value), ""); +} diff --git a/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp b/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp new file mode 100644 index 0000000000000..b23ba196ec30e --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class shared_future<R> + +// shared_future& operator=(const shared_future& rhs); + +#include <future> +#include <cassert> + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef int T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f; + f = f0; + assert(f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::shared_future<T> f0; + std::shared_future<T> f; + f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f; + f = f0; + assert(f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::shared_future<T> f0; + std::shared_future<T> f; + f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f; + f = f0; + assert(f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::shared_future<T> f0; + std::shared_future<T> f; + f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp b/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp new file mode 100644 index 0000000000000..425d1f9be96ff --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class shared_future<R> + +// shared_future(const shared_future& rhs); + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f = f0; + assert(f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::shared_future<T> f0; + std::shared_future<T> f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f = f0; + assert(f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::shared_future<T> f0; + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f = f0; + assert(f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::shared_future<T> f0; + std::shared_future<T> f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } +} diff --git a/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp b/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp new file mode 100644 index 0000000000000..3a78b80f0634a --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class shared_future<R> + +// shared_future(future<R>&& rhs); + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::future<T> f0; + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::future<T> f0; + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::future<T> f0; + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } +} diff --git a/test/std/thread/futures/futures.shared_future/default.pass.cpp b/test/std/thread/futures/futures.shared_future/default.pass.cpp new file mode 100644 index 0000000000000..92927f5f69330 --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/default.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class shared_future<R> + +// shared_future(); + +#include <future> +#include <cassert> + +int main() +{ + { + std::shared_future<int> f; + assert(!f.valid()); + } + { + std::shared_future<int&> f; + assert(!f.valid()); + } + { + std::shared_future<void> f; + assert(!f.valid()); + } +} diff --git a/test/std/thread/futures/futures.shared_future/dtor.pass.cpp b/test/std/thread/futures/futures.shared_future/dtor.pass.cpp new file mode 100644 index 0000000000000..baa89cb12b1c4 --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/dtor.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class shared_future<R> + +// ~shared_future(); + +#include <future> +#include <cassert> + +#include "../test_allocator.h" + +int main() +{ + assert(test_alloc_base::count == 0); + { + typedef int T; + std::shared_future<T> f; + { + std::promise<T> p(std::allocator_arg, test_allocator<T>()); + assert(test_alloc_base::count == 1); + f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); + { + typedef int& T; + std::shared_future<T> f; + { + std::promise<T> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 1); + f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); + { + typedef void T; + std::shared_future<T> f; + { + std::promise<T> p(std::allocator_arg, test_allocator<T>()); + assert(test_alloc_base::count == 1); + f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); +} diff --git a/test/std/thread/futures/futures.shared_future/get.pass.cpp b/test/std/thread/futures/futures.shared_future/get.pass.cpp new file mode 100644 index 0000000000000..c5ee234b127f8 --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/get.pass.cpp @@ -0,0 +1,145 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class shared_future<R> + +// const R& shared_future::get(); +// R& shared_future<R&>::get(); +// void shared_future<void>::get(); + +#include <future> +#include <cassert> + +void func1(std::promise<int> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(3); +} + +void func2(std::promise<int> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_exception(std::make_exception_ptr(3)); +} + +int j = 0; + +void func3(std::promise<int&> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + j = 5; + p.set_value(j); +} + +void func4(std::promise<int&> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_exception(std::make_exception_ptr(3.5)); +} + +void func5(std::promise<void> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(); +} + +void func6(std::promise<void> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_exception(std::make_exception_ptr('c')); +} + +int main() +{ + { + typedef int T; + { + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + assert(f.get() == 3); + assert(f.valid()); + } + { + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func2, std::move(p)).detach(); + try + { + assert(f.valid()); + assert(f.get() == 3); + assert(false); + } + catch (int i) + { + assert(i == 3); + } + assert(f.valid()); + } + } + { + typedef int& T; + { + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + assert(f.get() == 5); + assert(f.valid()); + } + { + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func4, std::move(p)).detach(); + try + { + assert(f.valid()); + assert(f.get() == 3); + assert(false); + } + catch (double i) + { + assert(i == 3.5); + } + assert(f.valid()); + } + } + { + typedef void T; + { + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + f.get(); + assert(f.valid()); + } + { + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func6, std::move(p)).detach(); + try + { + assert(f.valid()); + f.get(); + assert(false); + } + catch (char i) + { + assert(i == 'c'); + } + assert(f.valid()); + } + } +} diff --git a/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp b/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp new file mode 100644 index 0000000000000..6b58f41c90855 --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class shared_future<R> + +// shared_future& operator=(shared_future&& rhs); + +#include <future> +#include <cassert> + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef int T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::shared_future<T> f0; + std::shared_future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::shared_future<T> f0; + std::shared_future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::shared_future<T> f0; + std::shared_future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp b/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp new file mode 100644 index 0000000000000..32b8fd77c672b --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class shared_future<R> + +// shared_future(shared_future&& rhs); + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::shared_future<T> f0; + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::shared_future<T> f0; + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::shared_future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::shared_future<T> f0; + std::shared_future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } +} diff --git a/test/std/thread/futures/futures.shared_future/wait.pass.cpp b/test/std/thread/futures/futures.shared_future/wait.pass.cpp new file mode 100644 index 0000000000000..4293fcab35643 --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/wait.pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class shared_future<R> + +// void wait() const; + +#include <future> +#include <cassert> + +void func1(std::promise<int> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(3); +} + +int j = 0; + +void func3(std::promise<int&> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + j = 5; + p.set_value(j); +} + +void func5(std::promise<void> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(); +} + +int main() +{ + typedef std::chrono::high_resolution_clock Clock; + typedef std::chrono::duration<double, std::milli> ms; + { + typedef int T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + f.wait(); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef int& T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + f.wait(); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef void T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + f.wait(); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } +} diff --git a/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp b/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp new file mode 100644 index 0000000000000..e5a4754e38ad5 --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class shared_future<R> + +// template <class Rep, class Period> +// future_status +// wait_for(const chrono::duration<Rep, Period>& rel_time) const; + +#include <future> +#include <cassert> + +typedef std::chrono::milliseconds ms; + +void func1(std::promise<int> p) +{ + std::this_thread::sleep_for(ms(500)); + p.set_value(3); +} + +int j = 0; + +void func3(std::promise<int&> p) +{ + std::this_thread::sleep_for(ms(500)); + j = 5; + p.set_value(j); +} + +void func5(std::promise<void> p) +{ + std::this_thread::sleep_for(ms(500)); + p.set_value(); +} + +int main() +{ + typedef std::chrono::high_resolution_clock Clock; + { + typedef int T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::timeout); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef int& T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::timeout); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef void T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::timeout); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } +} diff --git a/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp b/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp new file mode 100644 index 0000000000000..6a6aeba7759e3 --- /dev/null +++ b/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp @@ -0,0 +1,129 @@ + //===----------------------------------------------------------------------===// + // + // The LLVM Compiler Infrastructure + // + // This file is dual licensed under the MIT and the University of Illinois Open + // Source Licenses. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // UNSUPPORTED: libcpp-has-no-threads + + // <future> + + // class shared_future<R> + + // template <class Clock, class Duration> + // future_status + // wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; + + #include <future> + #include <atomic> + #include <cassert> + + enum class WorkerThreadState { Uninitialized, AllowedToRun, Exiting }; + typedef std::chrono::milliseconds ms; + + std::atomic<WorkerThreadState> thread_state(WorkerThreadState::Uninitialized); + + void set_worker_thread_state(WorkerThreadState state) + { + thread_state.store(state, std::memory_order_relaxed); + } + + void wait_for_worker_thread_state(WorkerThreadState state) + { + while (thread_state.load(std::memory_order_relaxed) != state); + } + + void func1(std::promise<int> p) + { + wait_for_worker_thread_state(WorkerThreadState::AllowedToRun); + p.set_value(3); + set_worker_thread_state(WorkerThreadState::Exiting); + } + + int j = 0; + + void func3(std::promise<int&> p) + { + wait_for_worker_thread_state(WorkerThreadState::AllowedToRun); + j = 5; + p.set_value(j); + set_worker_thread_state(WorkerThreadState::Exiting); + } + + void func5(std::promise<void> p) + { + wait_for_worker_thread_state(WorkerThreadState::AllowedToRun); + p.set_value(); + set_worker_thread_state(WorkerThreadState::Exiting); + } + + int main() + { + typedef std::chrono::high_resolution_clock Clock; + { + typedef int T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout); + assert(f.valid()); + + // allow the worker thread to produce the result and wait until the worker is done + set_worker_thread_state(WorkerThreadState::AllowedToRun); + wait_for_worker_thread_state(WorkerThreadState::Exiting); + + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef int& T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout); + assert(f.valid()); + + // allow the worker thread to produce the result and wait until the worker is done + set_worker_thread_state(WorkerThreadState::AllowedToRun); + wait_for_worker_thread_state(WorkerThreadState::Exiting); + + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef void T; + std::promise<T> p; + std::shared_future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout); + assert(f.valid()); + + // allow the worker thread to produce the result and wait until the worker is done + set_worker_thread_state(WorkerThreadState::AllowedToRun); + wait_for_worker_thread_state(WorkerThreadState::Exiting); + + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + } diff --git a/test/std/thread/futures/futures.state/nothing_to_do.pass.cpp b/test/std/thread/futures/futures.state/nothing_to_do.pass.cpp new file mode 100644 index 0000000000000..9a59227abdd98 --- /dev/null +++ b/test/std/thread/futures/futures.state/nothing_to_do.pass.cpp @@ -0,0 +1,13 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main() +{ +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp new file mode 100644 index 0000000000000..70ea0ad31feda --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// packaged_task& operator=(packaged_task&) = delete; + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p0(A(5)); + std::packaged_task<double(int, char)> p; + p = p0; + assert(!p0.valid()); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p0; + std::packaged_task<double(int, char)> p; + p = p0; + assert(!p0.valid()); + assert(!p.valid()); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp new file mode 100644 index 0000000000000..18786f4eb7a26 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// packaged_task& operator=(packaged_task&& other); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p0(A(5)); + std::packaged_task<double(int, char)> p; + p = std::move(p0); + assert(!p0.valid()); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p0; + std::packaged_task<double(int, char)> p; + p = std::move(p0); + assert(!p0.valid()); + assert(!p.valid()); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp new file mode 100644 index 0000000000000..45048b747f7a4 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class packaged_task<R(ArgTypes...)> +// template <class F> +// packaged_task(F&& f); +// These constructors shall not participate in overload resolution if +// decay<F>::type is the same type as std::packaged_task<R(ArgTypes...)>. + +#include <future> +#include <cassert> + +struct A {}; +typedef std::packaged_task<A(int, char)> PT; +typedef volatile std::packaged_task<A(int, char)> VPT; + + +int main() +{ + PT p { VPT{} }; +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp new file mode 100644 index 0000000000000..e4df4ec225e70 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class packaged_task<R(ArgTypes...)> +// template <class F, class Allocator> +// packaged_task(allocator_arg_t, const Allocator& a, F&& f); +// These constructors shall not participate in overload resolution if +// decay<F>::type is the same type as std::packaged_task<R(ArgTypes...)>. + +#include <future> +#include <cassert> + +#include "../../test_allocator.h" + +struct A {}; +typedef std::packaged_task<A(int, char)> PT; +typedef volatile std::packaged_task<A(int, char)> VPT; + +int main() +{ + PT p { std::allocator_arg_t{}, test_allocator<A>{}, VPT {}}; +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp new file mode 100644 index 0000000000000..9884c49a6dc7e --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// packaged_task(packaged_task&) = delete; + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p0(A(5)); + std::packaged_task<double(int, char)> p(p0); + assert(!p0.valid()); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p0; + std::packaged_task<double(int, char)> p(p0); + assert(!p0.valid()); + assert(!p.valid()); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp new file mode 100644 index 0000000000000..76904962a778d --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// packaged_task(); + +#include <future> +#include <cassert> + +struct A {}; + +int main() +{ + std::packaged_task<A(int, char)> p; + assert(!p.valid()); +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp new file mode 100644 index 0000000000000..2eee2cbc2d509 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// template <class F> +// explicit packaged_task(F&& f); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + static int n_moves; + static int n_copies; + + explicit A(long i) : data_(i) {} + A(A&& a) : data_(a.data_) {++n_moves; a.data_ = -1;} + A(const A& a) : data_(a.data_) {++n_copies;} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int A::n_moves = 0; +int A::n_copies = 0; + +int func(int i) { return i; } + +int main() +{ + { + std::packaged_task<double(int, char)> p(A(5)); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + assert(A::n_copies == 0); + assert(A::n_moves > 0); + } + A::n_copies = 0; + A::n_copies = 0; + { + A a(5); + std::packaged_task<double(int, char)> p(a); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + assert(A::n_copies > 0); + assert(A::n_moves > 0); + } + { + std::packaged_task<int(int)> p(&func); + assert(p.valid()); + std::future<int> f = p.get_future(); + p(4); + assert(f.get() == 4); + } + { + std::packaged_task<int(int)> p(func); + assert(p.valid()); + std::future<int> f = p.get_future(); + p(4); + assert(f.get() == 4); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp new file mode 100644 index 0000000000000..3aac2b26bfc1d --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp @@ -0,0 +1,124 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// template <class F, class Allocator> +// explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f); + +#include <future> +#include <cassert> + +#include "../../test_allocator.h" +#include "min_allocator.h" + +class A +{ + long data_; + +public: + static int n_moves; + static int n_copies; + + explicit A(long i) : data_(i) {} + A(A&& a) : data_(a.data_) {++n_moves; a.data_ = -1;} + A(const A& a) : data_(a.data_) {++n_copies;} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int A::n_moves = 0; +int A::n_copies = 0; + +int func(int i) { return i; } + +int main() +{ + { + std::packaged_task<double(int, char)> p(std::allocator_arg, + test_allocator<A>(), A(5)); + assert(test_alloc_base::count > 0); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + assert(A::n_copies == 0); + assert(A::n_moves > 0); + } + assert(test_alloc_base::count == 0); + A::n_copies = 0; + A::n_moves = 0; + { + A a(5); + std::packaged_task<double(int, char)> p(std::allocator_arg, + test_allocator<A>(), a); + assert(test_alloc_base::count > 0); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + assert(A::n_copies > 0); + assert(A::n_moves > 0); + } + assert(test_alloc_base::count == 0); + A::n_copies = 0; + A::n_moves = 0; + { + A a(5); + std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(), &func); + assert(test_alloc_base::count > 0); + assert(p.valid()); + std::future<int> f = p.get_future(); + p(4); + assert(f.get() == 4); + } + assert(test_alloc_base::count == 0); + A::n_copies = 0; + A::n_moves = 0; + { + A a(5); + std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(), func); + assert(test_alloc_base::count > 0); + assert(p.valid()); + std::future<int> f = p.get_future(); + p(4); + assert(f.get() == 4); + } + assert(test_alloc_base::count == 0); + A::n_copies = 0; + A::n_moves = 0; + { + std::packaged_task<double(int, char)> p(std::allocator_arg, + bare_allocator<void>(), A(5)); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + assert(A::n_copies == 0); + assert(A::n_moves > 0); + } + A::n_copies = 0; + A::n_moves = 0; + { + std::packaged_task<double(int, char)> p(std::allocator_arg, + min_allocator<void>(), A(5)); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + assert(A::n_copies == 0); + assert(A::n_moves > 0); + } + A::n_copies = 0; + A::n_moves = 0; +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp new file mode 100644 index 0000000000000..88f0722817502 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// packaged_task(packaged_task&& other); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p0(A(5)); + std::packaged_task<double(int, char)> p = std::move(p0); + assert(!p0.valid()); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p0; + std::packaged_task<double(int, char)> p = std::move(p0); + assert(!p0.valid()); + assert(!p.valid()); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp new file mode 100644 index 0000000000000..e24232d1b2276 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// ~packaged_task(); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +void func(std::packaged_task<double(int, char)> p) +{ +} + +void func2(std::packaged_task<double(int, char)> p) +{ + p(3, 'a'); +} + +int main() +{ + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread(func, std::move(p)).detach(); + try + { + double i = f.get(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::broken_promise)); + } + } + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread(func2, std::move(p)).detach(); + assert(f.get() == 105.0); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp new file mode 100644 index 0000000000000..13b5db110668e --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// future<R> get_future(); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + try + { + f = p.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::future_already_retrieved)); + } + } + { + std::packaged_task<double(int, char)> p; + try + { + std::future<double> f = p.get_future(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp new file mode 100644 index 0000000000000..61a6a4f87965c --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// void make_ready_at_thread_exit(ArgTypes... args); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const + { + if (j == 'z') + throw A(6); + return data_ + i + j; + } +}; + +void func0(std::packaged_task<double(int, char)> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.make_ready_at_thread_exit(3, 'a'); +} + +void func1(std::packaged_task<double(int, char)> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.make_ready_at_thread_exit(3, 'z'); +} + +void func2(std::packaged_task<double(int, char)> p) +{ + p.make_ready_at_thread_exit(3, 'a'); + try + { + p.make_ready_at_thread_exit(3, 'c'); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); + } +} + +void func3(std::packaged_task<double(int, char)> p) +{ + try + { + p.make_ready_at_thread_exit(3, 'a'); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } +} + +int main() +{ + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread(func0, std::move(p)).detach(); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + try + { + f.get(); + assert(false); + } + catch (const A& e) + { + assert(e(3, 'a') == 106); + } + } + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread(func2, std::move(p)).detach(); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p; + std::thread t(func3, std::move(p)); + t.join(); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp new file mode 100644 index 0000000000000..2a09353b1e63b --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp @@ -0,0 +1,107 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// void operator()(ArgTypes... args); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const + { + if (j == 'z') + throw A(6); + return data_ + i + j; + } +}; + +void func0(std::packaged_task<double(int, char)> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p(3, 'a'); +} + +void func1(std::packaged_task<double(int, char)> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p(3, 'z'); +} + +void func2(std::packaged_task<double(int, char)> p) +{ + p(3, 'a'); + try + { + p(3, 'c'); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); + } +} + +void func3(std::packaged_task<double(int, char)> p) +{ + try + { + p(3, 'a'); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } +} + +int main() +{ + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread(func0, std::move(p)).detach(); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + try + { + f.get(); + assert(false); + } + catch (const A& e) + { + assert(e(3, 'a') == 106); + } + } + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + std::thread t(func2, std::move(p)); + assert(f.get() == 105.0); + t.join(); + } + { + std::packaged_task<double(int, char)> p; + std::thread t(func3, std::move(p)); + t.join(); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp new file mode 100644 index 0000000000000..9d38d9b409c09 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// void reset(); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const + { + if (j == 'z') + throw A(6); + return data_ + i + j; + } +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p(A(5)); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + p.reset(); + p(4, 'a'); + f = p.get_future(); + assert(f.get() == 106.0); + } + { + std::packaged_task<double(int, char)> p; + try + { + p.reset(); + assert(false); + } + catch (const std::future_error& e) + { + assert(e.code() == make_error_code(std::future_errc::no_state)); + } + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp new file mode 100644 index 0000000000000..33763bef0d0f8 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// void swap(packaged_task& other); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p0(A(5)); + std::packaged_task<double(int, char)> p; + p.swap(p0); + assert(!p0.valid()); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p0; + std::packaged_task<double(int, char)> p; + p.swap(p0); + assert(!p0.valid()); + assert(!p.valid()); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp new file mode 100644 index 0000000000000..668732b9b24a1 --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// template <class R, class... ArgTypes> +// void +// swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y); + +#include <future> +#include <cassert> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + std::packaged_task<double(int, char)> p0(A(5)); + std::packaged_task<double(int, char)> p; + swap(p, p0); + assert(!p0.valid()); + assert(p.valid()); + std::future<double> f = p.get_future(); + p(3, 'a'); + assert(f.get() == 105.0); + } + { + std::packaged_task<double(int, char)> p0; + std::packaged_task<double(int, char)> p; + swap(p, p0); + assert(!p0.valid()); + assert(!p.valid()); + } +} diff --git a/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp new file mode 100644 index 0000000000000..986f71e29a46d --- /dev/null +++ b/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class packaged_task<R(ArgTypes...)> + +// template <class Callable, class Alloc> +// struct uses_allocator<packaged_task<Callable>, Alloc> +// : true_type { }; + +#include <future> +#include "../../test_allocator.h" + +int main() +{ + static_assert((std::uses_allocator<std::packaged_task<double(int, char)>, test_allocator<int> >::value), ""); +} diff --git a/test/std/thread/futures/futures.tas/types.pass.cpp b/test/std/thread/futures/futures.tas/types.pass.cpp new file mode 100644 index 0000000000000..dd1724ddbda5c --- /dev/null +++ b/test/std/thread/futures/futures.tas/types.pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// template<class R, class... ArgTypes> +// class packaged_task<R(ArgTypes...)> +// { +// public: +// typedef R result_type; + +#include <future> +#include <type_traits> + +struct A {}; + +int main() +{ + static_assert((std::is_same<std::packaged_task<A(int, char)>::result_type, A>::value), ""); +} diff --git a/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp b/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp new file mode 100644 index 0000000000000..ebdcbf98d996d --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class future<R> + +// future& operator=(const future&) = delete; + +#include <future> +#include <cassert> + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef int T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f; + f = f0; + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::future<T> f0; + std::future<T> f; + f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f; + f = f0; + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::future<T> f0; + std::future<T> f; + f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f; + f = f0; + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::future<T> f0; + std::future<T> f; + f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp b/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp new file mode 100644 index 0000000000000..8d43294edc263 --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <future> + +// class future<R> + +// future(const future&) = delete; + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f = f0; + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::future<T> f0; + std::future<T> f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f = f0; + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::future<T> f0; + std::future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f = f0; + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::future<T> f0; + std::future<T> f = f0; + assert(!f0.valid()); + assert(!f.valid()); + } +} diff --git a/test/std/thread/futures/futures.unique_future/default.pass.cpp b/test/std/thread/futures/futures.unique_future/default.pass.cpp new file mode 100644 index 0000000000000..84cb84650dcdb --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/default.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class future<R> + +// future(); + +#include <future> +#include <cassert> + +int main() +{ + { + std::future<int> f; + assert(!f.valid()); + } + { + std::future<int&> f; + assert(!f.valid()); + } + { + std::future<void> f; + assert(!f.valid()); + } +} diff --git a/test/std/thread/futures/futures.unique_future/dtor.pass.cpp b/test/std/thread/futures/futures.unique_future/dtor.pass.cpp new file mode 100644 index 0000000000000..5e9697bb939b9 --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/dtor.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class future<R> + +// ~future(); + +#include <future> +#include <cassert> + +#include "../test_allocator.h" + +int main() +{ + assert(test_alloc_base::count == 0); + { + typedef int T; + std::future<T> f; + { + std::promise<T> p(std::allocator_arg, test_allocator<T>()); + assert(test_alloc_base::count == 1); + f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); + { + typedef int& T; + std::future<T> f; + { + std::promise<T> p(std::allocator_arg, test_allocator<int>()); + assert(test_alloc_base::count == 1); + f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); + { + typedef void T; + std::future<T> f; + { + std::promise<T> p(std::allocator_arg, test_allocator<T>()); + assert(test_alloc_base::count == 1); + f = p.get_future(); + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 1); + assert(f.valid()); + } + assert(test_alloc_base::count == 0); +} diff --git a/test/std/thread/futures/futures.unique_future/get.pass.cpp b/test/std/thread/futures/futures.unique_future/get.pass.cpp new file mode 100644 index 0000000000000..758e38a7dae97 --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/get.pass.cpp @@ -0,0 +1,145 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class future<R> + +// R future::get(); +// R& future<R&>::get(); +// void future<void>::get(); + +#include <future> +#include <cassert> + +void func1(std::promise<int> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(3); +} + +void func2(std::promise<int> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_exception(std::make_exception_ptr(3)); +} + +int j = 0; + +void func3(std::promise<int&> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + j = 5; + p.set_value(j); +} + +void func4(std::promise<int&> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_exception(std::make_exception_ptr(3.5)); +} + +void func5(std::promise<void> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(); +} + +void func6(std::promise<void> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_exception(std::make_exception_ptr('c')); +} + +int main() +{ + { + typedef int T; + { + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + assert(f.get() == 3); + assert(!f.valid()); + } + { + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func2, std::move(p)).detach(); + try + { + assert(f.valid()); + assert(f.get() == 3); + assert(false); + } + catch (int i) + { + assert(i == 3); + } + assert(!f.valid()); + } + } + { + typedef int& T; + { + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + assert(f.get() == 5); + assert(!f.valid()); + } + { + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func4, std::move(p)).detach(); + try + { + assert(f.valid()); + assert(f.get() == 3); + assert(false); + } + catch (double i) + { + assert(i == 3.5); + } + assert(!f.valid()); + } + } + { + typedef void T; + { + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + f.get(); + assert(!f.valid()); + } + { + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func6, std::move(p)).detach(); + try + { + assert(f.valid()); + f.get(); + assert(false); + } + catch (char i) + { + assert(i == 'c'); + } + assert(!f.valid()); + } + } +} diff --git a/test/std/thread/futures/futures.unique_future/move_assign.pass.cpp b/test/std/thread/futures/futures.unique_future/move_assign.pass.cpp new file mode 100644 index 0000000000000..8d38b81f0cdad --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/move_assign.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class future<R> + +// future& operator=(future&& rhs); + +#include <future> +#include <cassert> + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef int T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::future<T> f0; + std::future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::future<T> f0; + std::future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::future<T> f0; + std::future<T> f; + f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.unique_future/move_ctor.pass.cpp b/test/std/thread/futures/futures.unique_future/move_ctor.pass.cpp new file mode 100644 index 0000000000000..e12c920886fac --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/move_ctor.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class future<R> + +// future(future&& rhs); + +#include <future> +#include <cassert> + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef int T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::future<T> f0; + std::future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::future<T> f0; + std::future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::future<T> f = std::move(f0); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::future<T> f0; + std::future<T> f = std::move(f0); + assert(!f0.valid()); + assert(!f.valid()); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/std/thread/futures/futures.unique_future/share.pass.cpp b/test/std/thread/futures/futures.unique_future/share.pass.cpp new file mode 100644 index 0000000000000..794b5ce38feba --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/share.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class future<R> + +// shared_future<R> share() &&; + +#include <future> +#include <cassert> + +int main() +{ + { + typedef int T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0.share()); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int T; + std::future<T> f0; + std::shared_future<T> f = std::move(f0.share()); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0.share()); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef int& T; + std::future<T> f0; + std::shared_future<T> f = std::move(f0.share()); + assert(!f0.valid()); + assert(!f.valid()); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f0 = p.get_future(); + std::shared_future<T> f = std::move(f0.share()); + assert(!f0.valid()); + assert(f.valid()); + } + { + typedef void T; + std::future<T> f0; + std::shared_future<T> f = std::move(f0.share()); + assert(!f0.valid()); + assert(!f.valid()); + } +} diff --git a/test/std/thread/futures/futures.unique_future/wait.pass.cpp b/test/std/thread/futures/futures.unique_future/wait.pass.cpp new file mode 100644 index 0000000000000..e10d37cf80646 --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/wait.pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class future<R> + +// void wait() const; + +#include <future> +#include <cassert> + +void func1(std::promise<int> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(3); +} + +int j = 0; + +void func3(std::promise<int&> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + j = 5; + p.set_value(j); +} + +void func5(std::promise<void> p) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + p.set_value(); +} + +int main() +{ + typedef std::chrono::high_resolution_clock Clock; + typedef std::chrono::duration<double, std::milli> ms; + { + typedef int T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + f.wait(); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + f.wait(); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + f.wait(); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } +} diff --git a/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp b/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp new file mode 100644 index 0000000000000..0a381d9ca2f0d --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +// class future<R> + +// template <class Rep, class Period> +// future_status +// wait_for(const chrono::duration<Rep, Period>& rel_time) const; + +#include <future> +#include <cassert> + +typedef std::chrono::milliseconds ms; + +void func1(std::promise<int> p) +{ + std::this_thread::sleep_for(ms(500)); + p.set_value(3); +} + +int j = 0; + +void func3(std::promise<int&> p) +{ + std::this_thread::sleep_for(ms(500)); + j = 5; + p.set_value(j); +} + +void func5(std::promise<void> p) +{ + std::this_thread::sleep_for(ms(500)); + p.set_value(); +} + +int main() +{ + typedef std::chrono::high_resolution_clock Clock; + { + typedef int T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::timeout); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(50)); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::timeout); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(50)); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::timeout); + assert(f.valid()); + assert(f.wait_for(ms(300)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(50)); + } +} diff --git a/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp b/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp new file mode 100644 index 0000000000000..d5865b9b9dcf3 --- /dev/null +++ b/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp @@ -0,0 +1,129 @@ + //===----------------------------------------------------------------------===// + // + // The LLVM Compiler Infrastructure + // + // This file is dual licensed under the MIT and the University of Illinois Open + // Source Licenses. See LICENSE.TXT for details. + // + //===----------------------------------------------------------------------===// + // + // UNSUPPORTED: libcpp-has-no-threads + + // <future> + + // class future<R> + + // template <class Clock, class Duration> + // future_status + // wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; + + #include <future> + #include <atomic> + #include <cassert> + + enum class WorkerThreadState { Uninitialized, AllowedToRun, Exiting }; + typedef std::chrono::milliseconds ms; + + std::atomic<WorkerThreadState> thread_state(WorkerThreadState::Uninitialized); + + void set_worker_thread_state(WorkerThreadState state) + { + thread_state.store(state, std::memory_order_relaxed); + } + + void wait_for_worker_thread_state(WorkerThreadState state) + { + while (thread_state.load(std::memory_order_relaxed) != state); + } + + void func1(std::promise<int> p) + { + wait_for_worker_thread_state(WorkerThreadState::AllowedToRun); + p.set_value(3); + set_worker_thread_state(WorkerThreadState::Exiting); + } + + int j = 0; + + void func3(std::promise<int&> p) + { + wait_for_worker_thread_state(WorkerThreadState::AllowedToRun); + j = 5; + p.set_value(j); + set_worker_thread_state(WorkerThreadState::Exiting); + } + + void func5(std::promise<void> p) + { + wait_for_worker_thread_state(WorkerThreadState::AllowedToRun); + p.set_value(); + set_worker_thread_state(WorkerThreadState::Exiting); + } + + int main() + { + typedef std::chrono::high_resolution_clock Clock; + { + typedef int T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func1, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout); + assert(f.valid()); + + // allow the worker thread to produce the result and wait until the worker is done + set_worker_thread_state(WorkerThreadState::AllowedToRun); + wait_for_worker_thread_state(WorkerThreadState::Exiting); + + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef int& T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func3, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout); + assert(f.valid()); + + // allow the worker thread to produce the result and wait until the worker is done + set_worker_thread_state(WorkerThreadState::AllowedToRun); + wait_for_worker_thread_state(WorkerThreadState::Exiting); + + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + { + typedef void T; + std::promise<T> p; + std::future<T> f = p.get_future(); + std::thread(func5, std::move(p)).detach(); + assert(f.valid()); + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout); + assert(f.valid()); + + // allow the worker thread to produce the result and wait until the worker is done + set_worker_thread_state(WorkerThreadState::AllowedToRun); + wait_for_worker_thread_state(WorkerThreadState::Exiting); + + assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready); + assert(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + assert(f.valid()); + assert(t1-t0 < ms(5)); + } + } diff --git a/test/std/thread/futures/test_allocator.h b/test/std/thread/futures/test_allocator.h new file mode 100644 index 0000000000000..50072909fa4e0 --- /dev/null +++ b/test/std/thread/futures/test_allocator.h @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef TEST_ALLOCATOR_H +#define TEST_ALLOCATOR_H + +#include <cstddef> +#include <type_traits> +#include <utility> +#include <cstdlib> +#include <new> +#include <climits> + +class test_alloc_base +{ +public: + static int count; +public: + static int throw_after; +}; + +int test_alloc_base::count = 0; +int test_alloc_base::throw_after = INT_MAX; + +template <class T> +class test_allocator + : public test_alloc_base +{ + int data_; + + template <class U> friend class test_allocator; +public: + + typedef unsigned size_type; + typedef int difference_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef typename std::add_lvalue_reference<value_type>::type reference; + typedef typename std::add_lvalue_reference<const value_type>::type const_reference; + + template <class U> struct rebind {typedef test_allocator<U> other;}; + + test_allocator() throw() : data_(-1) {} + explicit test_allocator(int i) throw() : data_(i) {} + test_allocator(const test_allocator& a) throw() + : data_(a.data_) {} + template <class U> test_allocator(const test_allocator<U>& a) throw() + : data_(a.data_) {} + ~test_allocator() throw() {data_ = 0;} + pointer address(reference x) const {return &x;} + const_pointer address(const_reference x) const {return &x;} + pointer allocate(size_type n, const void* = 0) + { + if (count >= throw_after) { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw std::bad_alloc(); +#else + std::terminate(); +#endif + } + ++count; + return (pointer)std::malloc(n * sizeof(T)); + } + void deallocate(pointer p, size_type n) + {--count; std::free(p);} + size_type max_size() const throw() + {return UINT_MAX / sizeof(T);} + void construct(pointer p, const T& val) + {::new(p) T(val);} +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + void construct(pointer p, T&& val) + {::new(p) T(std::move(val));} +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + void destroy(pointer p) {p->~T();} + + friend bool operator==(const test_allocator& x, const test_allocator& y) + {return x.data_ == y.data_;} + friend bool operator!=(const test_allocator& x, const test_allocator& y) + {return !(x == y);} +}; + +template <> +class test_allocator<void> + : public test_alloc_base +{ + int data_; + + template <class U> friend class test_allocator; +public: + + typedef unsigned size_type; + typedef int difference_type; + typedef void value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + + template <class U> struct rebind {typedef test_allocator<U> other;}; + + test_allocator() throw() : data_(-1) {} + explicit test_allocator(int i) throw() : data_(i) {} + test_allocator(const test_allocator& a) throw() + : data_(a.data_) {} + template <class U> test_allocator(const test_allocator<U>& a) throw() + : data_(a.data_) {} + ~test_allocator() throw() {data_ = 0;} + + friend bool operator==(const test_allocator& x, const test_allocator& y) + {return x.data_ == y.data_;} + friend bool operator!=(const test_allocator& x, const test_allocator& y) + {return !(x == y);} +}; + +template <class T> +class other_allocator +{ + int data_; + + template <class U> friend class other_allocator; + +public: + typedef T value_type; + + other_allocator() : data_(-1) {} + explicit other_allocator(int i) : data_(i) {} + template <class U> other_allocator(const other_allocator<U>& a) + : data_(a.data_) {} + T* allocate(std::size_t n) + {return (T*)std::malloc(n * sizeof(T));} + void deallocate(T* p, std::size_t n) + {std::free(p);} + + other_allocator select_on_container_copy_construction() const + {return other_allocator(-2);} + + friend bool operator==(const other_allocator& x, const other_allocator& y) + {return x.data_ == y.data_;} + friend bool operator!=(const other_allocator& x, const other_allocator& y) + {return !(x == y);} + + typedef std::true_type propagate_on_container_copy_assignment; + typedef std::true_type propagate_on_container_move_assignment; + typedef std::true_type propagate_on_container_swap; + +#ifdef _LIBCPP_HAS_NO_ADVANCED_SFINAE + std::size_t max_size() const + {return UINT_MAX / sizeof(T);} +#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE + +}; + +#endif // TEST_ALLOCATOR_H diff --git a/test/std/thread/futures/version.pass.cpp b/test/std/thread/futures/version.pass.cpp new file mode 100644 index 0000000000000..6730a1477db7a --- /dev/null +++ b/test/std/thread/futures/version.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads + +// <future> + +#include <future> + +#ifndef _LIBCPP_VERSION +#error _LIBCPP_VERSION not defined +#endif + +int main() +{ +} |