////
Copyright 2023 Christian Mazakas
Distributed under the Boost Software License, Version 1.0.
https://www.boost.org/LICENSE_1_0.txt
////

[#latch]
# <boost/compat/latch.hpp>
:idprefix: latch_

## Description

The header `<boost/compat/latch.hpp>` implements, in a portable way, the C++20
`<latch>` header.

`latch` is a single-use barrier which counts downwards, enabling synchronization
between a set of threads. The counter can be manually decremented by any value,
but decrementing below zero causes undefined behavior. The maximum number of waiters is
specified to be `boost::compat::latch::max()`.

## Example

```cpp
std::ptrdiff_t const num_threads = 16;
boost::compat::latch l(num_threads);

std::vector<std::thread> threads;
for (int i = 0; i < num_threads; ++i) {
  threads.emplace_back([&l] {
    // do some preliminary work here...

    // block until all threads have reached this statement
    l.arrive_and_wait();

    // continue with further work...
  });
}

for (auto& t: threads) { t.join(); }
```

## Synopsis

```cpp
namespace boost
{
namespace compat
{

class latch {
  explicit latch(std::ptrdiff_t expected);

  latch(latch const &) = delete;
  latch &operator=(latch const &) = delete;

  ~latch() = default;

  void count_down(std::ptrdiff_t n = 1);
  bool try_wait() const noexcept;
  void wait() const;
  void arrive_and_wait(std::ptrdiff_t n = 1);

  static constexpr std::ptrdiff_t max() noexcept;
};

} // namespace compat
} // namespace boost
```

## Constructors

### Counter Constructor

```cpp
explicit latch(std::ptrdiff_t expected);
```

[horizontal]
Preconditions:;; `expected >= 0 && expected \<= boost::compat::latch::max()`.
Effects:;; Constructs a latch with an internal counter value of `expected`.

### Copy Constructor

```cpp
latch(latch const &) = delete;
```

`latch` is not copyable or movable.

## Member Functions

### count_down

```cpp
void count_down(std::ptrdiff_t n = 1);
```

[horizontal]
Preconditions:;; `n` must not be larger than the current internal counter's value.
Effects:;; Decrements the internal counter by `n`.

### try_wait

```cpp
bool try_wait() const noexcept;
```

Returns a boolean indicating whether or not the latch's internal counter has reached 0 (`true`) or not (`false`).

### wait

```cpp
void wait() const;
```

Blocks the current thread until the internal counter has reached 0.


### arrive_and_wait

```cpp
void arrive_and_wait(std::ptrdiff_t n = 1);
```

[horizontal]
Preconditions:;; `n` must not be larger than the current internal counter's value.
Effects:;; Decrements the internal counter by `n` and if the counter non-zero, blocks the current thread.

### max

```cpp
static constexpr std::ptrdiff_t max() noexcept;
```

Returns an implementation-defined number representing the maximum amount of waiters. Currently PTRDIFF_MAX.
