1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // UNSUPPORTED: libcpp-has-no-threads 11 // UNSUPPORTED: c++98, c++03 12 13 // <mutex> 14 15 // template <class Mutex> 16 // class lock_guard 17 // { 18 // public: 19 // typedef Mutex mutex_type; 20 // ... 21 // }; 22 23 // MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD 24 #define _LIBCPP_ABI_VARIADIC_LOCK_GUARD 25 #include <mutex> 26 #include <type_traits> 27 28 struct NAT {}; 29 30 template <class LG> 31 auto test_typedef(int) -> typename LG::mutex_type; 32 33 template <class LG> 34 auto test_typedef(...) -> NAT; 35 36 template <class LG> 37 constexpr bool has_mutex_type() { 38 return !std::is_same<decltype(test_typedef<LG>(0)), NAT>::value; 39 } 40 41 int main() 42 { 43 { 44 using T = std::lock_guard<>; 45 static_assert(!has_mutex_type<T>(), ""); 46 } 47 { 48 using M1 = std::mutex; 49 using T = std::lock_guard<M1>; 50 static_assert(std::is_same<T::mutex_type, M1>::value, ""); 51 } 52 { 53 using M1 = std::recursive_mutex; 54 using T = std::lock_guard<M1>; 55 static_assert(std::is_same<T::mutex_type, M1>::value, ""); 56 } 57 { 58 using M1 = std::mutex; 59 using M2 = std::recursive_mutex; 60 using T = std::lock_guard<M1, M2>; 61 static_assert(!has_mutex_type<T>(), ""); 62 } 63 { 64 using M1 = std::mutex; 65 using M2 = std::recursive_mutex; 66 using T = std::lock_guard<M1, M1, M2>; 67 static_assert(!has_mutex_type<T>(), ""); 68 } 69 { 70 using M1 = std::mutex; 71 using T = std::lock_guard<M1, M1>; 72 static_assert(!has_mutex_type<T>(), ""); 73 } 74 { 75 using M1 = std::recursive_mutex; 76 using T = std::lock_guard<M1, M1, M1>; 77 static_assert(!has_mutex_type<T>(), ""); 78 } 79 } 80