1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // UNSUPPORTED: libcpp-has-no-threads 11 // UNSUPPORTED: c++98, c++03 12 13 // <future> 14 15 // class packaged_task<R(ArgTypes...)> 16 17 // void operator()(ArgTypes... args); 18 19 #include <future> 20 #include <cassert> 21 22 #include "test_macros.h" 23 24 class A 25 { 26 long data_; 27 28 public: 29 explicit A(long i) : data_(i) {} 30 31 long operator()(long i, long j) const 32 { 33 if (j == 'z') 34 TEST_THROW(A(6)); 35 return data_ + i + j; 36 } 37 }; 38 39 void func0(std::packaged_task<double(int, char)> p) 40 { 41 std::this_thread::sleep_for(std::chrono::milliseconds(500)); 42 p(3, 'a'); 43 } 44 45 void func1(std::packaged_task<double(int, char)> p) 46 { 47 std::this_thread::sleep_for(std::chrono::milliseconds(500)); 48 p(3, 'z'); 49 } 50 51 void func2(std::packaged_task<double(int, char)> p) 52 { 53 #ifndef TEST_HAS_NO_EXCEPTIONS 54 p(3, 'a'); 55 try 56 { 57 p(3, 'c'); 58 } 59 catch (const std::future_error& e) 60 { 61 assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied)); 62 } 63 #else 64 ((void)p); 65 #endif 66 } 67 68 void func3(std::packaged_task<double(int, char)> p) 69 { 70 #ifndef TEST_HAS_NO_EXCEPTIONS 71 try 72 { 73 p(3, 'a'); 74 } 75 catch (const std::future_error& e) 76 { 77 assert(e.code() == make_error_code(std::future_errc::no_state)); 78 } 79 #else 80 ((void)p); 81 #endif 82 } 83 84 int main() 85 { 86 { 87 std::packaged_task<double(int, char)> p(A(5)); 88 std::future<double> f = p.get_future(); 89 std::thread(func0, std::move(p)).detach(); 90 assert(f.get() == 105.0); 91 } 92 #ifndef TEST_HAS_NO_EXCEPTIONS 93 { 94 std::packaged_task<double(int, char)> p(A(5)); 95 std::future<double> f = p.get_future(); 96 std::thread(func1, std::move(p)).detach(); 97 try 98 { 99 f.get(); 100 assert(false); 101 } 102 catch (const A& e) 103 { 104 assert(e(3, 'a') == 106); 105 } 106 } 107 { 108 std::packaged_task<double(int, char)> p(A(5)); 109 std::future<double> f = p.get_future(); 110 std::thread t(func2, std::move(p)); 111 assert(f.get() == 105.0); 112 t.join(); 113 } 114 { 115 std::packaged_task<double(int, char)> p; 116 std::thread t(func3, std::move(p)); 117 t.join(); 118 } 119 #endif 120 } 121