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 // XFAIL: libcpp-no-exceptions 11 // UNSUPPORTED: libcpp-has-no-threads 12 // UNSUPPORTED: c++98, c++03 13 14 // <future> 15 16 // template <class F, class... Args> 17 // future<typename result_of<F(Args...)>::type> 18 // async(F&& f, Args&&... args); 19 20 // template <class F, class... Args> 21 // future<typename result_of<F(Args...)>::type> 22 // async(launch policy, F&& f, Args&&... args); 23 24 25 #include <future> 26 #include <atomic> 27 #include <memory> 28 #include <cassert> 29 30 #include "test_macros.h" 31 32 typedef std::chrono::high_resolution_clock Clock; 33 typedef std::chrono::milliseconds ms; 34 35 std::atomic_bool invoked = ATOMIC_VAR_INIT(false); 36 37 int f0() 38 { 39 invoked = true; 40 std::this_thread::sleep_for(ms(200)); 41 return 3; 42 } 43 44 int i = 0; 45 46 int& f1() 47 { 48 invoked = true; 49 std::this_thread::sleep_for(ms(200)); 50 return i; 51 } 52 53 void f2() 54 { 55 invoked = true; 56 std::this_thread::sleep_for(ms(200)); 57 } 58 59 std::unique_ptr<int> f3(int j) 60 { 61 invoked = true; 62 std::this_thread::sleep_for(ms(200)); 63 return std::unique_ptr<int>(new int(j)); 64 } 65 66 std::unique_ptr<int> f4(std::unique_ptr<int>&& p) 67 { 68 invoked = true; 69 std::this_thread::sleep_for(ms(200)); 70 return std::move(p); 71 } 72 73 void f5(int j) 74 { 75 std::this_thread::sleep_for(ms(200)); 76 throw j; 77 } 78 79 template <class Ret, class CheckLamdba, class ...Args> 80 void test(CheckLamdba&& getAndCheckFn, bool IsDeferred, Args&&... args) { 81 // Reset global state. 82 invoked = false; 83 84 // Create the future and wait 85 std::future<Ret> f = std::async(std::forward<Args>(args)...); 86 std::this_thread::sleep_for(ms(300)); 87 88 // Check that deferred async's have not invoked the function. 89 assert(invoked == !IsDeferred); 90 91 // Time the call to f.get() and check that the returned value matches 92 // what is expected. 93 Clock::time_point t0 = Clock::now(); 94 assert(getAndCheckFn(f)); 95 Clock::time_point t1 = Clock::now(); 96 97 // If the async is deferred it should take more than 100ms, otherwise 98 // it should take less than 100ms. 99 if (IsDeferred) { 100 assert(t1-t0 > ms(100)); 101 } else { 102 assert(t1-t0 < ms(100)); 103 } 104 } 105 106 int main() 107 { 108 // The default launch policy is implementation defined. libc++ defines 109 // it to be std::launch::async. 110 bool DefaultPolicyIsDeferred = false; 111 bool DPID = DefaultPolicyIsDeferred; 112 113 std::launch AnyPolicy = std::launch::async | std::launch::deferred; 114 LIBCPP_ASSERT(AnyPolicy == std::launch::any); 115 116 { 117 auto checkInt = [](std::future<int>& f) { return f.get() == 3; }; 118 test<int>(checkInt, DPID, f0); 119 test<int>(checkInt, false, std::launch::async, f0); 120 test<int>(checkInt, true, std::launch::deferred, f0); 121 test<int>(checkInt, DPID, AnyPolicy, f0); 122 } 123 { 124 auto checkIntRef = [&](std::future<int&>& f) { return &f.get() == &i; }; 125 test<int&>(checkIntRef, DPID, f1); 126 test<int&>(checkIntRef, false, std::launch::async, f1); 127 test<int&>(checkIntRef, true, std::launch::deferred, f1); 128 test<int&>(checkIntRef, DPID, AnyPolicy, f1); 129 } 130 { 131 auto checkVoid = [](std::future<void>& f) { f.get(); return true; }; 132 test<void>(checkVoid, DPID, f2); 133 test<void>(checkVoid, false, std::launch::async, f2); 134 test<void>(checkVoid, true, std::launch::deferred, f2); 135 test<void>(checkVoid, DPID, AnyPolicy, f2); 136 } 137 { 138 using Ret = std::unique_ptr<int>; 139 auto checkUPtr = [](std::future<Ret>& f) { return *f.get() == 3; }; 140 test<Ret>(checkUPtr, DPID, f3, 3); 141 test<Ret>(checkUPtr, DPID, f4, std::unique_ptr<int>(new int(3))); 142 } 143 { 144 std::future<void> f = std::async(f5, 3); 145 std::this_thread::sleep_for(ms(300)); 146 try { f.get(); assert (false); } catch ( int ) {} 147 } 148 { 149 std::future<void> f = std::async(std::launch::deferred, f5, 3); 150 std::this_thread::sleep_for(ms(300)); 151 try { f.get(); assert (false); } catch ( int ) {} 152 } 153 } 154