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);
32 #include "test_macros.h"
34 typedef std::chrono::high_resolution_clock Clock
;
35 typedef std::chrono::milliseconds ms
;
37 std::atomic_bool invoked
{false};
42 std::this_thread::sleep_for(ms(200));
51 std::this_thread::sleep_for(ms(200));
58 std::this_thread::sleep_for(ms(200));
61 std::unique_ptr
<int> f3(int j
)
64 std::this_thread::sleep_for(ms(200));
65 return std::unique_ptr
<int>(new int(j
));
68 std::unique_ptr
<int> f4(std::unique_ptr
<int>&& p
)
71 std::this_thread::sleep_for(ms(200));
77 std::this_thread::sleep_for(ms(200));
82 template <class Ret
, class CheckLambda
, class... Args
>
83 void test(CheckLambda
&& getAndCheckFn
, bool IsDeferred
, Args
&&... args
) {
84 // Reset global state.
87 // Create the future and wait
88 std::future
<Ret
> f
= std::async(std::forward
<Args
>(args
)...);
89 std::this_thread::sleep_for(ms(300));
91 // Check that deferred async's have not invoked the function.
92 assert(invoked
== !IsDeferred
);
94 // Time the call to f.get() and check that the returned value matches
96 Clock::time_point t0
= Clock::now();
97 assert(getAndCheckFn(f
));
98 Clock::time_point t1
= Clock::now();
100 // If the async is deferred it should take more than 100ms, otherwise
101 // it should take less than 100ms.
103 assert(t1
- t0
> ms(100));
105 assert(t1
- t0
< ms(100));
109 int main(int, char**)
111 // The default launch policy is implementation defined. libc++ defines
112 // it to be std::launch::async.
113 bool DefaultPolicyIsDeferred
= false;
114 bool DPID
= DefaultPolicyIsDeferred
;
116 std::launch AnyPolicy
= std::launch::async
| std::launch::deferred
;
117 LIBCPP_ASSERT(AnyPolicy
== std::launch::any
);
120 auto checkInt
= [](std::future
<int>& f
) { return f
.get() == 3; };
121 test
<int>(checkInt
, DPID
, f0
);
122 test
<int>(checkInt
, false, std::launch::async
, f0
);
123 test
<int>(checkInt
, true, std::launch::deferred
, f0
);
124 test
<int>(checkInt
, DPID
, AnyPolicy
, f0
);
127 auto checkIntRef
= [&](std::future
<int&>& f
) { return &f
.get() == &i
; };
128 test
<int&>(checkIntRef
, DPID
, f1
);
129 test
<int&>(checkIntRef
, false, std::launch::async
, f1
);
130 test
<int&>(checkIntRef
, true, std::launch::deferred
, f1
);
131 test
<int&>(checkIntRef
, DPID
, AnyPolicy
, f1
);
134 auto checkVoid
= [](std::future
<void>& f
) { f
.get(); return true; };
135 test
<void>(checkVoid
, DPID
, f2
);
136 test
<void>(checkVoid
, false, std::launch::async
, f2
);
137 test
<void>(checkVoid
, true, std::launch::deferred
, f2
);
138 test
<void>(checkVoid
, DPID
, AnyPolicy
, f2
);
141 using Ret
= std::unique_ptr
<int>;
142 auto checkUPtr
= [](std::future
<Ret
>& f
) { return *f
.get() == 3; };
143 test
<Ret
>(checkUPtr
, DPID
, f3
, 3);
144 test
<Ret
>(checkUPtr
, DPID
, f4
, std::unique_ptr
<int>(new int(3)));
146 #ifndef TEST_HAS_NO_EXCEPTIONS
148 std::future
<void> f
= std::async(f5
, 3);
149 std::this_thread::sleep_for(ms(300));
150 try { f
.get(); assert (false); } catch ( int ) {}
153 std::future
<void> f
= std::async(std::launch::deferred
, f5
, 3);
154 std::this_thread::sleep_for(ms(300));
155 try { f
.get(); assert (false); } catch ( int ) {}