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
10 // UNSUPPORTED: c++03, c++11, c++14
14 // template <class ...Mutex> class scoped_lock;
16 // explicit scoped_lock(mutex_type& m);
20 #include "test_macros.h"
24 TestMutex() = default;
25 ~TestMutex() { assert(!locked
); }
27 void lock() { assert(!locked
); locked
= true; }
28 bool try_lock() { if (locked
) return false; locked
= true; return true; }
29 void unlock() { assert(locked
); locked
= false; }
31 TestMutex(TestMutex
const&) = delete;
32 TestMutex
& operator=(TestMutex
const&) = delete;
35 #if !defined(TEST_HAS_NO_EXCEPTIONS)
36 struct TestMutexThrows
{
38 bool throws_on_lock
= false;
40 TestMutexThrows() = default;
41 ~TestMutexThrows() { assert(!locked
); }
52 if (locked
) return false;
57 void unlock() { assert(locked
); locked
= false; }
59 TestMutexThrows(TestMutexThrows
const&) = delete;
60 TestMutexThrows
& operator=(TestMutexThrows
const&) = delete;
62 #endif // !defined(TEST_HAS_NO_EXCEPTIONS)
67 using LG
= std::scoped_lock
<>;
72 using LG
= std::scoped_lock
<TestMutex
>;
81 using LG
= std::scoped_lock
<TestMutex
, TestMutex
>;
85 assert(m1
.locked
&& m2
.locked
);
87 assert(!m1
.locked
&& !m2
.locked
);
90 using LG
= std::scoped_lock
<TestMutex
, TestMutex
, TestMutex
>;
94 assert(m1
.locked
&& m2
.locked
&& m3
.locked
);
96 assert(!m1
.locked
&& !m2
.locked
&& !m3
.locked
);
98 #if !defined(TEST_HAS_NO_EXCEPTIONS)
100 using MT
= TestMutexThrows
;
101 using LG
= std::scoped_lock
<MT
>;
103 m1
.throws_on_lock
= true;
111 using MT
= TestMutexThrows
;
112 using LG
= std::scoped_lock
<MT
, MT
>;
114 m1
.throws_on_lock
= true;
119 assert(!m1
.locked
&& !m2
.locked
);
122 using MT
= TestMutexThrows
;
123 using LG
= std::scoped_lock
<MT
, MT
, MT
>;
125 m2
.throws_on_lock
= true;
130 assert(!m1
.locked
&& !m2
.locked
&& !m3
.locked
);
134 #if TEST_STD_VER >= 17
136 TestMutex m1
, m2
, m3
;
138 std::scoped_lock sl
{};
139 static_assert((std::is_same
<decltype(sl
), std::scoped_lock
<>>::value
), "" );
142 std::scoped_lock sl
{m1
};
143 static_assert((std::is_same
<decltype(sl
), std::scoped_lock
<decltype(m1
)>>::value
), "" );
146 std::scoped_lock sl
{m1
, m2
};
147 static_assert((std::is_same
<decltype(sl
), std::scoped_lock
<decltype(m1
), decltype(m2
)>>::value
), "" );
150 std::scoped_lock sl
{m1
, m2
, m3
};
151 static_assert((std::is_same
<decltype(sl
), std::scoped_lock
<decltype(m1
), decltype(m2
), decltype(m3
)>>::value
), "" );