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
<>;
71 using LG
= std::scoped_lock
<TestMutex
>;
80 using LG
= std::scoped_lock
<TestMutex
, TestMutex
>;
84 assert(m1
.locked
&& m2
.locked
);
86 assert(!m1
.locked
&& !m2
.locked
);
89 using LG
= std::scoped_lock
<TestMutex
, TestMutex
, TestMutex
>;
93 assert(m1
.locked
&& m2
.locked
&& m3
.locked
);
95 assert(!m1
.locked
&& !m2
.locked
&& !m3
.locked
);
97 #if !defined(TEST_HAS_NO_EXCEPTIONS)
99 using MT
= TestMutexThrows
;
100 using LG
= std::scoped_lock
<MT
>;
102 m1
.throws_on_lock
= true;
110 using MT
= TestMutexThrows
;
111 using LG
= std::scoped_lock
<MT
, MT
>;
113 m1
.throws_on_lock
= true;
118 assert(!m1
.locked
&& !m2
.locked
);
121 using MT
= TestMutexThrows
;
122 using LG
= std::scoped_lock
<MT
, MT
, MT
>;
124 m2
.throws_on_lock
= true;
129 assert(!m1
.locked
&& !m2
.locked
&& !m3
.locked
);
133 #if TEST_STD_VER >= 17
135 TestMutex m1
, m2
, m3
;
137 std::scoped_lock sl
{};
138 static_assert((std::is_same
<decltype(sl
), std::scoped_lock
<>>::value
), "" );
141 std::scoped_lock sl
{m1
};
142 static_assert((std::is_same
<decltype(sl
), std::scoped_lock
<decltype(m1
)>>::value
), "" );
145 std::scoped_lock sl
{m1
, m2
};
146 static_assert((std::is_same
<decltype(sl
), std::scoped_lock
<decltype(m1
), decltype(m2
)>>::value
), "" );
149 std::scoped_lock sl
{m1
, m2
, m3
};
150 static_assert((std::is_same
<decltype(sl
), std::scoped_lock
<decltype(m1
), decltype(m2
), decltype(m3
)>>::value
), "" );