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
15 // template<class Callable, class ...Args>
16 // void call_once(once_flag& flag, Callable&& func, Args&&... args);
22 #include "make_test_thread.h"
23 #include "test_macros.h"
25 typedef std::chrono::milliseconds ms
;
33 std::this_thread::sleep_for(ms(250));
39 std::call_once(flg0
, init0
);
45 int init3_completed
= 0;
50 std::this_thread::sleep_for(ms(250));
51 if (init3_called
== 1)
58 #ifndef TEST_HAS_NO_EXCEPTIONS
61 std::call_once(flg3
, init3
);
69 #if TEST_STD_VER >= 11
75 void operator()(int i
) {called
+= i
;}
78 int init1::called
= 0;
84 std::call_once(flg1
, init1(), 1);
91 void operator()(int i
, int j
) const {called
+= i
+ j
;}
94 int init2::called
= 0;
100 std::call_once(flg2
, init2(), 2, 3);
101 std::call_once(flg2
, init2(), 4, 5);
104 #endif // TEST_STD_VER >= 11
106 std::once_flag flg41
;
107 std::once_flag flg42
;
109 int init41_called
= 0;
110 int init42_called
= 0;
116 std::this_thread::sleep_for(ms(250));
122 std::this_thread::sleep_for(ms(250));
128 std::call_once(flg41
, init41
);
129 std::call_once(flg42
, init42
);
134 std::call_once(flg42
, init42
);
135 std::call_once(flg41
, init41
);
138 #if TEST_STD_VER >= 11
142 #if !defined(__clang__)
143 // GCC 4.8 complains about the following being private
145 MoveOnly(const MoveOnly
&)
149 MoveOnly(const MoveOnly
&);
153 MoveOnly(MoveOnly
&&) {}
155 void operator()(MoveOnly
&&)
162 #if !defined(__clang__)
163 // GCC 4.8 complains about the following being private
165 NonCopyable(const NonCopyable
&)
169 NonCopyable(const NonCopyable
&);
174 void operator()(int&) {}
177 // reference qualifiers on functions are a C++11 extension
180 int lv_called
, rv_called
;
182 RefQual() : lv_called(0), rv_called(0) {}
184 void operator()() & { ++lv_called
; }
185 void operator()() && { ++rv_called
; }
188 #endif // TEST_STD_VER >= 11
190 int main(int, char**)
192 // check basic functionality
194 std::thread t0
= support::make_test_thread(f0
);
195 std::thread t1
= support::make_test_thread(f0
);
198 assert(init0_called
== 1);
200 #ifndef TEST_HAS_NO_EXCEPTIONS
201 // check basic exception safety
203 std::thread t0
= support::make_test_thread(f3
);
204 std::thread t1
= support::make_test_thread(f3
);
207 assert(init3_called
== 2);
208 assert(init3_completed
== 1);
211 // check deadlock avoidance
213 std::thread t0
= support::make_test_thread(f41
);
214 std::thread t1
= support::make_test_thread(f42
);
217 assert(init41_called
== 1);
218 assert(init42_called
== 1);
220 #if TEST_STD_VER >= 11
221 // check functors with 1 arg
223 std::thread t0
= support::make_test_thread(f1
);
224 std::thread t1
= support::make_test_thread(f1
);
227 assert(init1::called
== 1);
229 // check functors with 2 args
231 std::thread t0
= support::make_test_thread(f2
);
232 std::thread t1
= support::make_test_thread(f2
);
235 assert(init2::called
== 5);
239 std::call_once(f
, MoveOnly(), MoveOnly());
241 // check LWG2442: call_once() shouldn't DECAY_COPY()
245 std::call_once(f
, NonCopyable(), i
);
247 // reference qualifiers on functions are a C++11 extension
249 std::once_flag f1
, f2
;
251 std::call_once(f1
, rq
);
252 assert(rq
.lv_called
== 1);
253 std::call_once(f2
, std::move(rq
));
254 assert(rq
.rv_called
== 1);
256 #endif // TEST_STD_VER >= 11