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: libcpp-has-no-threads
14 // template <class F, class... Args>
15 // future<typename result_of<F(Args...)>::type>
16 // async(F&& f, Args&&... args);
18 // template <class F, class... Args>
19 // future<typename result_of<F(Args...)>::type>
20 // async(launch policy, F&& f, Args&&... args);
28 #include "test_macros.h"
30 typedef std::chrono::high_resolution_clock Clock
;
31 typedef std::chrono::milliseconds ms
;
33 std::atomic_bool invoked
= ATOMIC_VAR_INIT(false);
38 std::this_thread::sleep_for(ms(200));
47 std::this_thread::sleep_for(ms(200));
54 std::this_thread::sleep_for(ms(200));
57 std::unique_ptr
<int> f3(int j
)
60 std::this_thread::sleep_for(ms(200));
61 return std::unique_ptr
<int>(new int(j
));
64 std::unique_ptr
<int> f4(std::unique_ptr
<int>&& p
)
67 std::this_thread::sleep_for(ms(200));
73 std::this_thread::sleep_for(ms(200));
78 template <class Ret
, class CheckLamdba
, class ...Args
>
79 void test(CheckLamdba
&& getAndCheckFn
, bool IsDeferred
, Args
&&... args
) {
80 // Reset global state.
83 // Create the future and wait
84 std::future
<Ret
> f
= std::async(std::forward
<Args
>(args
)...);
85 std::this_thread::sleep_for(ms(300));
87 // Check that deferred async's have not invoked the function.
88 assert(invoked
== !IsDeferred
);
90 // Time the call to f.get() and check that the returned value matches
92 Clock::time_point t0
= Clock::now();
93 assert(getAndCheckFn(f
));
94 Clock::time_point t1
= Clock::now();
96 // If the async is deferred it should take more than 100ms, otherwise
97 // it should take less than 100ms.
99 assert(t1
-t0
> ms(100));
101 assert(t1
-t0
< ms(100));
105 int main(int, char**)
107 // The default launch policy is implementation defined. libc++ defines
108 // it to be std::launch::async.
109 bool DefaultPolicyIsDeferred
= false;
110 bool DPID
= DefaultPolicyIsDeferred
;
112 std::launch AnyPolicy
= std::launch::async
| std::launch::deferred
;
113 LIBCPP_ASSERT(AnyPolicy
== std::launch::any
);
116 auto checkInt
= [](std::future
<int>& f
) { return f
.get() == 3; };
117 test
<int>(checkInt
, DPID
, f0
);
118 test
<int>(checkInt
, false, std::launch::async
, f0
);
119 test
<int>(checkInt
, true, std::launch::deferred
, f0
);
120 test
<int>(checkInt
, DPID
, AnyPolicy
, f0
);
123 auto checkIntRef
= [&](std::future
<int&>& f
) { return &f
.get() == &i
; };
124 test
<int&>(checkIntRef
, DPID
, f1
);
125 test
<int&>(checkIntRef
, false, std::launch::async
, f1
);
126 test
<int&>(checkIntRef
, true, std::launch::deferred
, f1
);
127 test
<int&>(checkIntRef
, DPID
, AnyPolicy
, f1
);
130 auto checkVoid
= [](std::future
<void>& f
) { f
.get(); return true; };
131 test
<void>(checkVoid
, DPID
, f2
);
132 test
<void>(checkVoid
, false, std::launch::async
, f2
);
133 test
<void>(checkVoid
, true, std::launch::deferred
, f2
);
134 test
<void>(checkVoid
, DPID
, AnyPolicy
, f2
);
137 using Ret
= std::unique_ptr
<int>;
138 auto checkUPtr
= [](std::future
<Ret
>& f
) { return *f
.get() == 3; };
139 test
<Ret
>(checkUPtr
, DPID
, f3
, 3);
140 test
<Ret
>(checkUPtr
, DPID
, f4
, std::unique_ptr
<int>(new int(3)));
142 #ifndef TEST_HAS_NO_EXCEPTIONS
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 ) {}
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 ) {}