1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: no-threads
16 // template <class F, class... Args>
17 // future<typename result_of<F(Args...)>::type>
18 // async(F&& f, Args&&... args);
20 // template <class F, class... Args>
21 // future<typename result_of<F(Args...)>::type>
22 // async(launch policy, F&& f, Args&&... args);
31 #include "test_macros.h"
33 typedef std::chrono::high_resolution_clock Clock
;
34 typedef std::chrono::milliseconds ms
;
36 std::atomic_bool invoked
{false};
41 std::this_thread::sleep_for(ms(200));
50 std::this_thread::sleep_for(ms(200));
57 std::this_thread::sleep_for(ms(200));
60 std::unique_ptr
<int> f3(int j
)
63 std::this_thread::sleep_for(ms(200));
64 return std::unique_ptr
<int>(new int(j
));
67 std::unique_ptr
<int> f4(std::unique_ptr
<int>&& p
)
70 std::this_thread::sleep_for(ms(200));
76 std::this_thread::sleep_for(ms(200));
81 template <class Ret
, class CheckLambda
, class... Args
>
82 void test(CheckLambda
&& getAndCheckFn
, bool IsDeferred
, Args
&&... args
) {
83 // Reset global state.
86 // Create the future and wait
87 std::future
<Ret
> f
= std::async(std::forward
<Args
>(args
)...);
88 std::this_thread::sleep_for(ms(300));
90 // Check that deferred async's have not invoked the function.
91 assert(invoked
== !IsDeferred
);
93 // Time the call to f.get() and check that the returned value matches
95 Clock::time_point t0
= Clock::now();
96 assert(getAndCheckFn(f
));
97 Clock::time_point t1
= Clock::now();
99 // If the async is deferred it should take more than 100ms, otherwise
100 // it should take less than 100ms.
102 assert(t1
- t0
> ms(100));
104 assert(t1
- t0
< ms(100));
108 int main(int, char**)
110 // The default launch policy is implementation defined. libc++ defines
111 // it to be std::launch::async.
112 bool DefaultPolicyIsDeferred
= false;
113 bool DPID
= DefaultPolicyIsDeferred
;
115 std::launch AnyPolicy
= std::launch::async
| std::launch::deferred
;
116 LIBCPP_ASSERT(AnyPolicy
== std::launch::any
);
119 auto checkInt
= [](std::future
<int>& f
) { return f
.get() == 3; };
120 test
<int>(checkInt
, DPID
, f0
);
121 test
<int>(checkInt
, false, std::launch::async
, f0
);
122 test
<int>(checkInt
, true, std::launch::deferred
, f0
);
123 test
<int>(checkInt
, DPID
, AnyPolicy
, f0
);
126 auto checkIntRef
= [&](std::future
<int&>& f
) { return &f
.get() == &i
; };
127 test
<int&>(checkIntRef
, DPID
, f1
);
128 test
<int&>(checkIntRef
, false, std::launch::async
, f1
);
129 test
<int&>(checkIntRef
, true, std::launch::deferred
, f1
);
130 test
<int&>(checkIntRef
, DPID
, AnyPolicy
, f1
);
133 auto checkVoid
= [](std::future
<void>& f
) { f
.get(); return true; };
134 test
<void>(checkVoid
, DPID
, f2
);
135 test
<void>(checkVoid
, false, std::launch::async
, f2
);
136 test
<void>(checkVoid
, true, std::launch::deferred
, f2
);
137 test
<void>(checkVoid
, DPID
, AnyPolicy
, f2
);
140 using Ret
= std::unique_ptr
<int>;
141 auto checkUPtr
= [](std::future
<Ret
>& f
) { return *f
.get() == 3; };
142 test
<Ret
>(checkUPtr
, DPID
, f3
, 3);
143 test
<Ret
>(checkUPtr
, DPID
, f4
, std::unique_ptr
<int>(new int(3)));
145 #ifndef TEST_HAS_NO_EXCEPTIONS
147 std::future
<void> f
= std::async(f5
, 3);
148 std::this_thread::sleep_for(ms(300));
149 try { f
.get(); assert (false); } catch ( int ) {}
152 std::future
<void> f
= std::async(std::launch::deferred
, f5
, 3);
153 std::this_thread::sleep_for(ms(300));
154 try { f
.get(); assert (false); } catch ( int ) {}