[libc] Fix improper initialization of `StorageType` (#75610)
[llvm-project.git] / libcxx / include / latch
blob0d1b3713ea62dc6de10be6b7d2f5fc48cf71559f
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_LATCH
11 #define _LIBCPP_LATCH
14     latch synopsis
16 namespace std
19   class latch
20   {
21   public:
22     static constexpr ptrdiff_t max() noexcept;
24     constexpr explicit latch(ptrdiff_t __expected);
25     ~latch();
27     latch(const latch&) = delete;
28     latch& operator=(const latch&) = delete;
30     void count_down(ptrdiff_t __update = 1);
31     bool try_wait() const noexcept;
32     void wait() const;
33     void arrive_and_wait(ptrdiff_t __update = 1);
35   private:
36     ptrdiff_t __counter; // exposition only
37   };
43 #include <__assert> // all public C++ headers provide the assertion handler
44 #include <__atomic/atomic_base.h>
45 #include <__atomic/atomic_sync.h>
46 #include <__atomic/memory_order.h>
47 #include <__availability>
48 #include <__config>
49 #include <cstddef>
50 #include <limits>
51 #include <version>
53 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
54 #  pragma GCC system_header
55 #endif
57 #ifdef _LIBCPP_HAS_NO_THREADS
58 # error "<latch> is not supported since libc++ has been configured without support for threads."
59 #endif
61 _LIBCPP_PUSH_MACROS
62 #include <__undef_macros>
64 #if _LIBCPP_STD_VER >= 14
66 _LIBCPP_BEGIN_NAMESPACE_STD
68 class latch
70     __atomic_base<ptrdiff_t> __a_;
72 public:
73     static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept {
74         return numeric_limits<ptrdiff_t>::max();
75     }
77     inline _LIBCPP_HIDE_FROM_ABI
78     constexpr explicit latch(ptrdiff_t __expected) : __a_(__expected)
79     {
80         _LIBCPP_ASSERT_UNCATEGORIZED(__expected >= 0,
81                                      "latch::latch(ptrdiff_t): latch cannot be "
82                                      "initialized with a negative value");
83         _LIBCPP_ASSERT_UNCATEGORIZED(__expected <= max(),
84                                      "latch::latch(ptrdiff_t): latch cannot be "
85                                      "initialized with a value greater than max()");
86     }
88     _LIBCPP_HIDE_FROM_ABI ~latch() = default;
89     latch(const latch&) = delete;
90     latch& operator=(const latch&) = delete;
92     inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
93     void count_down(ptrdiff_t __update = 1)
94     {
95         _LIBCPP_ASSERT_UNCATEGORIZED(
96             __update >= 0, "latch::count_down called with a negative value");
97         auto const __old = __a_.fetch_sub(__update, memory_order_release);
98         _LIBCPP_ASSERT_UNCATEGORIZED(
99             __update <= __old, "latch::count_down called with a value greater "
100                                "than the internal counter");
101         if (__old == __update)
102             __a_.notify_all();
103     }
104     inline _LIBCPP_HIDE_FROM_ABI
105     bool try_wait() const noexcept
106     {
107         return 0 == __a_.load(memory_order_acquire);
108     }
109     inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
110     void wait() const
111     {
112         __cxx_atomic_wait(&__a_.__a_, [this]() -> bool {
113             return try_wait();
114         });
115     }
116     inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI
117     void arrive_and_wait(ptrdiff_t __update = 1)
118     {
119         _LIBCPP_ASSERT_UNCATEGORIZED(
120             __update >= 0, "latch::arrive_and_wait called with a negative value");
121         // other preconditions on __update are checked in count_down()
123         count_down(__update);
124         wait();
125     }
128 _LIBCPP_END_NAMESPACE_STD
130 #endif // _LIBCPP_STD_VER >= 14
132 _LIBCPP_POP_MACROS
134 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
135 #  include <atomic>
136 #endif
138 #endif //_LIBCPP_LATCH