1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: libcpp-has-no-threads
11 // UNSUPPORTED: c++98, c++03, c++11, c++14
15 // template <class ...Mutex> class scoped_lock;
17 // explicit scoped_lock(mutex_type& m);
21 #include "test_macros.h"
25 TestMutex() = default;
26 ~TestMutex() { assert(!locked); }
28 void lock() { assert(!locked); locked = true; }
29 bool try_lock() { if (locked) return false; locked = true; return true; }
30 void unlock() { assert(locked); locked = false; }
32 TestMutex(TestMutex const&) = delete;
33 TestMutex& operator=(TestMutex const&) = delete;
36 #if !defined(TEST_HAS_NO_EXCEPTIONS)
37 struct TestMutexThrows {
39 bool throws_on_lock = false;
41 TestMutexThrows() = default;
42 ~TestMutexThrows() { assert(!locked); }
53 if (locked) return false;
58 void unlock() { assert(locked); locked = false; }
60 TestMutexThrows(TestMutexThrows const&) = delete;
61 TestMutexThrows& operator=(TestMutexThrows const&) = delete;
63 #endif // !defined(TEST_HAS_NO_EXCEPTIONS)
68 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 #ifdef __cpp_deduction_guides
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), "" );