diff options
Diffstat (limited to 'libcxx/test')
19 files changed, 1113 insertions, 3 deletions
diff --git a/libcxx/test/thread/futures/futures.async/async.pass.cpp b/libcxx/test/thread/futures/futures.async/async.pass.cpp new file mode 100644 index 00000000000..f160ad35aa0 --- /dev/null +++ b/libcxx/test/thread/futures/futures.async/async.pass.cpp @@ -0,0 +1,177 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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); +} + +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::sync, 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::sync, 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::sync, 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)); + } +} diff --git a/libcxx/test/thread/futures/futures.promise/get_future.pass.cpp b/libcxx/test/thread/futures/futures.promise/get_future.pass.cpp new file mode 100644 index 00000000000..daa2c061fc0 --- /dev/null +++ b/libcxx/test/thread/futures/futures.promise/get_future.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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/libcxx/test/thread/futures/futures.promise/set_lvalue.pass.cpp b/libcxx/test/thread/futures/futures.promise/set_lvalue.pass.cpp index 4ebd8dd25df..8144fa68a7a 100644 --- a/libcxx/test/thread/futures/futures.promise/set_lvalue.pass.cpp +++ b/libcxx/test/thread/futures/futures.promise/set_lvalue.pass.cpp @@ -24,10 +24,10 @@ int main() std::promise<T> p; std::future<T> f = p.get_future(); p.set_value(i); - assert(f.get() == 3); + int& j = f.get(); + assert(j == 3); ++i; - f = p.get_future(); - assert(f.get() == 4); + assert(j == 4); try { p.set_value(i); diff --git a/libcxx/test/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp new file mode 100644 index 00000000000..ea6c4fad8f6 --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. 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); + assert(p); + 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); + assert(!p); + } +} diff --git a/libcxx/test/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp new file mode 100644 index 00000000000..c33349d3287 --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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); + assert(p); + 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); + assert(!p); + } +} diff --git a/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp new file mode 100644 index 00000000000..b2bcce531cb --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. 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); + assert(p); + 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); + assert(!p); + } +} diff --git a/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp new file mode 100644 index 00000000000..4e5fece73ac --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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); +} diff --git a/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp new file mode 100644 index 00000000000..de6032153fc --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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 main() +{ + { + std::packaged_task<double(int, char)> p(A(5)); + assert(p); + 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); + 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); + } +} diff --git a/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp new file mode 100644 index 00000000000..e38446f14dc --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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" + +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 main() +{ + { + std::packaged_task<double(int, char)> p(std::allocator_arg, + test_allocator<A>(), A(5)); + assert(test_alloc_base::count > 0); + assert(p); + 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_copies = 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); + 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); +} diff --git a/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp new file mode 100644 index 00000000000..2bc5061d62b --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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); + assert(p); + 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); + assert(!p); + } +} diff --git a/libcxx/test/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp new file mode 100644 index 00000000000..0f719173c4d --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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/libcxx/test/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp new file mode 100644 index 00000000000..369028e938a --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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/libcxx/test/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp new file mode 100644 index 00000000000..11c0f91b54e --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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/libcxx/test/thread/futures/futures.tas/futures.task.members/operator.pass.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.members/operator.pass.cpp new file mode 100644 index 00000000000..fff8467d950 --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.members/operator.pass.cpp @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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/libcxx/test/thread/futures/futures.tas/futures.task.members/reset.pass.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.members/reset.pass.cpp new file mode 100644 index 00000000000..db9cfbf285f --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.members/reset.pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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/libcxx/test/thread/futures/futures.tas/futures.task.members/swap.pass.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.members/swap.pass.cpp new file mode 100644 index 00000000000..c5bd7f59fb8 --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.members/swap.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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); + assert(p); + 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); + assert(!p); + } +} diff --git a/libcxx/test/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp new file mode 100644 index 00000000000..f6916a5af37 --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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); + assert(p); + 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); + assert(!p); + } +} diff --git a/libcxx/test/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp b/libcxx/test/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp new file mode 100644 index 00000000000..3203bf27952 --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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/libcxx/test/thread/futures/futures.tas/types.pass.cpp b/libcxx/test/thread/futures/futures.tas/types.pass.cpp new file mode 100644 index 00000000000..a8569dcd8c5 --- /dev/null +++ b/libcxx/test/thread/futures/futures.tas/types.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <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), ""); +} |