Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/latch
1 // <latch> -*- C++ -*- 2 3 // Copyright (C) 2020-2025 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file include/latch 26 * This is a Standard C++ Library header. 27 */ 28 29 #ifndef _GLIBCXX_LATCH 30 #define _GLIBCXX_LATCH 1 31 32 #ifdef _GLIBCXX_SYSHDR 33 #pragma GCC system_header 34 #endif 35 36 #include <bits/requires_hosted.h> // concurrency 37 38 #define __glibcxx_want_latch 39 #include <bits/version.h> 40 41 #ifdef __cpp_lib_latch // C++ >= 20 && atomic_wait 42 #include <bits/atomic_base.h> 43 #include <ext/numeric_traits.h> 44 #include <utility> // cmp_equal, cmp_less_equal, etc. 45 46 namespace std _GLIBCXX_VISIBILITY(default) 47 { 48 _GLIBCXX_BEGIN_NAMESPACE_VERSION 49 50 class latch 51 { 52 public: 53 static constexpr ptrdiff_t 54 max() noexcept 55 { 56 using __gnu_cxx::__int_traits; 57 constexpr auto __max = __int_traits<__detail::__platform_wait_t>::__max; 58 if constexpr (std::cmp_less(__max, __PTRDIFF_MAX__)) 59 return __max; 60 return __PTRDIFF_MAX__; 61 } 62 63 constexpr explicit 64 latch(ptrdiff_t __expected) noexcept 65 : _M_a(__expected) 66 { __glibcxx_assert(__expected >= 0 && __expected <= max()); } 67 68 ~latch() = default; 69 70 latch(const latch&) = delete; 71 latch& operator=(const latch&) = delete; 72 73 _GLIBCXX_ALWAYS_INLINE void 74 count_down(ptrdiff_t __update = 1) 75 { 76 __glibcxx_assert(__update >= 0 && __update <= max()); 77 auto const __old = __atomic_impl::fetch_sub(&_M_a, __update, 78 memory_order::release); 79 if (std::cmp_equal(__old, __update)) 80 __atomic_impl::notify_all(&_M_a); 81 else 82 __glibcxx_assert(std::cmp_less(__update, __old)); 83 } 84 85 _GLIBCXX_ALWAYS_INLINE bool 86 try_wait() const noexcept 87 { return __atomic_impl::load(&_M_a, memory_order::acquire) == 0; } 88 89 _GLIBCXX_ALWAYS_INLINE void 90 wait() const noexcept 91 { 92 auto const __pred = [this] { return this->try_wait(); }; 93 std::__atomic_wait_address(&_M_a, __pred); 94 } 95 96 _GLIBCXX_ALWAYS_INLINE void 97 arrive_and_wait(ptrdiff_t __update = 1) noexcept 98 { 99 count_down(__update); 100 wait(); 101 } 102 103 private: 104 alignas(__detail::__platform_wait_alignment) 105 __detail::__platform_wait_t _M_a; 106 }; 107 _GLIBCXX_END_NAMESPACE_VERSION 108 } // namespace 109 #endif // __cpp_lib_latch 110 #endif // _GLIBCXX_LATCH