From 9da8dc3bac40030de5b0c126326e9007079f0e4c Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 13 Apr 2024 19:35:02 +0800 Subject: [PATCH] Check "`is_clock_v`" for thread utilities before C++20 --- stl/inc/__msvc_chrono.hpp | 24 +++++++++++++++++------- stl/inc/condition_variable | 4 +--- stl/inc/future | 4 +--- stl/inc/mutex | 24 ++++++------------------ stl/inc/shared_mutex | 16 ++++------------ stl/inc/thread | 4 +--- 6 files changed, 30 insertions(+), 46 deletions(-) diff --git a/stl/inc/__msvc_chrono.hpp b/stl/inc/__msvc_chrono.hpp index f6857a61307..cad459cf814 100644 --- a/stl/inc/__msvc_chrono.hpp +++ b/stl/inc/__msvc_chrono.hpp @@ -52,6 +52,21 @@ namespace chrono { }; #if _HAS_CXX20 + _EXPORT_STD template + constexpr bool is_clock_v = requires { + typename _Clock::rep; + typename _Clock::period; + typename _Clock::duration; + typename _Clock::time_point; + _Clock::is_steady; + _Clock::now(); + }; + _EXPORT_STD template + struct is_clock : bool_constant> {}; + + template + constexpr bool _Is_clock_v = is_clock_v<_Clock>; +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv template constexpr bool _Is_clock_v = false; @@ -59,13 +74,8 @@ namespace chrono { constexpr bool _Is_clock_v<_Clock, void_t> = - true; // TRANSITION, GH-602 - - _EXPORT_STD template - struct is_clock : bool_constant<_Is_clock_v<_Clock>> {}; - _EXPORT_STD template - constexpr bool is_clock_v = _Is_clock_v<_Clock>; -#endif // _HAS_CXX20 + true; +#endif // ^^^ !_HAS_CXX20 ^^^ _EXPORT_STD template > class duration; diff --git a/stl/inc/condition_variable b/stl/inc/condition_variable index 93f84507535..29bd6f50fc6 100644 --- a/stl/inc/condition_variable +++ b/stl/inc/condition_variable @@ -92,9 +92,7 @@ public: template cv_status wait_until(_Lock& _Lck, const chrono::time_point<_Clock, _Duration>& _Abs_time) { // wait until time point -#if _HAS_CXX20 - static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); -#endif // _HAS_CXX20 + static_assert(chrono::_Is_clock_v<_Clock>, "Clock type required"); const auto _Now = _Clock::now(); using _Common_duration = decltype(_Abs_time - _Now); const _Common_duration _Rel_time = (_Abs_time <= _Now) ? _Common_duration::zero() : _Abs_time - _Now; diff --git a/stl/inc/future b/stl/inc/future index fd41ec8c94b..6778c109923 100644 --- a/stl/inc/future +++ b/stl/inc/future @@ -761,9 +761,7 @@ public: template future_status wait_until(const chrono::time_point<_Clock, _Dur>& _Abs_time) const { // wait until time point -#if _HAS_CXX20 - static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); -#endif // _HAS_CXX20 + static_assert(chrono::_Is_clock_v<_Clock>, "Clock type required"); if (!valid()) { _Throw_future_error2(future_errc::no_state); } diff --git a/stl/inc/mutex b/stl/inc/mutex index 49291830219..3fdf82f199d 100644 --- a/stl/inc/mutex +++ b/stl/inc/mutex @@ -162,9 +162,7 @@ public: _NODISCARD_CTOR_LOCK unique_lock(_Mutex& _Mtx, const chrono::time_point<_Clock, _Duration>& _Abs_time) : _Pmtx(_STD addressof(_Mtx)), _Owns(_Pmtx->try_lock_until(_Abs_time)) { // construct and lock with timeout -#if _HAS_CXX20 - static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); -#endif // _HAS_CXX20 + static_assert(chrono::_Is_clock_v<_Clock>, "Clock type required"); } _NODISCARD_CTOR_LOCK unique_lock(unique_lock&& _Other) noexcept : _Pmtx(_Other._Pmtx), _Owns(_Other._Owns) { @@ -216,9 +214,7 @@ public: template _NODISCARD_TRY_CHANGE_STATE bool try_lock_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) { -#if _HAS_CXX20 - static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); -#endif // _HAS_CXX20 + static_assert(chrono::_Is_clock_v<_Clock>, "Clock type required"); _Validate(); _Owns = _Pmtx->try_lock_until(_Abs_time); return _Owns; @@ -585,9 +581,7 @@ public: template cv_status wait_until(unique_lock& _Lck, const chrono::time_point<_Clock, _Duration>& _Abs_time) { // wait until time point -#if _HAS_CXX20 - static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); -#endif // _HAS_CXX20 + static_assert(chrono::_Is_clock_v<_Clock>, "Clock type required"); #if _CONTAINER_DEBUG_LEVEL > 0 _STL_VERIFY( _Lck.owns_lock(), "wait_until's caller must own the lock argument (N4958 [thread.condition.condvar]/17)"); @@ -614,9 +608,7 @@ public: bool wait_until( unique_lock& _Lck, const chrono::time_point<_Clock, _Duration>& _Abs_time, _Predicate _Pred) { // wait for signal with timeout and check predicate -#if _HAS_CXX20 - static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); -#endif // _HAS_CXX20 + static_assert(chrono::_Is_clock_v<_Clock>, "Clock type required"); while (!_Pred()) { if (wait_until(_Lck, _Abs_time) == cv_status::timeout) { return _Pred(); @@ -696,9 +688,7 @@ public: template _NODISCARD_TRY_CHANGE_STATE bool try_lock_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) { // try to lock the mutex with timeout -#if _HAS_CXX20 - static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); -#endif // _HAS_CXX20 + static_assert(chrono::_Is_clock_v<_Clock>, "Clock type required"); unique_lock _Lock(_My_mutex); if (!_My_cond.wait_until(_Lock, _Abs_time, _UInt_is_zero{_My_locked})) { return false; @@ -792,9 +782,7 @@ public: template _NODISCARD_TRY_CHANGE_STATE bool try_lock_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) { // try to lock the mutex with timeout -#if _HAS_CXX20 - static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); -#endif // _HAS_CXX20 + static_assert(chrono::_Is_clock_v<_Clock>, "Clock type required"); const thread::id _Tid = this_thread::get_id(); unique_lock _Lock(_My_mutex); diff --git a/stl/inc/shared_mutex b/stl/inc/shared_mutex index b8c088b2af5..3c67475e645 100644 --- a/stl/inc/shared_mutex +++ b/stl/inc/shared_mutex @@ -107,9 +107,7 @@ public: template _NODISCARD_TRY_CHANGE_STATE bool try_lock_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) { // try to lock until time point -#if _HAS_CXX20 - static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); -#endif // _HAS_CXX20 + static_assert(chrono::_Is_clock_v<_Clock>, "Clock type required"); auto _Not_writing = [this] { return !_Writing; }; auto _Zero_readers = [this] { return _Readers == 0; }; unique_lock _Lock(_Mymtx); @@ -168,9 +166,7 @@ public: template _NODISCARD_TRY_CHANGE_STATE bool try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) { // try to lock non-exclusive until absolute time -#if _HAS_CXX20 - static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); -#endif // _HAS_CXX20 + static_assert(chrono::_Is_clock_v<_Clock>, "Clock type required"); const auto _Can_acquire = [this] { return !_Writing && _Readers < _Max_readers; }; unique_lock _Lock(_Mymtx); @@ -240,9 +236,7 @@ public: _NODISCARD_CTOR_LOCK shared_lock(mutex_type& _Mtx, const chrono::time_point<_Clock, _Duration>& _Abs_time) : _Pmtx(_STD addressof(_Mtx)), _Owns(_Mtx.try_lock_shared_until(_Abs_time)) { // construct with mutex and try to lock until absolute time -#if _HAS_CXX20 - static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); -#endif // _HAS_CXX20 + static_assert(chrono::_Is_clock_v<_Clock>, "Clock type required"); } ~shared_lock() noexcept { @@ -294,9 +288,7 @@ public: template _NODISCARD_TRY_CHANGE_STATE bool try_lock_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) { // try to lock the mutex until _Abs_time -#if _HAS_CXX20 - static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); -#endif // _HAS_CXX20 + static_assert(chrono::_Is_clock_v<_Clock>, "Clock type required"); _Validate(); _Owns = _Pmtx->try_lock_shared_until(_Abs_time); return _Owns; diff --git a/stl/inc/thread b/stl/inc/thread index 323aa266f89..d96369fd4db 100644 --- a/stl/inc/thread +++ b/stl/inc/thread @@ -206,9 +206,7 @@ namespace this_thread { _EXPORT_STD template void sleep_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) { -#if _HAS_CXX20 - static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); -#endif // _HAS_CXX20 + static_assert(chrono::_Is_clock_v<_Clock>, "Clock type required"); for (;;) { const auto _Now = _Clock::now(); if (_Abs_time <= _Now) {