From 6015dd11c875b9467c93221f19e5d59b0522757a Mon Sep 17 00:00:00 2001 From: Marshall Clow Date: Fri, 24 Mar 2017 03:40:36 +0000 Subject: [PATCH] Implement Pp0156r2: 'Variadic Lock Guard, version 5' Reviewed as https://reviews.llvm.org/D31163. llvm-svn: 298681 --- libcxx/include/__config | 5 +- libcxx/include/__mutex_base | 12 ---- libcxx/include/mutex | 70 +++++++++++++++------- libcxx/include/shared_mutex | 4 +- .../variadic_mutex_mangling.pass.cpp | 37 ------------ .../thread.lock/thread.lock.guard/mutex.pass.cpp | 10 ++++ .../variadic_mutex_cxx03.pass.cpp | 21 ------- .../adopt_lock.pass.cpp} | 25 +++++--- .../assign.fail.cpp} | 21 ++++--- .../copy.fail.cpp} | 20 ++++--- .../mutex.fail.cpp} | 21 ++++--- .../mutex.pass.cpp} | 61 +++++++++++++++---- .../types.pass.cpp} | 25 ++++---- .../thread.lock.shared.cons/mutex.pass.cpp | 8 +++ .../thread.lock.unique.cons/mutex.pass.cpp | 10 ++++ libcxx/www/cxx1z_status.html | 6 +- 16 files changed, 201 insertions(+), 155 deletions(-) delete mode 100644 libcxx/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp delete mode 100644 libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp rename libcxx/test/std/thread/thread.mutex/thread.lock/{thread.lock.guard/variadic_adopt_lock.pass.cpp => thread.lock.scoped/adopt_lock.pass.cpp} (71%) rename libcxx/test/std/thread/thread.mutex/thread.lock/{thread.lock.guard/variadic_assign.fail.cpp => thread.lock.scoped/assign.fail.cpp} (66%) rename libcxx/test/std/thread/thread.mutex/thread.lock/{thread.lock.guard/variadic_copy.fail.cpp => thread.lock.scoped/copy.fail.cpp} (65%) rename libcxx/test/std/thread/thread.mutex/thread.lock/{thread.lock.guard/variadic_mutex.fail.cpp => thread.lock.scoped/mutex.fail.cpp} (69%) rename libcxx/test/std/thread/thread.mutex/thread.lock/{thread.lock.guard/variadic_mutex.pass.cpp => thread.lock.scoped/mutex.pass.cpp} (61%) rename libcxx/test/std/thread/thread.mutex/thread.lock/{thread.lock.guard/variadic_types.pass.cpp => thread.lock.scoped/types.pass.cpp} (75%) diff --git a/libcxx/include/__config b/libcxx/include/__config index 95ffbe2..9b48a70 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -49,7 +49,6 @@ #define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB #define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB #define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE -#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD // Don't use a nullptr_t simulation type in C++03 instead using C++11 nullptr // provided under the alternate keyword __nullptr, which changes the mangling // of nullptr_t. This option is ABI incompatible with GCC in C++03 mode. @@ -1076,6 +1075,10 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( # define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE #endif // _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES +#if !defined(__cpp_deduction_guides) || __cpp_deduction_guides < 201611 +# define _LIBCPP_HAS_NO_DEDUCTION_GUIDES +#endif + #endif // __cplusplus #endif // _LIBCPP_CONFIG diff --git a/libcxx/include/__mutex_base b/libcxx/include/__mutex_base index f76e966..4940f93 100644 --- a/libcxx/include/__mutex_base +++ b/libcxx/include/__mutex_base @@ -80,21 +80,9 @@ constexpr adopt_lock_t adopt_lock = adopt_lock_t(); #endif - -// Forward declare lock_guard as a variadic template even in C++03 to keep -// the mangling consistent between dialects. -#if defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD) -template -class _LIBCPP_TEMPLATE_VIS lock_guard; -#endif - template class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) -#if !defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD) lock_guard -#else -lock_guard<_Mutex> -#endif { public: typedef _Mutex mutex_type; diff --git a/libcxx/include/mutex b/libcxx/include/mutex index 11b0f7e..5cc8ca66 100644 --- a/libcxx/include/mutex +++ b/libcxx/include/mutex @@ -109,15 +109,17 @@ public: lock_guard& operator=(lock_guard const&) = delete; }; -template // Variadic lock_guard only provided in ABI V2. -class lock_guard +template +class scoped_lock // C++17 { public: - explicit lock_guard(MutexTypes&... m); - lock_guard(MutexTypes&... m, adopt_lock_t); - ~lock_guard(); - lock_guard(lock_guard const&) = delete; - lock_guard& operator=(lock_guard const&) = delete; + using mutex_type = Mutex; // If MutexTypes... consists of the single type Mutex + + explicit scoped_lock(MutexTypes&... m); + scoped_lock(MutexTypes&... m, adopt_lock_t); + ~scoped_lock(); + scoped_lock(scoped_lock const&) = delete; + scoped_lock& operator=(scoped_lock const&) = delete; private: tuple pm; // exposition only }; @@ -614,50 +616,72 @@ call_once(once_flag& __flag, const _Callable& __func) #endif // _LIBCPP_HAS_NO_VARIADICS +#if _LIBCPP_STD_VER > 14 +template +class _LIBCPP_TEMPLATE_VIS scoped_lock; -#if defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD) \ - && !defined(_LIBCPP_CXX03_LANG) template <> -class _LIBCPP_TEMPLATE_VIS lock_guard<> { +class _LIBCPP_TEMPLATE_VIS scoped_lock<> { public: - explicit lock_guard() {} - ~lock_guard() = default; + explicit scoped_lock() {} + ~scoped_lock() = default; _LIBCPP_INLINE_VISIBILITY - explicit lock_guard(adopt_lock_t) {} + explicit scoped_lock(adopt_lock_t) {} - lock_guard(lock_guard const&) = delete; - lock_guard& operator=(lock_guard const&) = delete; + scoped_lock(scoped_lock const&) = delete; + scoped_lock& operator=(scoped_lock const&) = delete; +}; + +template +class _LIBCPP_TEMPLATE_VIS scoped_lock<_Mutex> { +public: + typedef _Mutex mutex_type; +private: + mutex_type& __m_; +public: + explicit scoped_lock(mutex_type & __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m)) + : __m_(__m) {__m_.lock();} + + ~scoped_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) {__m_.unlock();} + + _LIBCPP_INLINE_VISIBILITY + explicit scoped_lock(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m)) + : __m_(__m) {} + + + scoped_lock(scoped_lock const&) = delete; + scoped_lock& operator=(scoped_lock const&) = delete; }; template -class _LIBCPP_TEMPLATE_VIS lock_guard +class _LIBCPP_TEMPLATE_VIS scoped_lock { - static_assert(sizeof...(_MArgs) >= 2, "At least 2 lock types required"); + static_assert(sizeof...(_MArgs) > 1, "At least 2 lock types required"); typedef tuple<_MArgs&...> _MutexTuple; public: _LIBCPP_INLINE_VISIBILITY - explicit lock_guard(_MArgs&... __margs) + explicit scoped_lock(_MArgs&... __margs) : __t_(__margs...) { _VSTD::lock(__margs...); } _LIBCPP_INLINE_VISIBILITY - lock_guard(_MArgs&... __margs, adopt_lock_t) + scoped_lock(_MArgs&... __margs, adopt_lock_t) : __t_(__margs...) { } _LIBCPP_INLINE_VISIBILITY - ~lock_guard() { + ~scoped_lock() { typedef typename __make_tuple_indices::type _Indices; __unlock_unpack(_Indices{}, __t_); } - lock_guard(lock_guard const&) = delete; - lock_guard& operator=(lock_guard const&) = delete; + scoped_lock(scoped_lock const&) = delete; + scoped_lock& operator=(scoped_lock const&) = delete; private: template @@ -669,7 +693,7 @@ private: _MutexTuple __t_; }; -#endif // _LIBCPP_ABI_VARIADIC_LOCK_GUARD +#endif // _LIBCPP_STD_VER > 14 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/shared_mutex b/libcxx/include/shared_mutex index 29e8cef..f2fd667 100644 --- a/libcxx/include/shared_mutex +++ b/libcxx/include/shared_mutex @@ -175,7 +175,7 @@ struct _LIBCPP_TYPE_VIS __shared_mutex_base #if _LIBCPP_STD_VER > 14 class _LIBCPP_TYPE_VIS shared_mutex { - __shared_mutex_base __base; + __shared_mutex_base __base; public: shared_mutex() : __base() {} _LIBCPP_INLINE_VISIBILITY ~shared_mutex() = default; @@ -201,7 +201,7 @@ public: class _LIBCPP_TYPE_VIS shared_timed_mutex { - __shared_mutex_base __base; + __shared_mutex_base __base; public: shared_timed_mutex(); _LIBCPP_INLINE_VISIBILITY ~shared_timed_mutex() = default; diff --git a/libcxx/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp b/libcxx/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp deleted file mode 100644 index 7e4fe22..0000000 --- a/libcxx/test/libcxx/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_mangling.pass.cpp +++ /dev/null @@ -1,37 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// UNSUPPORTED: libcpp-has-no-threads - -// TODO(EricWF) Investigate why typeid(...).name() returns a different string -// on GCC 4.9 but not newer GCCs. -// XFAIL: gcc-4.9 -// XFAIL: windows - -// THIS TESTS C++03 EXTENSIONS. - -// - -// template class lock_guard; - -// Test that the the variadic lock guard implementation mangles the same in -// C++11 and C++03. This is important since the mangling of `lock_guard` depends -// on it being declared as a variadic template, even in C++03. - -// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD -#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD -#include -#include -#include -#include - -int main() { - const std::string expect = "NSt3__110lock_guardIJNS_5mutexEEEE"; - assert(typeid(std::lock_guard).name() == expect); -} diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp index a15405f..fffd087 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp @@ -15,11 +15,16 @@ // explicit lock_guard(mutex_type& m); +// template lock_guard(lock_guard<_Mutex>) +// -> lock_guard<_Mutex>; // C++17 + #include #include #include #include +#include "test_macros.h" + std::mutex m; typedef std::chrono::system_clock Clock; @@ -47,4 +52,9 @@ int main() std::this_thread::sleep_for(ms(250)); m.unlock(); t.join(); + +#ifdef __cpp_deduction_guides + std::lock_guard lg(m); + static_assert((std::is_same>::value), "" ); +#endif } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp deleted file mode 100644 index 0ad16e2..0000000 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex_cxx03.pass.cpp +++ /dev/null @@ -1,21 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// UNSUPPORTED: libcpp-has-no-threads -// - -// template class lock_guard; - -// Test that the variadic lock guard implementation compiles in all standard -// dialects, including C++03, even though it is forward declared using -// variadic templates. - -// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD -#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD -#include "mutex.pass.cpp" // Use the existing non-variadic test diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/adopt_lock.pass.cpp similarity index 71% rename from libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp rename to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/adopt_lock.pass.cpp index 81fc0d3..7816538 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_adopt_lock.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/adopt_lock.pass.cpp @@ -8,18 +8,17 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: libcpp-has-no-threads -// UNSUPPORTED: c++98, c++03 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // -// template class lock_guard; +// template class scoped_lock; -// lock_guard(Mutex&..., adopt_lock_t); +// scoped_lock(Mutex&..., adopt_lock_t); -// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD -#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD #include #include +#include "test_macros.h" struct TestMutex { bool locked = false; @@ -36,12 +35,22 @@ struct TestMutex { int main() { { - using LG = std::lock_guard<>; + using LG = std::scoped_lock<>; LG lg(std::adopt_lock); } { + TestMutex m1; + using LG = std::scoped_lock; + m1.lock(); + { + LG lg(m1, std::adopt_lock); + assert(m1.locked); + } + assert(!m1.locked); + } + { TestMutex m1, m2; - using LG = std::lock_guard; + using LG = std::scoped_lock; m1.lock(); m2.lock(); { LG lg(m1, m2, std::adopt_lock); @@ -51,7 +60,7 @@ int main() } { TestMutex m1, m2, m3; - using LG = std::lock_guard; + using LG = std::scoped_lock; m1.lock(); m2.lock(); m3.lock(); { LG lg(m1, m2, m3, std::adopt_lock); diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/assign.fail.cpp similarity index 66% rename from libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp rename to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/assign.fail.cpp index 1b4c9d4..a054729 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_assign.fail.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/assign.fail.cpp @@ -8,17 +8,16 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: libcpp-has-no-threads -// UNSUPPORTED: c++98, c++03 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // -// template class lock_guard; +// template class scoped_lock; -// lock_guard& operator=(lock_guard const&) = delete; +// scoped_lock& operator=(scoped_lock const&) = delete; -// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD -#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD #include +#include "test_macros.h" int main() { @@ -26,18 +25,24 @@ int main() M m0, m1, m2; M om0, om1, om2; { - using LG = std::lock_guard<>; + using LG = std::scoped_lock<>; LG lg1, lg2; lg1 = lg2; // expected-error{{overload resolution selected deleted operator '='}} } { - using LG = std::lock_guard; + using LG = std::scoped_lock; + LG lg1(m0); + LG lg2(om0); + lg1 = lg2; // expected-error{{overload resolution selected deleted operator '='}} + } + { + using LG = std::scoped_lock; LG lg1(m0, m1); LG lg2(om0, om1); lg1 = lg2; // expected-error{{overload resolution selected deleted operator '='}} } { - using LG = std::lock_guard; + using LG = std::scoped_lock; LG lg1(m0, m1, m2); LG lg2(om0, om1, om2); lg1 = lg2; // expected-error{{overload resolution selected deleted operator '='}} diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/copy.fail.cpp similarity index 65% rename from libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp rename to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/copy.fail.cpp index c7fd0e9..5075a42 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_copy.fail.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/copy.fail.cpp @@ -8,34 +8,38 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: libcpp-has-no-threads -// UNSUPPORTED: c++98, c++03 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // -// template class lock_guard; +// template class scoped_lock; -// lock_guard(lock_guard const&) = delete; +// scoped_lock(scoped_lock const&) = delete; -// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD -#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD #include +#include "test_macros.h" int main() { using M = std::mutex; M m0, m1, m2; { - using LG = std::lock_guard<>; + using LG = std::scoped_lock<>; const LG Orig; LG Copy(Orig); // expected-error{{call to deleted constructor of 'LG'}} } { - using LG = std::lock_guard; + using LG = std::scoped_lock; + const LG Orig(m0); + LG Copy(Orig); // expected-error{{call to deleted constructor of 'LG'}} + } + { + using LG = std::scoped_lock; const LG Orig(m0, m1); LG Copy(Orig); // expected-error{{call to deleted constructor of 'LG'}} } { - using LG = std::lock_guard; + using LG = std::scoped_lock; const LG Orig(m0, m1, m2); LG Copy(Orig); // expected-error{{call to deleted constructor of 'LG'}} } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/mutex.fail.cpp similarity index 69% rename from libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp rename to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/mutex.fail.cpp index 1eef7e2..7bb4673 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.fail.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/mutex.fail.cpp @@ -8,17 +8,16 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: libcpp-has-no-threads -// UNSUPPORTED: c++98, c++03 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // -// template class lock_guard; +// template class scoped_lock; -// explicit lock_guard(Mutex&...); +// explicit scoped_lock(Mutex&...); -// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD -#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD #include +#include "test_macros.h" template void test_conversion(LG) {} @@ -29,19 +28,25 @@ int main() M m0, m1, m2; M n0, n1, n2; { - using LG = std::lock_guard<>; + using LG = std::scoped_lock<>; LG lg = {}; // expected-error{{chosen constructor is explicit in copy-initialization}} test_conversion({}); // expected-error{{no matching function for call}} ((void)lg); } { - using LG = std::lock_guard; + using LG = std::scoped_lock; + LG lg = {m0}; // expected-error{{chosen constructor is explicit in copy-initialization}} + test_conversion({n0}); // expected-error{{no matching function for call}} + ((void)lg); + } + { + using LG = std::scoped_lock; LG lg = {m0, m1}; // expected-error{{chosen constructor is explicit in copy-initialization}} test_conversion({n0, n1}); // expected-error{{no matching function for call}} ((void)lg); } { - using LG = std::lock_guard; + using LG = std::scoped_lock; LG lg = {m0, m1, m2}; // expected-error{{chosen constructor is explicit in copy-initialization}} test_conversion({n0, n1, n2}); // expected-error{{no matching function for call}} } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/mutex.pass.cpp similarity index 61% rename from libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp rename to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/mutex.pass.cpp index 8d83ddf..ef39bbc 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_mutex.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/mutex.pass.cpp @@ -8,19 +8,16 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: libcpp-has-no-threads -// UNSUPPORTED: c++98, c++03 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // -// template class lock_guard; +// template class scoped_lock; -// explicit lock_guard(mutex_type& m); +// explicit scoped_lock(mutex_type& m); -// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD -#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD #include #include - #include "test_macros.h" struct TestMutex { @@ -68,11 +65,20 @@ struct TestMutexThrows { int main() { { - using LG = std::lock_guard<>; + using LG = std::scoped_lock<>; LG lg; } { - using LG = std::lock_guard; + using LG = std::scoped_lock; + TestMutex m1; + { + LG lg(m1); + assert(m1.locked); + } + assert(!m1.locked); + } + { + using LG = std::scoped_lock; TestMutex m1, m2; { LG lg(m1, m2); @@ -81,7 +87,7 @@ int main() assert(!m1.locked && !m2.locked); } { - using LG = std::lock_guard; + using LG = std::scoped_lock; TestMutex m1, m2, m3; { LG lg(m1, m2, m3); @@ -92,7 +98,18 @@ int main() #if !defined(TEST_HAS_NO_EXCEPTIONS) { using MT = TestMutexThrows; - using LG = std::lock_guard; + using LG = std::scoped_lock; + MT m1; + m1.throws_on_lock = true; + try { + LG lg(m1); + assert(false); + } catch (int) {} + assert(!m1.locked); + } + { + using MT = TestMutexThrows; + using LG = std::scoped_lock; MT m1, m2; m1.throws_on_lock = true; try { @@ -103,7 +120,7 @@ int main() } { using MT = TestMutexThrows; - using LG = std::lock_guard; + using LG = std::scoped_lock; MT m1, m2, m3; m2.throws_on_lock = true; try { @@ -113,4 +130,26 @@ int main() assert(!m1.locked && !m2.locked && !m3.locked); } #endif + +#ifdef __cpp_deduction_guides + { + TestMutex m1, m2, m3; + { + std::scoped_lock sl{}; + static_assert((std::is_same>::value), "" ); + } + { + std::scoped_lock sl{m1}; + static_assert((std::is_same>::value), "" ); + } + { + std::scoped_lock sl{m1, m2}; + static_assert((std::is_same>::value), "" ); + } + { + std::scoped_lock sl{m1, m2, m3}; + static_assert((std::is_same>::value), "" ); + } + } +#endif } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/types.pass.cpp similarity index 75% rename from libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp rename to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/types.pass.cpp index 600399d..6af3c6c 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/variadic_types.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.scoped/types.pass.cpp @@ -8,22 +8,21 @@ //===----------------------------------------------------------------------===// // // UNSUPPORTED: libcpp-has-no-threads -// UNSUPPORTED: c++98, c++03 +// UNSUPPORTED: c++98, c++03, c++11, c++14 // -// template -// class lock_guard +// template +// class scoped_lock // { // public: -// typedef Mutex mutex_type; +// typedef Mutex mutex_type; // only if sizeof...(Mutex) == 1 // ... // }; -// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD -#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD #include #include +#include "test_macros.h" struct NAT {}; @@ -41,39 +40,39 @@ constexpr bool has_mutex_type() { int main() { { - using T = std::lock_guard<>; + using T = std::scoped_lock<>; static_assert(!has_mutex_type(), ""); } { using M1 = std::mutex; - using T = std::lock_guard; + using T = std::scoped_lock; static_assert(std::is_same::value, ""); } { using M1 = std::recursive_mutex; - using T = std::lock_guard; + using T = std::scoped_lock; static_assert(std::is_same::value, ""); } { using M1 = std::mutex; using M2 = std::recursive_mutex; - using T = std::lock_guard; + using T = std::scoped_lock; static_assert(!has_mutex_type(), ""); } { using M1 = std::mutex; using M2 = std::recursive_mutex; - using T = std::lock_guard; + using T = std::scoped_lock; static_assert(!has_mutex_type(), ""); } { using M1 = std::mutex; - using T = std::lock_guard; + using T = std::scoped_lock; static_assert(!has_mutex_type(), ""); } { using M1 = std::recursive_mutex; - using T = std::lock_guard; + using T = std::scoped_lock; static_assert(!has_mutex_type(), ""); } } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp index f9a5370..ac33806 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp @@ -18,6 +18,9 @@ // explicit shared_lock(mutex_type& m); +// template shared_lock(shared_lock<_Mutex>) +// -> shared_lock<_Mutex>; // C++17 + #include #include #include @@ -92,4 +95,9 @@ int main() t.join(); q.join(); } + +#ifdef __cpp_deduction_guides + std::shared_lock sl(m); + static_assert((std::is_same>::value), "" ); +#endif } diff --git a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp index 1f7217a..ca8bc69 100644 --- a/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp +++ b/libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp @@ -15,11 +15,16 @@ // explicit unique_lock(mutex_type& m); +// template unique_lock(unique_lock<_Mutex>) +// -> unique_lock<_Mutex>; // C++17 + #include #include #include #include +#include "test_macros.h" + std::mutex m; typedef std::chrono::system_clock Clock; @@ -47,4 +52,9 @@ int main() std::this_thread::sleep_for(ms(250)); m.unlock(); t.join(); + +#ifdef __cpp_deduction_guides + std::unique_lock ul(m); + static_assert((std::is_same>::value), "" ); +#endif } diff --git a/libcxx/www/cxx1z_status.html b/libcxx/www/cxx1z_status.html index 906585f..2354eb7 100644 --- a/libcxx/www/cxx1z_status.html +++ b/libcxx/www/cxx1z_status.html @@ -75,7 +75,7 @@ P0006R0LWGAdopt Type Traits Variable Templates for C++17.KonaComplete3.8 P0092R1LWGPolishing <chrono>KonaComplete3.8 P0007R1LWGConstant View: A proposal for a std::as_const helper function template.KonaComplete3.8 - P0156R0LWGVariadic lock_guard(rev 3).KonaComplete (ABI V2 Only)3.9 + P0156R0LWGVariadic lock_guard(rev 3).KonaReverted in Kona3.9 P0074R0LWGMaking std::owner_less more flexibleKonaComplete3.8 P0013R1LWGLogical type traits rev 2KonaComplete3.8 @@ -142,7 +142,7 @@ P0517R0LWGMake future_error ConstructibleIssaquahComplete4.0 P0521R0LWGProposed Resolution for CA 14 (shared_ptr use_count/unique)IssaquahNothing to don/a - P0156R2LWGVariadic Lock guardKona + P0156R2LWGVariadic Lock guard(rev 5)KonaComplete5.0 P0270R3CWGRemoving C dependencies from signal handler wordingKona P0298R3CWGA byte type definitionKona P0317R1LWGDirectory Entry Caching for FilesystemKona @@ -489,7 +489,7 @@ -

Last Updated: 6-Mar-2017

+

Last Updated: 23-Mar-2017

-- 2.7.4