%!TEX root = std.tex
\rSec0[thread]{Concurrency support library}

\rSec1[thread.general]{General}

\pnum
The following subclauses describe components to create and manage
threads\iref{intro.multithread}, perform mutual exclusion, and communicate conditions
and values
between threads, as summarized in \tref{thread.summary}.

\begin{libsumtab}{Concurrency support library summary}{thread.summary}
\ref{thread.req}      & Requirements          &                               \\ \rowsep
\ref{thread.stoptoken}& Stop tokens           & \tcode{<stop_token>}          \\ \rowsep
\ref{thread.threads}  & Threads               & \tcode{<thread>}              \\ \rowsep
\ref{atomics}         & Atomic operations     &
  \tcode{<atomic>}, \tcode{<stdatomic.h>} \\ \rowsep
\ref{thread.mutex}    & Mutual exclusion      &
  \tcode{<mutex>}, \tcode{<shared_mutex>} \\ \rowsep
\ref{thread.condition}& Condition variables   & \tcode{<condition_variable>}  \\ \rowsep
\ref{thread.sema}     & Semaphores & \tcode{<semaphore>} \\ \rowsep
\ref{thread.coord}    & Coordination types & \tcode{<latch>}, \tcode{<barrier>} \\ \rowsep
\ref{futures}         & Futures               & \tcode{<future>}              \\ \rowsep
\ref{saferecl}        & Safe reclamation      & \tcode{<rcu>}, \tcode{<hazard_pointer>}  \\
\end{libsumtab}

\rSec1[thread.req]{Requirements}

\rSec2[thread.req.paramname]{Template parameter names}

\pnum
Throughout this Clause, the names of template parameters are used to express type
requirements.
\tcode{Predicate} is a function object type\iref{function.objects}.
Let \tcode{pred} denote an lvalue of type \tcode{Predicate}.
Then the expression \tcode{pred()} shall be well-formed and
the type \tcode{decltype(pred())} shall model
\exposconcept{boolean-testable}\iref{concept.booleantestable}.
The return value of \tcode{pred()}, converted to \tcode{bool},
yields \tcode{true} if the corresponding test condition is satisfied, and
\tcode{false} otherwise.
If a template parameter is named \tcode{Clock},
the corresponding template argument shall be a type \tcode{C}
that meets the \oldconcept{Clock} requirements\iref{time.clock.req};
the program is ill-formed if \tcode{is_clock_v<C>} is \tcode{false}.

\rSec2[thread.req.exception]{Exceptions}

\pnum
Some functions described in this Clause are specified to throw exceptions of type
\tcode{system_error}\iref{syserr.syserr}. Such exceptions are thrown if
any of the function's error conditions is detected or
a call to
an operating system or other underlying API results in an error that prevents the
library function from
meeting its specifications. Failure to allocate storage is reported as described
in~\ref{res.on.exception.handling}.

\begin{example}
Consider a function in this Clause that is specified to throw exceptions of type
\tcode{system_error} and specifies error conditions that include
\tcode{operation_not_permitted} for a thread that does not have the privilege to
perform the operation. Assume that, during the execution of this function, an \tcode{errno}
of \tcode{EPERM} is reported by a POSIX API call used by the implementation. Since POSIX
specifies an \tcode{errno} of \tcode{EPERM} when ``the caller does not have the privilege
to perform the operation'', the implementation maps \tcode{EPERM} to an
\tcode{error_condition} of \tcode{operation_not_permitted}\iref{syserr} and an exception
of type \tcode{system_error} is thrown.
\end{example}

\pnum
The \tcode{error_code} reported by such an exception's \tcode{code()} member function
compares equal to one of the conditions specified in the function's error condition
element.

\rSec2[thread.req.native]{Native handles}

\pnum
Several classes described in this Clause have members \tcode{native_handle_type} and
\tcode{native_handle}. The presence of these members and their semantics is
\impldef{presence and meaning of \tcode{native_handle_type} and \tcode{native_handle}}.
\begin{note}
These members allow implementations to provide access
to implementation details. Their names are specified to facilitate portable compile-time
detection. Actual use of these members is inherently non-portable.
\end{note}

\rSec2[thread.req.timing]{Timing specifications}

\pnum
Several functions described in this Clause take an argument to specify a timeout. These
timeouts are specified as either a \tcode{duration} or a \tcode{time_point} type as
specified in~\ref{time}.

\pnum
Implementations necessarily have some delay in returning from a timeout. Any overhead in
interrupt response, function return, and scheduling induces a ``quality of implementation''
delay, expressed as duration $D_i$. Ideally, this delay would be zero. Further, any contention for
processor and memory resources induces a ``quality of management'' delay, expressed as duration
$D_m$. The delay durations may vary from timeout to timeout, but in all cases shorter is better.

\pnum
The functions whose names end in \tcode{_for} take an argument that
specifies a duration. These functions produce relative timeouts. Implementations
should use a steady clock to measure time for these functions.
\begin{footnote}
Implementations for which standard time units are meaningful will typically
have a steady clock within their hardware implementation.
\end{footnote}
Given a duration
argument $D_t$, the real-time duration of the timeout is $D_t + D_i + D_m$.

\pnum
The functions whose names end in \tcode{_until} take an argument that specifies a time
point. These functions produce absolute timeouts. Implementations should use the clock
specified in the time point to measure time for these functions. Given a clock time point
argument $C_t$, the clock time point of the return from timeout should be $C_t + D_i + D_m$
when the clock is not adjusted during the timeout. If the clock is adjusted to the time $C_a$
during the timeout, the behavior should be as follows:
\begin{itemize}
\item
If $C_a > C_t$, the waiting function should wake as soon as possible, i.e., $C_a + D_i + D_m$,
since the timeout is already satisfied.
This specification may result in the total
duration of the wait decreasing when measured against a steady clock.

\item
If $C_a \leq C_t$, the waiting function should not time out until \tcode{Clock::now()} returns a
time $C_n \geq C_t$, i.e., waking at $C_t + D_i + D_m$.
\begin{note}
When the clock is adjusted
backwards, this specification can result in the total duration of the wait increasing when
measured against a steady clock. When the clock is adjusted forwards, this specification can
result in the total duration of the wait decreasing when measured against a steady clock.
\end{note}
\end{itemize}

An implementation returns from such a timeout at any point from the time specified above to
the time it would return from a steady-clock relative timeout on the difference between $C_t$
and the time point of the call to the \tcode{_until} function.

\recommended
Implementations
should decrease the duration of the wait when the clock is adjusted forwards.

\pnum
\begin{note}
If the clock is not synchronized with a steady clock, e.g., a CPU time clock, these
timeouts can fail to provide useful functionality.
\end{note}

\pnum
The resolution of timing provided by an implementation depends on both operating system
and hardware. The finest resolution provided by an implementation is called the
\term{native resolution}.

\pnum
Implementation-provided clocks that are used for these functions meet the
\oldconcept{TrivialClock} requirements\iref{time.clock.req}.

\pnum
A function that takes an argument which specifies a timeout will throw if,
during its execution, a clock, time point, or time duration throws an exception.
Such exceptions are referred to as \term{timeout-related exceptions}.
\begin{note}
Instantiations of clock, time point and duration types supplied by
the implementation as specified in~\ref{time.clock} do not throw exceptions.
\end{note}

\rSec2[thread.req.lockable]{Requirements for \oldconcept{Lockable} types}

\rSec3[thread.req.lockable.general]{General}

\pnum
An \defn{execution agent} is an entity such as a thread that may perform work in parallel with
other execution agents.
\begin{note}
Implementations or users can introduce other kinds of
agents such as processes or thread-pool tasks.
\end{note}
The calling agent is determined by
context, e.g., the calling thread that contains the call, and so on.

\pnum
\begin{note}
Some lockable objects are ``agent oblivious'' in that they work for any
execution agent model because they do not determine or store the agent's ID (e.g., an
ordinary spin lock).
\end{note}

\pnum
The standard library templates \tcode{unique_lock}\iref{thread.lock.unique},
\tcode{shared_lock}\iref{thread.lock.shared},
\tcode{scoped_lock}\iref{thread.lock.scoped},
\tcode{lock_guard}\iref{thread.lock.guard}, \tcode{lock},
\tcode{try_lock}\iref{thread.lock.algorithm}, and
\tcode{condition_variable_any}\iref{thread.condition.condvarany} all operate on user-supplied
lockable objects. The \oldconcept{BasicLockable} requirements, the \oldconcept{Lockable} requirements,
the \oldconcept{TimedLockable} requirements,
the \oldconcept{SharedLockable} requirements, and
the \oldconcept{SharedTimedLock\-able} requirements
list the requirements imposed by these library types
in order to acquire or release ownership of a \tcode{lock} by a given execution agent.
\begin{note}
The nature of any lock ownership and any synchronization it entails are not part
of these requirements.
\end{note}

\pnum
A lock on an object \tcode{m} is said to be
\begin{itemize}
\item
a \defnadj{non-shared}{lock} if it is acquired by a call to
\tcode{lock},
\tcode{try_lock},
\tcode{try_lock_for}, or
\tcode{try_lock_until} on \tcode{m}, or
\item
a \defnadj{shared}{lock} if it is acquired by a call to
\tcode{lock_shared},
\tcode{try_lock_shared},
\tcode{try_lock_shared_for}, or
\tcode{try_lock_shared_until} on \tcode{m}.
\end{itemize}
\begin{note}
Only the method of lock acquisition is considered;
the nature of any lock ownership is not part of these definitions.
\end{note}

\rSec3[thread.req.lockable.basic]{\oldconcept{BasicLockable} requirements}

\pnum
A type \tcode{L} meets the \defnoldconcept{BasicLockable} requirements if the following expressions are
well-formed and have the specified semantics (\tcode{m} denotes a value of type \tcode{L}).

\begin{itemdecl}
m.lock()
\end{itemdecl}

\begin{itemdescr}
\pnum
\indextext{block (execution)}%
\effects
Blocks until a lock can be acquired for the current execution agent. If an exception
is thrown then a lock shall not have been acquired for the current execution agent.
\end{itemdescr}

\begin{itemdecl}
m.unlock()
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The current execution agent holds a non-shared lock on \tcode{m}.

\pnum
\effects
Releases a non-shared lock on \tcode{m} held by the current execution agent.

\pnum
\throws
Nothing.
\end{itemdescr}

\rSec3[thread.req.lockable.req]{\oldconcept{Lockable} requirements}

\pnum
A type \tcode{L} meets the \defnoldconcept{Lockable} requirements if it meets the \oldconcept{BasicLockable}
requirements and the following expressions are well-formed and have the specified semantics
(\tcode{m} denotes a value of type \tcode{L}).

\begin{itemdecl}
m.try_lock()
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to acquire a lock for the current execution agent without blocking. If an
exception is thrown then a lock shall not have been acquired for the current execution agent.

\pnum
\returntype \tcode{bool}.

\pnum
\returns
\tcode{true} if the lock was acquired, otherwise \tcode{false}.
\end{itemdescr}

\rSec3[thread.req.lockable.timed]{\oldconcept{TimedLockable} requirements}

\pnum
A type \tcode{L} meets the \defnoldconcept{TimedLockable} requirements if it meets the \oldconcept{Lockable}
requirements and the following expressions are well-formed and have the specified semantics
(\tcode{m} denotes a value of type \tcode{L}, \tcode{rel_time} denotes a value of a
specialization of \tcode{duration}\iref{time.duration}, and \tcode{abs_time} denotes a value
of a specialization of \tcode{time_point}\iref{time.point}).

\begin{itemdecl}
m.try_lock_for(rel_time)
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to acquire a lock for the current execution agent within the relative
timeout\iref{thread.req.timing} specified by \tcode{rel_time}. The function will not return
within the timeout specified by \tcode{rel_time} unless it has obtained a lock on \tcode{m}
for the current execution agent. If an exception is thrown then a lock has not been
acquired for the current execution agent.

\pnum
\returntype \tcode{bool}.

\pnum
\returns
\tcode{true} if the lock was acquired, otherwise \tcode{false}.
\end{itemdescr}

\begin{itemdecl}
m.try_lock_until(abs_time)
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to acquire a lock for the current execution agent before the absolute
timeout\iref{thread.req.timing} specified by \tcode{abs_time}. The function will not return
before the timeout specified by \tcode{abs_time} unless it has obtained a lock on \tcode{m} for
the current execution agent. If an exception is thrown then a lock has not been acquired
for the current execution agent.

\pnum
\returntype \tcode{bool}.

\pnum
\returns
\tcode{true} if the lock was acquired, otherwise \tcode{false}.
\end{itemdescr}

\rSec3[thread.req.lockable.shared]{\oldconcept{SharedLockable} requirements}

\pnum
A type \tcode{L} meets the \defnoldconcept{SharedLockable} requirements if
the following expressions are well-formed, have the specified semantics, and
the expression \tcode{m.try_lock_shared()} has type \tcode{bool}
(\tcode{m} denotes a value of type \tcode{L}):

\begin{itemdecl}
m.lock_shared()
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Blocks until a lock can be acquired for the current execution agent.
If an exception is thrown then a lock shall not have been acquired for
the current execution agent.
\end{itemdescr}

\begin{itemdecl}
m.try_lock_shared()
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to acquire a lock for the current execution agent without blocking.
If an exception is thrown then a lock shall not have been acquired for
the current execution agent.

\pnum
\returns
\tcode{true} if the lock was acquired, \tcode{false} otherwise.
\end{itemdescr}

\begin{itemdecl}
m.unlock_shared()
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The current execution agent holds a shared lock on \tcode{m}.

\pnum
\effects
Releases a shared lock on \tcode{m} held by the current execution agent.

\pnum
\throws
Nothing.
\end{itemdescr}

\rSec3[thread.req.lockable.shared.timed]{\oldconcept{SharedTimedLockable} requirements}

\pnum
A type \tcode{L} meets the \defnoldconcept{SharedTimedLockable} requirements if
it meets the \oldconcept{SharedLockable} requirements, and
the following expressions are well-formed, have type \tcode{bool}, and
have the specified semantics
(\tcode{m} denotes a value of type \tcode{L},
\tcode{rel_time} denotes a value of a specialization of \tcode{chrono::duration}, and
\tcode{abs_time} denotes a value of a specialization of \tcode{chrono::time_point}).

\begin{itemdecl}
m.try_lock_shared_for(rel_time)
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to acquire a lock for the current execution agent within
the relative timeout\iref{thread.req.timing} specified by \tcode{rel_time}.
The function will not return within the timeout specified by \tcode{rel_time}
unless it has obtained a lock on \tcode{m} for the current execution agent.
If an exception is thrown then a lock has not been acquired for
the current execution agent.

\pnum
\returns
\tcode{true} if the lock was acquired, \tcode{false} otherwise.
\end{itemdescr}

\begin{itemdecl}
m.try_lock_shared_until(abs_time)
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to acquire a lock for the current execution agent before
the absolute timeout\iref{thread.req.timing} specified by \tcode{abs_time}.
The function will not return before the timeout specified by \tcode{abs_time}
unless it has obtained a lock on \tcode{m} for the current execution agent.
If an exception is thrown then a lock has not been acquired for
the current execution agent.

\pnum
\returns
\tcode{true} if the lock was acquired, \tcode{false} otherwise.
\end{itemdescr}

\rSec1[thread.stoptoken]{Stop tokens}

\rSec2[thread.stoptoken.intro]{Introduction}

\pnum
Subclause \ref{thread.stoptoken} describes components that can be used
to asynchronously request that an operation stops execution in a timely manner,
typically because the result is no longer required.
Such a request is called a \defn{stop request}.

\pnum
The concepts
\exposconcept{stoppable-source},
\libconcept{stoppable_token}, and
\exposconcept{stoppable-callback-for}
specify the required syntax and semantics of
shared access to a \defn{stop state}.
Any object modeling \exposconcept{stoppable-source},
\libconcept{stoppable_token}, or
\exposconcept{stoppable-callback-for}
that refers to the same stop state is
an \defn{associated}
\exposconcept{stoppable-source},
\libconcept{stoppable_token}, or
\exposconcept{stoppable-callback-for},
respectively.

\pnum
An object of a type that models \libconcept{stoppable_token}
can be passed to an operation that can either
\begin{itemize}
 \item actively poll the token to check if there has been a stop request, or
 \item register a callback that
        will be called in the event that a stop request is made.
\end{itemize}
A stop request made via an object
whose type models \exposconcept{stoppable-source}
will be visible to
all associated \libconcept{stoppable_token} and
\exposconcept{stoppable-source} objects.
Once a stop request has been made it cannot be withdrawn
(a subsequent stop request has no effect).

\pnum
Callbacks registered via an object
whose type models \exposconcept{stoppable-callback-for}
are called when a stop request is first made
by any associated \exposconcept{stoppable-source} object.

\pnum
The types \tcode{stop_source} and \tcode{stop_token} and
the class template \tcode{stop_callback} implement
the semantics of shared ownership of a stop state.
The last remaining owner of the stop state automatically releases
the resources associated with the stop state.

\pnum
An object of type \tcode{inplace_stop_source}
is the sole owner of its stop state.
An object of type \tcode{inplace_stop_token} or
of a specialization of the class template \tcode{inplace_stop_callback}
does not participate in ownership of its associated stop state.
\begin{note}
They are for use when all uses of the associated token and callback objects
are known to nest within the lifetime of the \tcode{inplace_stop_source} object.
\end{note}

\rSec2[thread.stoptoken.syn]{Header \tcode{<stop_token>} synopsis}

\indexheader{stop_token}%
\begin{codeblock}
namespace std {
  // \ref{stoptoken.concepts}, stop token concepts
  template<class CallbackFn, class Token, class Initializer = CallbackFn>
    concept @\exposconcept{stoppable-callback-for}@ = @\seebelow@;           // \expos

  template<class Token>
    concept @\libconcept{stoppable_token}@ = @\seebelow@;

  template<class Token>
    concept @\libconcept{unstoppable_token}@ = @\seebelow@;

  template<class Source>
    concept @\exposconcept{stoppable-source}@ = @\seebelow@;                 // \expos

  // \ref{stoptoken}, class \tcode{stop_token}
  class stop_token;

  // \ref{stopsource}, class \tcode{stop_source}
  class stop_source;

  // no-shared-stop-state indicator
  struct @\libglobal{nostopstate_t}@ {
    explicit nostopstate_t() = default;
  };
  inline constexpr nostopstate_t @\libglobal{nostopstate}@{};

  // \ref{stopcallback}, class template \tcode{stop_callback}
  template<class Callback>
    class stop_callback;

  // \ref{stoptoken.never}, class \tcode{never_stop_token}
  class never_stop_token;

  // \ref{stoptoken.inplace}, class \tcode{inplace_stop_token}
  class inplace_stop_token;

  // \ref{stopsource.inplace}, class \tcode{inplace_stop_source}
  class inplace_stop_source;

  // \ref{stopcallback.inplace}, class template \tcode{inplace_stop_callback}
  template<class CallbackFn>
    class inplace_stop_callback;

  template<class T, class CallbackFn>
    using @\libglobal{stop_callback_for_t}@ = T::template callback_type<CallbackFn>;
}
\end{codeblock}

\rSec2[stoptoken.concepts]{Stop token concepts}

\pnum
The exposition-only \exposconcept{stoppable-callback-for} concept
checks for a callback compatible with a given \tcode{Token} type.
\begin{codeblock}
template<class CallbackFn, class Token, class Initializer = CallbackFn>
  concept @\defexposconcept{stoppable-callback-for}@ =                          // \expos
    @\libconcept{invocable}@<CallbackFn> &&
    @\libconcept{constructible_from}@<CallbackFn, Initializer> &&
    requires { typename stop_callback_for_t<Token, CallbackFn>; } &&
    @\libconcept{constructible_from}@<stop_callback_for_t<Token, CallbackFn>, const Token&, Initializer>;
\end{codeblock}

\pnum
Let \tcode{t} and \tcode{u} be distinct, valid objects of type \tcode{Token}
that reference the same logical stop state;
let \tcode{init} be an expression such that
\tcode{\libconcept{same_as}<decltype(init), Initializer>} is \tcode{true}; and
let \tcode{SCB} denote the type \tcode{stop_callback_for_t<Token, CallbackFn>}.

\pnum
The concept
\tcode{\exposconcept{stoppable-callback-for}<CallbackFn, Token, Initializer>}
is modeled only if:
\begin{itemize}
\item
The following concepts are modeled:
\begin{itemize}
\item \tcode{\libconcept{constructible_from}<SCB, Token, Initializer>}
\item \tcode{\libconcept{constructible_from}<SCB, Token\&, Initializer>}
\item \tcode{\libconcept{constructible_from}<SCB, const Token, Initializer>}
\end{itemize}

\item
An object of type \tcode{SCB} has
an associated callback function of type \tcode{CallbackFn}.
Let \tcode{scb} be an object of type \tcode{SCB} and
let \tcode{callback_fn} denote \tcode{scb}'s associated callback function.
Direct-non-list-initializing \tcode{scb} from
arguments \tcode{t} and \tcode{init}
shall execute a \defnadj{stoppable callback}{registration} as follows:
\begin{itemize}
\item
If \tcode{t.stop_possible()} is \tcode{true}:
\begin{itemize}
\item
\tcode{callback_fn} shall be direct-initialized with \tcode{init}.
\item
Construction of \tcode{scb} shall only throw exceptions
thrown by the initialization of \tcode{callback_fn} from \tcode{init}.
\item
The callback invocation \tcode{std::forward<CallbackFn>(callback_fn)()}
shall be registered with \tcode{t}'s associated stop state as follows:
\begin{itemize}
\item
If \tcode{t.stop_requested()} evaluates to \tcode{false}
at the time of registration,
the callback invocation is added to the stop state's list of callbacks
such that \tcode{std::forward<CallbackFn>(\newline callback_fn)()} is evaluated
if a stop request is made on the stop state.
\item
Otherwise, \tcode{std::forward<CallbackFn>(callback_fn)()}
shall be immediately evaluated
on the thread executing \tcode{scb}'s constructor, and
the callback invocation shall not be added to the list of callback invocations.
\end{itemize}
If the callback invocation was added to stop state's list of callbacks,
\tcode{scb} shall be associated with the stop state.
\end{itemize}
\begin{note}
If \tcode{t.stop_possible()} is \tcode{false},
there is no requirement
that the initialization of \tcode{scb}
causes the initialization of \tcode{callback_fn}.
\end{note}
\end{itemize}

\item
Destruction of \tcode{scb} shall execute
a \defnadj{stoppable}{callback deregistration} as follows (in order):
\begin{itemize}
\item
If the constructor of \tcode{scb} did not register
a callback invocation with \tcode{t}'s stop state,
then the stoppable callback deregistration shall have no effect
other than destroying \tcode{callback_fn} if it was constructed.
\item
Otherwise, the invocation of \tcode{callback_fn} shall be removed
from the associated stop state.
\item
If \tcode{callback_fn} is concurrently executing on another thread,
then the stoppable callback deregistration shall block\iref{defns.block}
until the invocation of \tcode{callback_fn} returns
such that the return from the invocation of \tcode{callback_fn}
strongly happens before\iref{intro.races}
the destruction of \tcode{callback_fn}.
\item
If \tcode{callback_fn} is executing on the current thread,
then the destructor shall not block
waiting for the return from the invocation of \tcode{callback_fn}.
\item
A stoppable callback deregistration shall not block
on the completion of the invocation of some other callback
registered with the same logical stop state.
\item
The stoppable callback deregistration shall destroy \tcode{callback_fn}.
\end{itemize}
\end{itemize}

\pnum
The \libconcept{stoppable_token} concept checks
for the basic interface of a stop token
that is copyable and allows polling to see if stop has been requested and
also whether a stop request is possible.
The \libconcept{unstoppable_token} concept checks
for a \libconcept{stoppable_token} type that does not allow stopping.
\begin{codeblock}
template<template<class> class>
  struct @\exposid{check-type-alias-exists}@;                               // \expos

template<class Token>
  concept @\deflibconcept{stoppable_token}@ =
    requires (const Token tok) {
      typename @\exposid{check-type-alias-exists}@<Token::template callback_type>;
      { tok.stop_requested() } noexcept -> @\libconcept{same_as}@<bool>;
      { tok.stop_possible() } noexcept -> @\libconcept{same_as}@<bool>;
      { Token(tok) } noexcept;                  // see implicit expression variations\iref{concepts.equality}
    } &&
    @\libconcept{copyable}@<Token> &&
    @\libconcept{equality_comparable}@<Token>;

template<class Token>
  concept @\deflibconcept{unstoppable_token}@ =
    @\libconcept{stoppable_token}@<Token> &&
    requires (const Token tok) {
      requires bool_constant<(!tok.stop_possible())>::value;
    };
\end{codeblock}

\pnum
An object whose type models \libconcept{stoppable_token}
has at most one associated logical stop state.
A \libconcept{stoppable_token} object with no associated stop state
is said to be \defn{disengaged}.

\pnum
Let \tcode{SP} be an evaluation of \tcode{t.stop_possible()}
that is \tcode{false}, and
let SR be an evaluation of \tcode{t.stop_requested()} that is \tcode{true}.

\pnum
The type \tcode{Token} models \libconcept{stoppable_token} only if:
\begin{itemize}
\item
Any evaluation of \tcode{u.stop_possible()} or \tcode{u.stop_requested()}
that happens after\iref{intro.races} \tcode{SP} is \tcode{false}.
\item
Any evaluation of \tcode{u.stop_possible()} or \tcode{u.stop_requested()}
that happens after \tcode{SR} is \tcode{true}.
\item
For any types \tcode{CallbackFn} and \tcode{Initializer} such that
\tcode{\exposconcept{stoppable-callback-for}<CallbackFn, To\-ken, Initializer>}
is satisfied,
\tcode{\exposconcept{stoppable-callback-for}<CallbackFn, Token, Initializer>}
is modeled.
\item
If \tcode{t} is disengaged,
evaluations of \tcode{t.stop_possible()} and \tcode{t.stop_requested()}
are \tcode{false}.
\item
If \tcode{t} and \tcode{u} reference the same stop state, or
if both \tcode{t} and \tcode{u} are disengaged,
\tcode{t == u} is \tcode{true}; otherwise, it is \tcode{false}.
\end{itemize}

\pnum
An object
whose type models the exposition-only \exposconcept{stoppable-source} concept
can be queried
whether stop has been requested (\tcode{stop_requested}) and
whether stop is possible (\tcode{stop_possible}).
It is a factory for associated stop tokens (\tcode{get_token}), and
a stop request can be made on it (\tcode{request_stop}).
It maintains a list of registered stop callback invocations
that it executes when a stop request is first made.
\begin{codeblock}
template<class Source>
  concept @\defexposconcept{stoppable-source}@ =                                    // \expos
    requires (Source& src, const Source csrc) {         // see implicit expression variations\iref{concepts.equality}
      { csrc.get_token() } -> stoppable_token;
      { csrc.stop_possible() } noexcept -> @\libconcept{same_as}@<bool>;
      { csrc.stop_requested() } noexcept -> @\libconcept{same_as}@<bool>;
      { src.request_stop() } -> @\libconcept{same_as}@<bool>;
    };
\end{codeblock}

\pnum
An object whose type models \exposconcept{stoppable-source} has
at most one associated logical stop state.
If it has no associated stop state, it is said to be disengaged.
Let \tcode{s} be an object whose type models \exposconcept{stoppable-source} and
that is disengaged.
\tcode{s.stop_possible()} and \tcode{s.stop_requested()} shall be \tcode{false}.

\pnum
Let \tcode{t} be an object whose type models \exposconcept{stoppable-source}.
If \tcode{t} is disengaged,
\tcode{t.get_token()} shall return a disengaged stop token;
otherwise, it shall return
a stop token that is associated with the stop state of \tcode{t}.

\pnum
Calls to the member functions
\tcode{request_stop}, \tcode{stop_requested}, and \tcode{stop_possible} and
similarly named member functions
on associated \libconcept{stoppable_token} objects
do not introduce data races.
A call to \tcode{request_stop} that returns \tcode{true} synchronizes with
a call to \tcode{stop_requested} on
an associated
\libconcept{stoppable_token} or \exposconcept{stoppable-source} object
that returns \tcode{true}.
Registration of a callback synchronizes with the invocation of that callback.

\pnum
If the \exposconcept{stoppable-source} is disengaged,
\tcode{request_stop} shall have no effect and return \tcode{false}.
Otherwise, it shall execute a \defnadj{stop request}{operation}
on the associated stop state.
A stop request operation determines
whether the stop state has received a stop request, and
if not, makes a stop request.
The determination and making of the stop request shall happen atomically,
as-if by a read-modify-write operation\iref{intro.races}.
If the request was made,
the stop state's registered callback invocations shall be
synchronously executed.
If an invocation of a callback exits via an exception
then \tcode{terminate} shall be invoked\iref{except.terminate}.
\begin{note}
No constraint is placed on the order
in which the callback invocations are executed.
\end{note}
\tcode{request_stop} shall return \tcode{true} if a stop request was made, and
\tcode{false} otherwise.
After a call to \tcode{request_stop} either
a call to \tcode{stop_possible} shall return \tcode{false} or
a call to \tcode{stop_requested} shall return \tcode{true}.
\begin{note}
A stop request includes notifying
all condition variables of type \tcode{condition_variable_any}
temporarily registered during
an interruptible wait\iref{thread.condvarany.intwait}.
\end{note}

\rSec2[stoptoken]{Class \tcode{stop_token}}%
\indexlibraryglobal{stop_token}%

\rSec3[stoptoken.general]{General}

\pnum
\indexlibraryglobal{stop_token}%
The class \tcode{stop_token} models the concept \libconcept{stoppable_token}.
It shares ownership of its stop state, if any,
with its associated \tcode{stop_source} object\iref{stopsource} and
any \tcode{stop_token} objects to which it compares equal.

\begin{codeblock}
namespace std {
  class stop_token {
  public:
    template<class CallbackFn>
      using @\libmember{callback_type}{stop_token}@ = stop_callback<CallbackFn>;

    stop_token() noexcept = default;

    // \ref{stoptoken.mem}, member functions
    void swap(stop_token&) noexcept;

    bool stop_requested() const noexcept;
    bool stop_possible() const noexcept;

    bool operator==(const stop_token& rhs) noexcept = default;

  private:
    shared_ptr<@\unspec@> @\exposid{stop-state}@;                           // \expos
  };
}
\end{codeblock}

\pnum
\exposid{stop-state} refers to the \tcode{stop_token}'s associated stop state.
A \tcode{stop_token} object is disengaged when \exposid{stop-state} is empty.

\rSec3[stoptoken.mem]{Member functions}

\indexlibrarymember{swap}{stop_token}%
\begin{itemdecl}
void swap(stop_token& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
@\exposid{stop-state}@.swap(rhs.@\exposid{stop-state}@);
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{stop_requested}{stop_token}%
\begin{itemdecl}
bool stop_requested() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if \exposid{stop-state} refers to a stop state
that has received a stop request;
otherwise, \tcode{false}.
\end{itemdescr}

\indexlibrarymember{stop_possible}{stop_token}%
\begin{itemdecl}
bool stop_possible() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{false} if
\begin{itemize}
\item \tcode{*this} is disengaged, or
\item a stop request was not made
      and there are no associated \tcode{stop_source} objects;
\end{itemize}
otherwise, \tcode{true}.
\end{itemdescr}

\rSec2[stopsource]{Class \tcode{stop_source}}%
\indexlibraryglobal{stop_source}%

\rSec3[stopsource.general]{General}

\begin{codeblock}
namespace std {
  class stop_source {
  public:
    // \ref{stopsource.cons}, constructors, copy, and assignment
    stop_source();
    explicit stop_source(nostopstate_t) noexcept {}

    // \ref{stopsource.mem}, member functions
    void swap(stop_source&) noexcept;

    stop_token get_token() const noexcept;
    bool stop_possible() const noexcept;
    bool stop_requested() const noexcept;
    bool request_stop() noexcept;

    bool operator==(const stop_source& rhs) noexcept = default;

  private:
    shared_ptr<@\unspec@> @\exposid{stop-state}@;                         // \expos
  };
}
\end{codeblock}

\pnum
\exposid{stop-state} refers to the \tcode{stop_source}'s associated stop state.
A \tcode{stop_source} object is disengaged when \exposid{stop-state} is empty.

\pnum
\tcode{stop_source} models
\exposconcept{stoppable-source},
\libconcept{copyable},
\libconcept{equality_comparable}, and
\libconcept{swappable}.

\rSec3[stopsource.cons]{Constructors, copy, and assignment}

\indexlibraryctor{stop_source}%
\begin{itemdecl}
stop_source();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \exposid{stop-state} with a pointer to a new stop state.

\pnum
\ensures
\tcode{stop_possible()} is \tcode{true}
and \tcode{stop_requested()} is \tcode{false}.

\pnum
\throws
\tcode{bad_alloc} if memory cannot be allocated for the stop state.
\end{itemdescr}

\rSec3[stopsource.mem]{Member functions}

\indexlibrarymember{swap}{stop_source}%
\begin{itemdecl}
void swap(stop_source& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
@\exposid{stop-state}@.swap(rhs.@\exposid{stop-state}@);
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{get_token}{stop_source}%
\begin{itemdecl}
stop_token get_token() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{stop_token()} if \tcode{stop_possible()} is \tcode{false};
otherwise a new associated \tcode{stop_token} object;
i.e., its \exposid{stop-state} member is equal to
the \exposid{stop-state} member of \tcode{*this}.
\end{itemdescr}

\indexlibrarymember{stop_possible}{stop_source}%
\begin{itemdecl}
bool stop_possible() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\exposidnc{stop-state} != nullptr}.
\end{itemdescr}

\indexlibrarymember{stop_requested}{stop_source}%
\begin{itemdecl}
bool stop_requested() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if \exposid{stop-state} refers to a stop state
that has received a stop request;
otherwise, \tcode{false}.
\end{itemdescr}

\indexlibrarymember{request_stop}{stop_source}%
\begin{itemdecl}
bool request_stop() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Executes a stop request operation\iref{stoptoken.concepts} on
the associated stop state, if any.
\end{itemdescr}

\rSec2[stopcallback]{Class template \tcode{stop_callback}}%
\indexlibraryglobal{stop_callback}%

\rSec3[stopcallback.general]{General}

\pnum
\indexlibraryglobal{stop_callback}%
\begin{codeblock}
namespace std {
  template<class CallbackFn>
  class stop_callback {
  public:
    using @\libmember{callback_type}{stop_callback}@ = CallbackFn;

    // \ref{stopcallback.cons}, constructors and destructor
    template<class Initializer>
      explicit stop_callback(const stop_token& st, Initializer&& init)
        noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);
    template<class Initializer>
      explicit stop_callback(stop_token&& st, Initializer&& init)
        noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);
    ~stop_callback();

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

  private:
    CallbackFn @\exposid{callback-fn}@;                                     // \expos
  };

  template<class CallbackFn>
    stop_callback(stop_token, CallbackFn) -> stop_callback<CallbackFn>;
}
\end{codeblock}

\pnum
\mandates
\tcode{stop_callback} is instantiated with an argument for the
template parameter \tcode{CallbackFn}
that satisfies both \libconcept{invocable}
and \libconcept{destructible}.

\pnum
\remarks
For a type \tcode{Initializer},
if
\tcode{\exposconcept{stoppable-callback-for}<CallbackFn, stop_token, Initiali\-zer>}
is satisfied, then
\tcode{\exposconcept{stoppable-callback-for}<CallbackFn, stop_token, Initializer>} is modeled.
The exposition-only \exposid{callback-fn} member is
the associated callback function\iref{stoptoken.concepts} of
\tcode{stop_callback<\newline CallbackFn>} objects.

\rSec3[stopcallback.cons]{Constructors and destructor}

\indexlibraryctor{stop_callback}%
\begin{itemdecl}
template<class Initializer>
  explicit stop_callback(const stop_token& st, Initializer&& init)
    noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);

template<class Initializer>
  explicit stop_callback(stop_token&& st, Initializer&& init)
    noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{CallbackFn} and \tcode{Initializer} satisfy
\tcode{\libconcept{constructible_from}<CallbackFn, Initiali\-zer>}.

\pnum
\effects
Initializes \exposid{callback-fn} with \tcode{std::forward<Initializer>(init)}
and executes a stoppable callback registration\iref{stoptoken.concepts}.
If a callback is registered with \tcode{st}'s shared stop state,
then \tcode{*this} acquires shared ownership of that stop state.
\end{itemdescr}

\indexlibrarydtor{stop_callback}%
\begin{itemdecl}
~stop_callback();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Executes a stoppable callback deregistration\iref{stoptoken.concepts} and
releases ownership of the stop state, if any.
\end{itemdescr}

\rSec2[stoptoken.never]{Class \tcode{never_stop_token}}

\pnum
The class \tcode{never_stop_token} models
the \libconcept{unstoppable_token} concept.
It provides a stop token interface,
but also provides static information
that a stop is never possible nor requested.
\indexlibraryglobal{never_stop_token}%
\begin{codeblock}
namespace std {
  class never_stop_token {
    struct @\exposid{callback-type}@ {                                      // \expos
      explicit @\exposid{callback-type}@(never_stop_token, auto&&) noexcept {}
    };
  public:
    template<class>
      using @\libmember{callback_type}{never_stop_token}@ = @\exposid{callback-type}@;

    static constexpr bool @\libmember{stop_requested}{never_stop_token}@() noexcept { return false; }
    static constexpr bool @\libmember{stop_possible}{never_stop_token}@() noexcept { return false; }

    bool operator==(const never_stop_token&) const = default;
  };
}
\end{codeblock}

\rSec2[stoptoken.inplace]{Class \tcode{inplace_stop_token}}

\rSec3[stoptoken.inplace.general]{General}

\pnum
The class \tcode{inplace_stop_token} models
the concept \libconcept{stoppable_token}.
It references the stop state of
its associated \tcode{inplace_stop_source} object\iref{stopsource.inplace},
if any.
\indexlibraryglobal{inplace_stop_token}%
\begin{codeblock}
namespace std {
  class inplace_stop_token {
  public:
    template<class CallbackFn>
      using @\libmember{callback_type}{inplace_stop_token}@ = inplace_stop_callback<CallbackFn>;

    inplace_stop_token() = default;
    bool operator==(const inplace_stop_token&) const = default;

    // \ref{stoptoken.inplace.mem}, member functions
    bool stop_requested() const noexcept;
    bool stop_possible() const noexcept;
    void swap(inplace_stop_token&) noexcept;

  private:
    const inplace_stop_source* @\exposid{stop-source}@ = nullptr;           // \expos
  };
}
\end{codeblock}

\rSec3[stoptoken.inplace.mem]{Member functions}

\indexlibrarymember{swap}{inplace_stop_token}%
\begin{itemdecl}
void swap(inplace_stop_token& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Exchanges the values of \exposid{stop-source} and \tcode{rhs.\exposid{stop-source}}.
\end{itemdescr}

\indexlibrarymember{stop_requested}{inplace_stop_token}%
\begin{itemdecl}
bool stop_requested() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return @\exposid{stop-source}@ != nullptr && @\exposid{stop-source}@->stop_requested();
\end{codeblock}

\pnum
\begin{note}
As specified in \ref{basic.life},
the behavior of \tcode{stop_requested} is undefined
unless the call strongly happens before the start of
the destructor of the associated \tcode{inplace_stop_source} object, if any.
\end{note}
\end{itemdescr}

\indexlibrarymember{stop_possible}{inplace_stop_token}%
\begin{itemdecl}
stop_possible() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\exposidnc{stop-source} != nullptr}.

\pnum
\begin{note}
As specified in \ref{basic.stc.general},
the behavior of \tcode{stop_possible} is implementation-defined
unless the call strongly happens before
the end of the storage duration of
the associated \tcode{inplace_stop_source} object, if any.
\end{note}
\end{itemdescr}

\rSec2[stopsource.inplace]{Class \tcode{inplace_stop_source}}

\rSec3[stopsource.inplace.general]{General}

\pnum
The class \tcode{inplace_stop_source} models \exposconcept{stoppable-source}.

\indexlibraryglobal{inplace_stop_source}%
\begin{codeblock}
namespace std {
  class inplace_stop_source {
  public:
    // \ref{stopsource.inplace.cons}, constructors
    constexpr inplace_stop_source() noexcept;

    inplace_stop_source(inplace_stop_source&&) = delete;
    inplace_stop_source(const inplace_stop_source&) = delete;
    inplace_stop_source& operator=(inplace_stop_source&&) = delete;
    inplace_stop_source& operator=(const inplace_stop_source&) = delete;
    ~inplace_stop_source();

    // \ref{stopsource.inplace.mem}, stop handling
    constexpr inplace_stop_token get_token() const noexcept;
    static constexpr bool @\libmember{stop_possible}{inplace_stop_source}@() noexcept { return true; }
    bool stop_requested() const noexcept;
    bool request_stop() noexcept;
  };
}
\end{codeblock}

\rSec3[stopsource.inplace.cons]{Constructors}

\indexlibraryctor{inplace_stop_source}%
\begin{itemdecl}
constexpr inplace_stop_source() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes a new stop state inside \tcode{*this}.

\pnum
\ensures
\tcode{stop_requested()} is \tcode{false}.
\end{itemdescr}

\rSec3[stopsource.inplace.mem]{Member functions}

\indexlibrarymember{get_token}{inplace_stop_source}%
\begin{itemdecl}
constexpr inplace_stop_token get_token() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A new associated \tcode{inplace_stop_token} object
whose \exposid{stop-source} member is equal to \tcode{this}.
\end{itemdescr}

\indexlibrarymember{stop_requested}{inplace_stop_source}%
\begin{itemdecl}
bool stop_requested() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if the stop state inside \tcode{*this}
has received a stop request; otherwise, \tcode{false}.
\end{itemdescr}

\indexlibrarymember{request_stop}{inplace_stop_source}%
\begin{itemdecl}
bool request_stop() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Executes a stop request operation\iref{stoptoken.concepts}.

\pnum
\ensures
\tcode{stop_requested()} is \tcode{true}.
\end{itemdescr}

\rSec2[stopcallback.inplace]{Class template \tcode{inplace_stop_callback}}

\rSec3[stopcallback.inplace.general]{General}

\indexlibraryglobal{inplace_stop_callback}%
\begin{codeblock}
namespace std {
  template<class CallbackFn>
  class inplace_stop_callback {
  public:
    using @\libmember{callback_type}{inplace_stop_callback}@ = CallbackFn;

    // \ref{stopcallback.inplace.cons}, constructors and destructor
    template<class Initializer>
      explicit inplace_stop_callback(inplace_stop_token st, Initializer&& init)
        noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);
    ~inplace_stop_callback();

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

  private:
    CallbackFn @\exposid{callback-fn}@;                                     // \expos
  };

  template<class CallbackFn>
    inplace_stop_callback(inplace_stop_token, CallbackFn)
      -> inplace_stop_callback<CallbackFn>;
}
\end{codeblock}

\pnum
\mandates
\tcode{CallbackFn} satisfies both
\libconcept{invocable} and \libconcept{destructible}.

\pnum
\remarks
For a type \tcode{Initializer}, if
\begin{codeblock}
@\exposconcept{stoppable-callback-for}@<CallbackFn, inplace_stop_token, Initializer>
\end{codeblock}
is satisfied, then
\begin{codeblock}
@\exposconcept{stoppable-callback-for}@<CallbackFn, inplace_stop_token, Initializer>
\end{codeblock}
is modeled.
For an \tcode{inplace_stop_callback<CallbackFn>} object,
the exposition-only \exposid{callback-fn} member is
its associated callback function\iref{stoptoken.concepts}.

\rSec3[stopcallback.inplace.cons]{Constructors and destructor}

\indexlibraryctor{inplace_stop_callback}%
\begin{itemdecl}
template<class Initializer>
  explicit inplace_stop_callback(inplace_stop_token st, Initializer&& init)
    noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{\libconcept{constructible_from}<CallbackFn, Initializer>} is satisfied.

\pnum
\effects
Initializes \exposid{callback-fn} with \tcode{std::forward<Initializer>(init)}
and executes a stoppable callback registration\iref{stoptoken.concepts}.
\end{itemdescr}

\indexlibrarydtor{inplace_stop_callback}%
\begin{itemdecl}
~inplace_stop_callback();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Executes a stoppable callback deregistration\iref{stoptoken.concepts}.
\end{itemdescr}

\rSec1[thread.threads]{Threads}

\rSec2[thread.threads.general]{General}

\pnum
\ref{thread.threads} describes components that can be used to create and manage threads.
\begin{note}
These threads are intended to map one-to-one with operating system threads.
\end{note}

\rSec2[thread.syn]{Header \tcode{<thread>} synopsis}

\indexheader{thread}%
\begin{codeblock}
#include <compare>              // see \ref{compare.syn}

namespace std {
  // \ref{thread.thread.class}, class \tcode{thread}
  class thread;

  void swap(thread& x, thread& y) noexcept;

  // \ref{thread.jthread.class}, class \tcode{jthread}
  class jthread;

  // \ref{thread.thread.this}, namespace \tcode{this_thread}
  namespace this_thread {
    thread::id get_id() noexcept;

    void yield() noexcept;
    template<class Clock, class Duration>
      void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
    template<class Rep, class Period>
      void sleep_for(const chrono::duration<Rep, Period>& rel_time);
  }
}
\end{codeblock}

\rSec2[thread.thread.class]{Class \tcode{thread}}

\rSec3[thread.thread.class.general]{General}

\pnum
The class \tcode{thread} provides a mechanism to create a new thread of execution, to join with
a thread (i.e., wait for a thread to complete), and to perform other operations that manage and
query the state of a thread. A \tcode{thread} object uniquely represents a particular thread of
execution. That representation may be transferred to other \tcode{thread} objects in such a way
that no two \tcode{thread} objects simultaneously represent the same thread of execution. A
thread of execution is \term{detached} when no \tcode{thread} object represents that thread.
Objects of class \tcode{thread} can be in a state that does not represent a thread of
execution.
\begin{note}
A \tcode{thread} object does not represent a thread of execution after
default construction, after being moved from, or after a successful call to \tcode{detach} or
\tcode{join}.
\end{note}

\indexlibraryglobal{thread}%
\begin{codeblock}
namespace std {
  class thread {
  public:
    // \ref{thread.thread.id}, class \tcode{thread::id}
    class id;
    using native_handle_type = @\impdefnc@;         // see~\ref{thread.req.native}

    // construct/copy/destroy
    thread() noexcept;
    template<class F, class... Args> explicit thread(F&& f, Args&&... args);
    ~thread();
    thread(const thread&) = delete;
    thread(thread&&) noexcept;
    thread& operator=(const thread&) = delete;
    thread& operator=(thread&&) noexcept;

    // \ref{thread.thread.member}, members
    void swap(thread&) noexcept;
    bool joinable() const noexcept;
    void join();
    void detach();
    id get_id() const noexcept;
    native_handle_type native_handle();                         // see~\ref{thread.req.native}

    // static members
    static unsigned int hardware_concurrency() noexcept;
  };
}
\end{codeblock}

\rSec3[thread.thread.id]{Class \tcode{thread::id}}

\indexlibraryglobal{thread::id}%
\indexlibrarymember{thread}{id}%
\begin{codeblock}
namespace std {
  class thread::id {
  public:
    id() noexcept;
  };

  bool operator==(thread::id x, thread::id y) noexcept;
  strong_ordering operator<=>(thread::id x, thread::id y) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& out, thread::id id);

  template<class charT> struct formatter<thread::id, charT>;

  // hash support
  template<class T> struct hash;
  template<> struct hash<thread::id>;
}
\end{codeblock}

\pnum
An object of type \tcode{thread::id} provides a unique identifier for
each thread of execution and a single distinct value for all \tcode{thread}
objects that do not represent a thread of
execution\iref{thread.thread.class}. Each thread of execution has an
associated \tcode{thread::id} object that is not equal to the
\tcode{thread::id} object of any other thread of execution and that is not
equal to the \tcode{thread::id} object of any \tcode{thread} object that
does not represent threads of execution.

\pnum
The \defn{text representation} for
the character type \tcode{charT} of an object of type \tcode{thread::id}
is an unspecified sequence of \tcode{charT} such that,
for two objects of type \tcode{thread::id} \tcode{x} and \tcode{y},
if \tcode{x == y} is \tcode{true},
the \tcode{thread::id} objects have the same text representation, and
if \tcode{x != y} is \tcode{true},
the \tcode{thread::id} objects have distinct text representations.

\pnum
\tcode{thread::id} is a trivially copyable class\iref{class.prop}.
The library may reuse the value of a \tcode{thread::id} of a terminated thread that can no longer be joined.

\pnum
\begin{note}
Relational operators allow \tcode{thread::id} objects to be used as
keys in associative containers.
\end{note}

\indexlibraryctor{thread::id}%
\begin{itemdecl}
id() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
The constructed object does not represent a thread of execution.
\end{itemdescr}

\indexlibrarymember{operator==}{thread::id}%
\begin{itemdecl}
bool operator==(thread::id x, thread::id y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} only if \tcode{x} and \tcode{y} represent the same
thread of execution or neither \tcode{x} nor \tcode{y} represents a thread of
execution.
\end{itemdescr}

\indexlibrarymember{operator<=>}{thread::id}%
\begin{itemdecl}
strong_ordering operator<=>(thread::id x, thread::id y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
Let $P(\tcode{x}, \tcode{y})$ be
an unspecified total ordering over \tcode{thread::id}
as described in \ref{alg.sorting}.

\pnum
\returns
\tcode{strong_ordering::less} if $P(\tcode{x}, \tcode{y})$ is \tcode{true}.
Otherwise, \tcode{strong_ordering::greater}
if $P(\tcode{y}, \tcode{x})$ is \tcode{true}.
Otherwise, \tcode{strong_ordering::equal}.
\end{itemdescr}

\indexlibrarymember{operator<<}{thread::id}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& out, thread::id id);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Inserts the text representation for \tcode{charT} of \tcode{id} into
\tcode{out}.

\pnum
\returns
\tcode{out}.
\end{itemdescr}

\indexlibrary{\idxcode{formatter}!specializations!\idxcode{thread::id}}%
\begin{itemdecl}
template<class charT> struct formatter<thread::id, charT>;
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{formatter<thread::id, charT>} interprets \fmtgrammarterm{format-spec}
as a \fmtgrammarterm{thread-id-format-spec}.
The syntax of format specifications is as follows:

\begin{ncbnf}
\fmtnontermdef{thread-id-format-spec}\br
    \opt{fill-and-align} \opt{width}
\end{ncbnf}

\begin{note}
The productions \fmtgrammarterm{fill-and-align} and \fmtgrammarterm{width}
are described in \ref{format.string.std}.
\end{note}

\pnum
If the \fmtgrammarterm{align} option is omitted it defaults to \tcode{>}.

\pnum
A \tcode{thread::id} object is formatted by
writing its text representation for \tcode{charT} to the output
with additional padding and adjustments as specified by the format specifiers.
\end{itemdescr}

\indexlibrarymember{hash}{thread::id}%
\begin{itemdecl}
template<> struct hash<thread::id>;
\end{itemdecl}

\begin{itemdescr}
\pnum
The specialization is enabled\iref{unord.hash}.
\end{itemdescr}

\rSec3[thread.thread.constr]{Constructors}

\indexlibraryctor{thread}%
\begin{itemdecl}
thread() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The object does not represent a thread of execution.

\pnum
\ensures
\tcode{get_id() == id()}.
\end{itemdescr}

\indexlibraryctor{thread}%
\begin{itemdecl}
template<class F, class... Args> explicit thread(F&& f, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{remove_cvref_t<F>} is not the same type as \tcode{thread}.

\pnum
\mandates
The following are all \tcode{true}:
\begin{itemize}
\item \tcode{is_constructible_v<decay_t<F>, F>},
\item \tcode{(is_constructible_v<decay_t<Args>, Args> \&\& ...)}, and
\item \tcode{is_invocable_v<decay_t<F>, decay_t<Args>...>}.
\end{itemize}

\pnum
\effects
The new thread of execution executes
\begin{codeblock}
invoke(auto(std::forward<F>(f)),                // for \tcode{invoke}, see \ref{func.invoke}
       auto(std::forward<Args>(args))...)
\end{codeblock}
with the values produced by \tcode{auto}
being materialized\iref{conv.rval} in the constructing thread.
Any return value from this invocation is ignored.
\begin{note}
This implies that any exceptions not thrown from the invocation of the copy
of \tcode{f} will be thrown in the constructing thread, not the new thread.
\end{note}
If the invocation of \tcode{invoke} terminates with an uncaught exception,
\tcode{terminate} is invoked\iref{except.terminate}.

\pnum
\sync
The completion of the invocation of the constructor
synchronizes with the beginning of the invocation of the copy of \tcode{f}.

\pnum
\ensures
\tcode{get_id() != id()}. \tcode{*this} represents the newly started thread.

\pnum
\throws
\tcode{system_error} if unable to start the new thread.

\pnum
\errors
\begin{itemize}
\item \tcode{resource_unavailable_try_again} --- the system lacked the necessary
resources to create another thread, or the system-imposed limit on the number of
threads in a process would be exceeded.
\end{itemize}
\end{itemdescr}

\indexlibraryctor{thread}%
\begin{itemdecl}
thread(thread&& x) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{x.get_id() == id()} and \tcode{get_id()} returns the
value of \tcode{x.get_id()} prior to the start of construction.
\end{itemdescr}

\rSec3[thread.thread.destr]{Destructor}

\indexlibrarydtor{thread}%
\begin{itemdecl}
~thread();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{joinable()}, invokes \tcode{terminate}\iref{except.terminate}.
Otherwise, has no effects.
\begin{note}
Either implicitly detaching or joining a \tcode{joinable()} thread in its
destructor can result in difficult to debug correctness (for detach) or performance
(for join) bugs encountered only when an exception is thrown.
These bugs can be avoided by ensuring that
the destructor is never executed while the thread is still joinable.
\end{note}
\end{itemdescr}

\rSec3[thread.thread.assign]{Assignment}

\indexlibrarymember{operator=}{thread}%
\begin{itemdecl}
thread& operator=(thread&& x) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{joinable()}, invokes \tcode{terminate}\iref{except.terminate}.
Otherwise, assigns the
state of \tcode{x} to \tcode{*this} and sets \tcode{x} to a default constructed state.

\pnum
\ensures
\tcode{x.get_id() == id()} and \tcode{get_id()} returns the value of
\tcode{x.get_id()} prior to the assignment.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\rSec3[thread.thread.member]{Members}

\indexlibrarymember{swap}{thread}%
\begin{itemdecl}
void swap(thread& x) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Swaps the state of \tcode{*this} and \tcode{x}.
\end{itemdescr}

\indexlibrarymember{joinable}{thread}%
\begin{itemdecl}
bool joinable() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{get_id() != id()}.
\end{itemdescr}

\indexlibrarymember{join}{thread}%
\begin{itemdecl}
void join();
\end{itemdecl}

\begin{itemdescr}
\pnum
\indextext{block (execution)}%
\effects
Blocks until the thread represented by \tcode{*this} has completed.

\pnum
\sync
The completion of the thread represented by \tcode{*this} synchronizes with\iref{intro.multithread}
the corresponding successful
\tcode{join()} return.
\begin{note}
Operations on
\tcode{*this} are not synchronized.
\end{note}

\pnum
\ensures
The thread represented by \tcode{*this} has completed. \tcode{get_id() == id()}.

\pnum
\throws
\tcode{system_error} when
an exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{resource_deadlock_would_occur} --- if deadlock is detected or
\tcode{get_id() == this_thread::\brk{}get_id()}.

\item \tcode{no_such_process} --- if the thread is not valid.

\item \tcode{invalid_argument} --- if the thread is not joinable.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{detach}{thread}%
\begin{itemdecl}
void detach();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The thread represented by \tcode{*this} continues execution without the calling thread
blocking. When \tcode{detach()} returns, \tcode{*this} no longer represents the possibly continuing
thread of execution. When the thread previously represented by \tcode{*this} ends execution, the
implementation releases any owned resources.

\pnum
\ensures
\tcode{get_id() == id()}.

\pnum
\throws
\tcode{system_error} when
an exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{no_such_process} --- if the thread is not valid.
\item \tcode{invalid_argument} --- if the thread is not joinable.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{get_id}{thread}%
\begin{itemdecl}
id get_id() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A default constructed \tcode{id} object if \tcode{*this} does not represent a thread,
otherwise \tcode{this_thread::get_id()} for the thread of execution represented by
\tcode{*this}.
\end{itemdescr}

\rSec3[thread.thread.static]{Static members}

\indexlibrarymember{hardware_concurrency}{thread}%
\begin{itemdecl}
unsigned hardware_concurrency() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The number of hardware thread contexts.
\begin{note}
This value should
only be considered to be a hint.
\end{note}
If this value is not computable or
well-defined, an implementation should return 0.
\end{itemdescr}

\rSec3[thread.thread.algorithm]{Specialized algorithms}

\indexlibrarymember{swap}{thread}%
\begin{itemdecl}
void swap(thread& x, thread& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
As if by \tcode{x.swap(y)}.
\end{itemdescr}

\rSec2[thread.jthread.class]{Class \tcode{jthread}}

\rSec3[thread.jthread.class.general]{General}

\pnum
The class \tcode{jthread} provides a mechanism
to create a new thread of execution.
The functionality is the same as for
class \tcode{thread}\iref{thread.thread.class}
with the additional abilities to provide
a \tcode{stop_token}\iref{thread.stoptoken} to the new thread of execution,
make stop requests, and automatically join.

\indexlibraryglobal{jthread}%
\begin{codeblock}
namespace std {
  class jthread {
  public:
    // types
    using id = thread::id;
    using native_handle_type = thread::native_handle_type;

    // \ref{thread.jthread.cons}, constructors, move, and assignment
    jthread() noexcept;
    template<class F, class... Args> explicit jthread(F&& f, Args&&... args);
    ~jthread();
    jthread(const jthread&) = delete;
    jthread(jthread&&) noexcept;
    jthread& operator=(const jthread&) = delete;
    jthread& operator=(jthread&&) noexcept;

    // \ref{thread.jthread.mem}, members
    void swap(jthread&) noexcept;
    bool joinable() const noexcept;
    void join();
    void detach();
    id get_id() const noexcept;
    native_handle_type native_handle();                 // see~\ref{thread.req.native}

    // \ref{thread.jthread.stop}, stop token handling
    stop_source get_stop_source() noexcept;
    stop_token get_stop_token() const noexcept;
    bool request_stop() noexcept;

    // \ref{thread.jthread.special}, specialized algorithms
    friend void swap(jthread& lhs, jthread& rhs) noexcept;

    // \ref{thread.jthread.static}, static members
    static unsigned int hardware_concurrency() noexcept;

  private:
    stop_source ssource;        // \expos
  };
}
\end{codeblock}

\rSec3[thread.jthread.cons]{Constructors, move, and assignment}

\indexlibraryctor{jthread}%
\begin{itemdecl}
jthread() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs a \tcode{jthread} object that does not represent
a thread of execution.

\pnum
\ensures
\tcode{get_id() == id()} is \tcode{true}
and \tcode{ssource.stop_possible()} is \tcode{false}.
\end{itemdescr}

\indexlibraryctor{jthread}%
\begin{itemdecl}
template<class F, class... Args> explicit jthread(F&& f, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{remove_cvref_t<F>} is not the same type as \tcode{jthread}.

\pnum
\mandates
The following are all \tcode{true}:
\begin{itemize}
\item \tcode{is_constructible_v<decay_t<F>, F>},
\item \tcode{(is_constructible_v<decay_t<Args>, Args> \&\& ...)}, and
\item \tcode{is_invocable_v<decay_t<F>, decay_t<Args>...> ||} \\ \tcode{is_invocable_v<decay_t<F>, stop_token, decay_t<Args>...>}.
\end{itemize}

\pnum
\effects
Initializes \tcode{ssource}.
The new thread of execution executes
\begin{codeblock}
invoke(auto(std::forward<F>(f)), get_stop_token(),  // for \tcode{invoke}, see \ref{func.invoke}
       auto(std::forward<Args>(args))...)
\end{codeblock}
if that expression is well-formed,
otherwise
\begin{codeblock}
invoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...)
\end{codeblock}
with the values produced by \tcode{auto}
being materialized\iref{conv.rval} in the constructing thread.
Any return value from this invocation is ignored.
\begin{note}
This implies that any exceptions not thrown from the invocation of the copy
of \tcode{f} will be thrown in the constructing thread, not the new thread.
\end{note}
If the \tcode{invoke} expression exits via an exception,
\tcode{terminate} is called.

\pnum
\sync
The completion of the invocation of the constructor
synchronizes with the beginning of the invocation of the copy of \tcode{f}.

\pnum
\ensures
\tcode{get_id() != id()} is \tcode{true}
and \tcode{ssource.stop_possible()} is \tcode{true}
and \tcode{*this} represents the newly started thread.
\begin{note}
The calling thread can make a stop request only once,
because it cannot replace this stop token.
\end{note}

\pnum
\throws
\tcode{system_error} if unable to start the new thread.

\pnum
\errors
\begin{itemize}
\item \tcode{resource_unavailable_try_again} --- the system lacked
the necessary resources to create another thread,
or the system-imposed limit on the number of threads in a process
would be exceeded.
\end{itemize}
\end{itemdescr}

\indexlibraryctor{jthread}%
\begin{itemdecl}
jthread(jthread&& x) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{x.get_id() == id()}
and \tcode{get_id()} returns the value of \tcode{x.get_id()}
prior to the start of construction.
\tcode{ssource} has the value of \tcode{x.ssource}
prior to the start of construction
and \tcode{x.ssource.stop_possible()} is \tcode{false}.
\end{itemdescr}

\indexlibrarydtor{jthread}%
\begin{itemdecl}
~jthread();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{joinable()} is \tcode{true},
calls \tcode{request_stop()} and then \tcode{join()}.
\begin{note}
Operations on \tcode{*this} are not synchronized.
\end{note}
\end{itemdescr}

\indexlibrarymember{operator=}{jthread}%
\begin{itemdecl}
jthread& operator=(jthread&& x) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{\&x == this} is \tcode{true}, there are no effects.
Otherwise, if \tcode{joinable()} is \tcode{true},
calls \tcode{request_stop()} and then \tcode{join()},
then assigns the state of \tcode{x} to \tcode{*this}
and sets \tcode{x} to a default constructed state.

\pnum
\ensures
\tcode{get_id()} returns the value of \tcode{x.get_id()}
prior to the assignment.
\tcode{ssource} has the value of \tcode{x.ssource}
prior to the assignment.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\rSec3[thread.jthread.mem]{Members}

\indexlibrarymember{swap}{jthread}%
\begin{itemdecl}
void swap(jthread& x) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Exchanges the values of \tcode{*this} and \tcode{x}.
\end{itemdescr}

\indexlibrarymember{joinable}{jthread}%
\begin{itemdecl}
bool joinable() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{get_id() != id()}.
\end{itemdescr}

\indexlibrarymember{join}{jthread}%
\begin{itemdecl}
void join();
\end{itemdecl}

\begin{itemdescr}
\pnum
\indextext{block (execution)}%
\effects
Blocks until the thread represented by \tcode{*this} has completed.

\pnum
\sync
The completion of the thread represented by \tcode{*this}
synchronizes with\iref{intro.multithread}
the corresponding successful \tcode{join()} return.
\begin{note}
Operations on \tcode{*this} are not synchronized.
\end{note}

\pnum
\ensures
The thread represented by \tcode{*this} has completed.
\tcode{get_id() == id()}.

\pnum
\throws
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{resource_deadlock_would_occur} --- if deadlock is detected or
\tcode{get_id() == this_thread::\brk{}get_id()}.

\item \tcode{no_such_process} --- if the thread is not valid.

\item \tcode{invalid_argument} --- if the thread is not joinable.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{detach}{jthread}%
\begin{itemdecl}
void detach();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The thread represented by \tcode{*this} continues execution
without the calling thread blocking.
When \tcode{detach()} returns,
\tcode{*this} no longer represents the possibly continuing thread of execution.
When the thread previously represented by \tcode{*this} ends execution,
the implementation releases any owned resources.

\pnum
\ensures
\tcode{get_id() == id()}.

\pnum
\throws
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{no_such_process} --- if the thread is not valid.
\item \tcode{invalid_argument} --- if the thread is not joinable.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{get_id}{jthread}%
\begin{itemdecl}
id get_id() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A default constructed \tcode{id} object
if \tcode{*this} does not represent a thread,
otherwise \tcode{this_thread::get_id()}
for the thread of execution represented by \tcode{*this}.
\end{itemdescr}

\rSec3[thread.jthread.stop]{Stop token handling}

\indexlibrarymember{get_stop_source}{jthread}%
\begin{itemdecl}
stop_source get_stop_source() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return ssource;}
\end{itemdescr}

\indexlibrarymember{get_stop_token}{jthread}%
\begin{itemdecl}
stop_token get_stop_token() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return ssource.get_token();}
\end{itemdescr}

\indexlibrarymember{request_stop}{jthread}%
\begin{itemdecl}
bool request_stop() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return ssource.request_stop();}
\end{itemdescr}


\rSec3[thread.jthread.special]{Specialized algorithms}

\indexlibrarymember{swap}{jthread}%
\begin{itemdecl}
friend void swap(jthread& x, jthread& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{x.swap(y)}.
\end{itemdescr}

\rSec3[thread.jthread.static]{Static members}

\indexlibrarymember{hardware_concurrency}{jthread}%
\begin{itemdecl}
static unsigned int hardware_concurrency() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{thread::hardware_concurrency()}.
\end{itemdescr}


\rSec2[thread.thread.this]{Namespace \tcode{this_thread}}

\begin{codeblock}
namespace std::this_thread {
  thread::id get_id() noexcept;

  void yield() noexcept;
  template<class Clock, class Duration>
    void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
  template<class Rep, class Period>
    void sleep_for(const chrono::duration<Rep, Period>& rel_time);
}
\end{codeblock}

\indexlibrarymember{get_id}{this_thread}%
\begin{itemdecl}
thread::id this_thread::get_id() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An object of type \tcode{thread::id}
that uniquely identifies the current thread of execution.
Every invocation from this thread of execution returns the same value.
The object returned does not compare equal to
a default-constructed \tcode{thread::id}.
\end{itemdescr}

\indexlibrarymember{yield}{this_thread}%
\begin{itemdecl}
void this_thread::yield() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Offers the implementation the opportunity to reschedule.

\pnum
\sync
None.
\end{itemdescr}

\indexlibrarymember{sleep_until}{this_thread}%
\begin{itemdecl}
template<class Clock, class Duration>
  void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\indextext{block (execution)}%
\effects
Blocks the calling thread for the absolute timeout\iref{thread.req.timing} specified
by \tcode{abs_time}.

\pnum
\sync
None.

\pnum
\throws
Timeout-related exceptions\iref{thread.req.timing}.
\end{itemdescr}

\indexlibrarymember{sleep_for}{this_thread}%
\begin{itemdecl}
template<class Rep, class Period>
  void sleep_for(const chrono::duration<Rep, Period>& rel_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\indextext{block (execution)}%
\effects
Blocks the calling thread for the relative timeout\iref{thread.req.timing} specified
by \tcode{rel_time}.

\pnum
\sync
None.

\pnum
\throws
Timeout-related exceptions\iref{thread.req.timing}.
\end{itemdescr}

\rSec1[atomics]{Atomic operations}

\rSec2[atomics.general]{General}

\pnum
Subclause \ref{atomics} describes components for fine-grained atomic access.
This access is provided via operations on atomic objects.

\rSec2[atomics.syn]{Header \tcode{<atomic>} synopsis}

\indexheader{atomic}%
\begin{codeblock}
// mostly freestanding
namespace std {
  // \ref{atomics.order}, order and consistency
  enum class memory_order : @\unspecnc@;
  inline constexpr memory_order memory_order_relaxed = memory_order::relaxed;
  inline constexpr memory_order memory_order_acquire = memory_order::acquire;
  inline constexpr memory_order memory_order_release = memory_order::release;
  inline constexpr memory_order memory_order_acq_rel = memory_order::acq_rel;
  inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cst;
}

// \ref{atomics.lockfree}, lock-free property
#define @\libmacro{ATOMIC_BOOL_LOCK_FREE}@ @\unspecnc@
#define @\libmacro{ATOMIC_CHAR_LOCK_FREE}@ @\unspecnc@
#define @\libmacro{ATOMIC_CHAR8_T_LOCK_FREE}@ @\unspecnc@
#define @\libmacro{ATOMIC_CHAR16_T_LOCK_FREE}@ @\unspecnc@
#define @\libmacro{ATOMIC_CHAR32_T_LOCK_FREE}@ @\unspecnc@
#define @\libmacro{ATOMIC_WCHAR_T_LOCK_FREE}@ @\unspecnc@
#define @\libmacro{ATOMIC_SHORT_LOCK_FREE}@ @\unspecnc@
#define @\libmacro{ATOMIC_INT_LOCK_FREE}@ @\unspecnc@
#define @\libmacro{ATOMIC_LONG_LOCK_FREE}@ @\unspecnc@
#define @\libmacro{ATOMIC_LLONG_LOCK_FREE}@ @\unspecnc@
#define @\libmacro{ATOMIC_POINTER_LOCK_FREE}@ @\unspecnc@

namespace std {
  // \ref{atomics.ref.generic}, class template \tcode{atomic_ref}
  template<class T> struct atomic_ref;

  // \ref{atomics.types.generic}, class template \tcode{atomic}
  template<class T> struct atomic;
  // \ref{atomics.types.pointer}, partial specialization for pointers
  template<class T> struct atomic<T*>;

  // \ref{atomics.nonmembers}, non-member functions
  template<class T>
    bool atomic_is_lock_free(const volatile atomic<T>*) noexcept;
  template<class T>
    bool atomic_is_lock_free(const atomic<T>*) noexcept;
  template<class T>
    void atomic_store(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr void atomic_store(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    void atomic_store_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
  template<class T>
    constexpr void atomic_store_explicit(atomic<T>*, typename atomic<T>::value_type,
                                         memory_order) noexcept;
  template<class T>
    T atomic_load(const volatile atomic<T>*) noexcept;
  template<class T>
    constexpr T atomic_load(const atomic<T>*) noexcept;
  template<class T>
    T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept;
  template<class T>
    constexpr T atomic_load_explicit(const atomic<T>*, memory_order) noexcept;
  template<class T>
    T atomic_exchange(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr T atomic_exchange(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    T atomic_exchange_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
  template<class T>
    constexpr T atomic_exchange_explicit(atomic<T>*, typename atomic<T>::value_type,
                                         memory_order) noexcept;
  template<class T>
    bool atomic_compare_exchange_weak(volatile atomic<T>*,
                                      typename atomic<T>::value_type*,
                                      typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr bool atomic_compare_exchange_weak(atomic<T>*,
                                                typename atomic<T>::value_type*,
                                                typename atomic<T>::value_type) noexcept;
  template<class T>
    bool atomic_compare_exchange_strong(volatile atomic<T>*,
                                        typename atomic<T>::value_type*,
                                        typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr bool atomic_compare_exchange_strong(atomic<T>*,
                                                  typename atomic<T>::value_type*,
                                                  typename atomic<T>::value_type) noexcept;
  template<class T>
    bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*,
                                               typename atomic<T>::value_type*,
                                               typename atomic<T>::value_type,
                                               memory_order, memory_order) noexcept;
  template<class T>
    constexpr bool atomic_compare_exchange_weak_explicit(atomic<T>*,
                                                         typename atomic<T>::value_type*,
                                                         typename atomic<T>::value_type,
                                                         memory_order, memory_order) noexcept;
  template<class T>
    bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*,
                                                 typename atomic<T>::value_type*,
                                                 typename atomic<T>::value_type,
                                                 memory_order, memory_order) noexcept;
  template<class T>
    constexpr bool atomic_compare_exchange_strong_explicit(atomic<T>*,
                                                           typename atomic<T>::value_type*,
                                                           typename atomic<T>::value_type,
                                                           memory_order, memory_order) noexcept;

  template<class T>
    T atomic_fetch_add(volatile atomic<T>*, typename atomic<T>::difference_type) noexcept;
  template<class T>
    constexpr T atomic_fetch_add(atomic<T>*, typename atomic<T>::difference_type) noexcept;
  template<class T>
    T atomic_fetch_add_explicit(volatile atomic<T>*, typename atomic<T>::difference_type,
                                memory_order) noexcept;
  template<class T>
    constexpr T atomic_fetch_add_explicit(atomic<T>*, typename atomic<T>::difference_type,
                                          memory_order) noexcept;
  template<class T>
    T atomic_fetch_sub(volatile atomic<T>*, typename atomic<T>::difference_type) noexcept;
  template<class T>
    constexpr T atomic_fetch_sub(atomic<T>*, typename atomic<T>::difference_type) noexcept;
  template<class T>
    T atomic_fetch_sub_explicit(volatile atomic<T>*, typename atomic<T>::difference_type,
                                memory_order) noexcept;
  template<class T>
    constexpr T atomic_fetch_sub_explicit(atomic<T>*, typename atomic<T>::difference_type,
                                          memory_order) noexcept;
  template<class T>
    T atomic_fetch_and(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr T atomic_fetch_and(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    T atomic_fetch_and_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                                memory_order) noexcept;
  template<class T>
    constexpr T atomic_fetch_and_explicit(atomic<T>*, typename atomic<T>::value_type,
                                          memory_order) noexcept;
  template<class T>
    T atomic_fetch_or(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr T atomic_fetch_or(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    T atomic_fetch_or_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
  template<class T>
    constexpr T atomic_fetch_or_explicit(atomic<T>*, typename atomic<T>::value_type,
                                         memory_order) noexcept;
  template<class T>
    T atomic_fetch_xor(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr T atomic_fetch_xor(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    T atomic_fetch_xor_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                                memory_order) noexcept;
  template<class T>
    constexpr T atomic_fetch_xor_explicit(atomic<T>*, typename atomic<T>::value_type,
                                          memory_order) noexcept;
  template<class T>
    T atomic_fetch_max(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr T atomic_fetch_max(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    T atomic_fetch_max_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                                memory_order) noexcept;
  template<class T>
    constexpr T atomic_fetch_max_explicit(atomic<T>*, typename atomic<T>::value_type,
                                          memory_order) noexcept;
  template<class T>
    T atomic_fetch_min(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr T atomic_fetch_min(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    T atomic_fetch_min_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                                memory_order) noexcept;
  template<class T>
    constexpr T atomic_fetch_min_explicit(atomic<T>*, typename atomic<T>::value_type,
                                          memory_order) noexcept;

  template<class T>
    void atomic_store_add(volatile atomic<T>*, typename atomic<T>::difference_type) noexcept;
  template<class T>
    constexpr void atomic_store_add(atomic<T>*, typename atomic<T>::difference_type) noexcept;
  template<class T>
    void atomic_store_add_explicit(volatile atomic<T>*, typename atomic<T>::difference_type,
                                   memory_order) noexcept;
  template<class T>
    constexpr void atomic_store_add_explicit(atomic<T>*, typename atomic<T>::difference_type,
                                             memory_order) noexcept;
  template<class T>
    void atomic_store_sub(volatile atomic<T>*, typename atomic<T>::difference_type) noexcept;
  template<class T>
    constexpr void atomic_store_sub(atomic<T>*, typename atomic<T>::difference_type) noexcept;
  template<class T>
    void atomic_store_sub_explicit(volatile atomic<T>*, typename atomic<T>::difference_type,
                                   memory_order) noexcept;
  template<class T>
    constexpr void atomic_store_sub_explicit(atomic<T>*, typename atomic<T>::difference_type,
                                             memory_order) noexcept;
  template<class T>
    void atomic_store_and(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr void atomic_store_and(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    void atomic_store_and_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                                   memory_order) noexcept;
  template<class T>
    constexpr void atomic_store_and_explicit(atomic<T>*, typename atomic<T>::value_type,
                                             memory_order) noexcept;
  template<class T>
    void atomic_store_or(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr void atomic_store_or(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    void atomic_store_or_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                                  memory_order) noexcept;
  template<class T>
    constexpr void atomic_store_or_explicit(atomic<T>*, typename atomic<T>::value_type,
                                            memory_order) noexcept;
  template<class T>
    void atomic_store_xor(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr void atomic_store_xor(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    void atomic_store_xor_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                                   memory_order) noexcept;
  template<class T>
    constexpr void atomic_store_xor_explicit(atomic<T>*, typename atomic<T>::value_type,
                                             memory_order) noexcept;
  template<class T>
    void atomic_store_max(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr void atomic_store_max(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    void atomic_store_max_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                                   memory_order) noexcept;
  template<class T>
    constexpr void atomic_store_max_explicit(atomic<T>*, typename atomic<T>::value_type,
                                             memory_order) noexcept;
  template<class T>
    void atomic_store_min(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr void atomic_store_min(atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    void atomic_store_min_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                                   memory_order) noexcept;
  template<class T>
    constexpr void atomic_store_min_explicit(atomic<T>*, typename atomic<T>::value_type,
                                             memory_order) noexcept;

  template<class T>
    void atomic_wait(const volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    constexpr void atomic_wait(const atomic<T>*, typename atomic<T>::value_type) noexcept;
  template<class T>
    void atomic_wait_explicit(const volatile atomic<T>*, typename atomic<T>::value_type,
                              memory_order) noexcept;
  template<class T>
    constexpr void atomic_wait_explicit(const atomic<T>*, typename atomic<T>::value_type,
                                        memory_order) noexcept;
  template<class T>
    void atomic_notify_one(volatile atomic<T>*) noexcept;
  template<class T>
    constexpr void atomic_notify_one(atomic<T>*) noexcept;
  template<class T>
    void atomic_notify_all(volatile atomic<T>*) noexcept;
  template<class T>
    constexpr void atomic_notify_all(atomic<T>*) noexcept;

  // \ref{atomics.alias}, type aliases
  using atomic_bool           = atomic<bool>;
  using atomic_char           = atomic<char>;
  using atomic_schar          = atomic<signed char>;
  using atomic_uchar          = atomic<unsigned char>;
  using atomic_short          = atomic<short>;
  using atomic_ushort         = atomic<unsigned short>;
  using atomic_int            = atomic<int>;
  using atomic_uint           = atomic<unsigned int>;
  using atomic_long           = atomic<long>;
  using atomic_ulong          = atomic<unsigned long>;
  using atomic_llong          = atomic<long long>;
  using atomic_ullong         = atomic<unsigned long long>;
  using atomic_char8_t        = atomic<char8_t>;
  using atomic_char16_t       = atomic<char16_t>;
  using atomic_char32_t       = atomic<char32_t>;
  using atomic_wchar_t        = atomic<wchar_t>;

  using atomic_int8_t         = atomic<int8_t>;
  using atomic_uint8_t        = atomic<uint8_t>;
  using atomic_int16_t        = atomic<int16_t>;
  using atomic_uint16_t       = atomic<uint16_t>;
  using atomic_int32_t        = atomic<int32_t>;
  using atomic_uint32_t       = atomic<uint32_t>;
  using atomic_int64_t        = atomic<int64_t>;
  using atomic_uint64_t       = atomic<uint64_t>;

  using atomic_int_least8_t   = atomic<int_least8_t>;
  using atomic_uint_least8_t  = atomic<uint_least8_t>;
  using atomic_int_least16_t  = atomic<int_least16_t>;
  using atomic_uint_least16_t = atomic<uint_least16_t>;
  using atomic_int_least32_t  = atomic<int_least32_t>;
  using atomic_uint_least32_t = atomic<uint_least32_t>;
  using atomic_int_least64_t  = atomic<int_least64_t>;
  using atomic_uint_least64_t = atomic<uint_least64_t>;

  using atomic_int_fast8_t    = atomic<int_fast8_t>;
  using atomic_uint_fast8_t   = atomic<uint_fast8_t>;
  using atomic_int_fast16_t   = atomic<int_fast16_t>;
  using atomic_uint_fast16_t  = atomic<uint_fast16_t>;
  using atomic_int_fast32_t   = atomic<int_fast32_t>;
  using atomic_uint_fast32_t  = atomic<uint_fast32_t>;
  using atomic_int_fast64_t   = atomic<int_fast64_t>;
  using atomic_uint_fast64_t  = atomic<uint_fast64_t>;

  using atomic_intptr_t       = atomic<intptr_t>;
  using atomic_uintptr_t      = atomic<uintptr_t>;
  using atomic_size_t         = atomic<size_t>;
  using atomic_ptrdiff_t      = atomic<ptrdiff_t>;
  using atomic_intmax_t       = atomic<intmax_t>;
  using atomic_uintmax_t      = atomic<uintmax_t>;

  using atomic_signed_lock_free   = @\seebelow@;                  // hosted
  using atomic_unsigned_lock_free = @\seebelow@;                  // hosted

  // \ref{atomics.flag}, flag type and operations
  struct atomic_flag;

  bool atomic_flag_test(const volatile atomic_flag*) noexcept;
  constexpr bool atomic_flag_test(const atomic_flag*) noexcept;
  bool atomic_flag_test_explicit(const volatile atomic_flag*, memory_order) noexcept;
  constexpr bool atomic_flag_test_explicit(const atomic_flag*, memory_order) noexcept;
  bool atomic_flag_test_and_set(volatile atomic_flag*) noexcept;
  constexpr bool atomic_flag_test_and_set(atomic_flag*) noexcept;
  bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, memory_order) noexcept;
  constexpr bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order) noexcept;
  void atomic_flag_clear(volatile atomic_flag*) noexcept;
  constexpr void atomic_flag_clear(atomic_flag*) noexcept;
  void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order) noexcept;
  constexpr void atomic_flag_clear_explicit(atomic_flag*, memory_order) noexcept;

  void atomic_flag_wait(const volatile atomic_flag*, bool) noexcept;
  constexpr void atomic_flag_wait(const atomic_flag*, bool) noexcept;
  void atomic_flag_wait_explicit(const volatile atomic_flag*, bool, memory_order) noexcept;
  constexpr void atomic_flag_wait_explicit(const atomic_flag*, bool, memory_order) noexcept;
  void atomic_flag_notify_one(volatile atomic_flag*) noexcept;
  constexpr void atomic_flag_notify_one(atomic_flag*) noexcept;
  void atomic_flag_notify_all(volatile atomic_flag*) noexcept;
  constexpr void atomic_flag_notify_all(atomic_flag*) noexcept;
  #define @\libmacro{ATOMIC_FLAG_INIT}@ @\seebelownc@

  // \ref{atomics.fences}, fences
  extern "C" constexpr void atomic_thread_fence(memory_order) noexcept;
  extern "C" constexpr void atomic_signal_fence(memory_order) noexcept;
}
\end{codeblock}

\rSec2[atomics.alias]{Type aliases}
\indexlibraryglobal{atomic_bool}%
\indexlibraryglobal{atomic_char}%
\indexlibraryglobal{atomic_schar}%
\indexlibraryglobal{atomic_uchar}%
\indexlibraryglobal{atomic_short}%
\indexlibraryglobal{atomic_ushort}%
\indexlibraryglobal{atomic_int}%
\indexlibraryglobal{atomic_uint}%
\indexlibraryglobal{atomic_long}%
\indexlibraryglobal{atomic_ulong}%
\indexlibraryglobal{atomic_llong}%
\indexlibraryglobal{atomic_ullong}%
\indexlibraryglobal{atomic_char8_t}%
\indexlibraryglobal{atomic_char16_t}%
\indexlibraryglobal{atomic_char32_t}%
\indexlibraryglobal{atomic_wchar_t}%
\indexlibraryglobal{atomic_int8_t}%
\indexlibraryglobal{atomic_uint8_t}%
\indexlibraryglobal{atomic_int16_t}%
\indexlibraryglobal{atomic_uint16_t}%
\indexlibraryglobal{atomic_int32_t}%
\indexlibraryglobal{atomic_uint32_t}%
\indexlibraryglobal{atomic_int64_t}%
\indexlibraryglobal{atomic_uint64_t}%
\indexlibraryglobal{atomic_int_least8_t}%
\indexlibraryglobal{atomic_uint_least8_t}%
\indexlibraryglobal{atomic_int_least16_t}%
\indexlibraryglobal{atomic_uint_least16_t}%
\indexlibraryglobal{atomic_int_least32_t}%
\indexlibraryglobal{atomic_uint_least32_t}%
\indexlibraryglobal{atomic_int_least64_t}%
\indexlibraryglobal{atomic_uint_least64_t}%
\indexlibraryglobal{atomic_int_fast8_t}%
\indexlibraryglobal{atomic_uint_fast8_t}%
\indexlibraryglobal{atomic_int_fast16_t}%
\indexlibraryglobal{atomic_uint_fast16_t}%
\indexlibraryglobal{atomic_int_fast32_t}%
\indexlibraryglobal{atomic_uint_fast32_t}%
\indexlibraryglobal{atomic_int_fast64_t}%
\indexlibraryglobal{atomic_uint_fast64_t}%
\indexlibraryglobal{atomic_intptr_t}%
\indexlibraryglobal{atomic_uintptr_t}%
\indexlibraryglobal{atomic_size_t}%
\indexlibraryglobal{atomic_ptrdiff_t}%
\indexlibraryglobal{atomic_intmax_t}%
\indexlibraryglobal{atomic_uintmax_t}%
\pnum
The type aliases \tcode{atomic_int$N$_t}, \tcode{atomic_uint$N$_t},
\tcode{atomic_intptr_t}, and \tcode{atomic_uintptr_t}
are declared if and only if
\tcode{int$N$_t}, \tcode{uint$N$_t},
\tcode{intptr_t}, and \tcode{uintptr_t}
are declared, respectively.

\pnum
\indexlibraryglobal{atomic_signed_lock_free}%
\indexlibraryglobal{atomic_unsigned_lock_free}%
The type aliases
\tcode{atomic_signed_lock_free} and \tcode{atomic_unsigned_lock_free}
name specializations of \tcode{atomic}
whose template arguments are integral types, respectively signed and unsigned,
and whose \tcode{is_always_lock_free} property is \tcode{true}.
\begin{note}
\indextext{implementation!freestanding}%
These aliases are optional in freestanding implementations\iref{compliance}.
\end{note}
Implementations should choose for these aliases
the integral specializations of \tcode{atomic}
for which the atomic waiting and notifying operations\iref{atomics.wait}
are most efficient.

\rSec2[atomics.order]{Order and consistency}
\indexlibraryglobal{memory_order}%
\indexlibrarymember{relaxed}{memory_order}%
\indexlibrarymember{acquire}{memory_order}%
\indexlibrarymember{release}{memory_order}%
\indexlibrarymember{acq_rel}{memory_order}%
\indexlibrarymember{seq_cst}{memory_order}%
\indexlibraryglobal{memory_order_relaxed}%
\indexlibraryglobal{memory_order_acquire}%
\indexlibraryglobal{memory_order_release}%
\indexlibraryglobal{memory_order_acq_rel}%
\indexlibraryglobal{memory_order_seq_cst}%

\begin{codeblock}
namespace std {
  enum class memory_order : @\unspec@ {
    relaxed = 0, acquire = 2, release = 3, acq_rel = 4, seq_cst = 5
  };
}
\end{codeblock}

\pnum
The enumeration \tcode{memory_order} specifies the detailed regular
(non-atomic) memory synchronization order as defined in
\ref{intro.multithread} and may provide for operation ordering. Its
enumerated values and their meanings are as follows:

\begin{itemize}
\item \tcode{memory_order::relaxed}: no operation orders memory.

\item \tcode{memory_order::release}, \tcode{memory_order::acq_rel}, and
\tcode{memory_order::seq_cst}: a store operation performs a release operation on the
affected memory location.

\item \tcode{memory_order::acquire}, \tcode{memory_order::acq_rel}, and
\tcode{memory_order::seq_cst}: a load operation performs an acquire operation on the
affected memory location.
\end{itemize}

\begin{note}
Atomic operations specifying \tcode{memory_order::relaxed} are relaxed
with respect to memory ordering. Implementations must still guarantee that any
given atomic access to a particular atomic object be indivisible with respect
to all other atomic accesses to that object.
\end{note}

\pnum
An atomic operation $A$ that performs a release operation on an atomic
object $M$ synchronizes with an atomic operation $B$ that performs
an acquire operation on $M$ and takes its value from any side effect in the
release sequence headed by $A$.

\pnum
An atomic operation $A$ on some atomic object $M$ is
\defn{coherence-ordered before}
another atomic operation $B$ on $M$ if
\begin{itemize}
\item $A$ is a modification, and
$B$ reads the value stored by $A$, or
\item $A$ precedes $B$
in the modification order of $M$, or
\item $A$ and $B$ are not
the same atomic read-modify-write operation, and
there exists an atomic modification $X$ of $M$
such that $A$ reads the value stored by $X$ and
$X$ precedes $B$
in the modification order of $M$, or
\item there exists an atomic modification $X$ of $M$
such that $A$ is coherence-ordered before $X$ and
$X$ is coherence-ordered before $B$.
\end{itemize}

\pnum
There is a single total order $S$
on all \tcode{memory_order::seq_cst} operations, including fences,
that satisfies the following constraints.
First, if $A$ and $B$ are
\tcode{memory_order::seq_cst} operations and
$A$ strongly happens before $B$,
then $A$ precedes $B$ in $S$.
Second, for every pair of atomic operations $A$ and
$B$ on an object $M$,
where $A$ is coherence-ordered before $B$,
the following four conditions are required to be satisfied by $S$:
\begin{itemize}
\item if $A$ and $B$ are both
\tcode{memory_order::seq_cst} operations,
then $A$ precedes $B$ in $S$; and
\item if $A$ is a \tcode{memory_order::seq_cst} operation and
$B$ happens before
a \tcode{memory_order::seq_cst} fence $Y$,
then $A$ precedes $Y$ in $S$; and
\item if a \tcode{memory_order::seq_cst} fence $X$
happens before $A$ and
$B$ is a \tcode{memory_order::seq_cst} operation,
then $X$ precedes $B$ in $S$; and
\item if a \tcode{memory_order::seq_cst} fence $X$
happens before $A$ and
$B$ happens before
a \tcode{memory_order::seq_cst} fence $Y$,
then $X$ precedes $Y$ in $S$.
\end{itemize}

\pnum
\begin{note}
This definition ensures that $S$ is consistent with
the modification order of any atomic object $M$.
It also ensures that
a \tcode{memory_order::seq_cst} load $A$ of $M$
gets its value either from the last modification of $M$
that precedes $A$ in $S$ or
from some non-\tcode{memory_order::seq_cst} modification of $M$
that does not happen before any modification of $M$
that precedes $A$ in $S$.
\end{note}

\pnum
\begin{note}
We do not require that $S$ be consistent with
``happens before''\iref{intro.races}.
This allows more efficient implementation
of \tcode{memory_order::acquire} and \tcode{memory_order::release}
on some machine architectures.
It can produce surprising results
when these are mixed with \tcode{memory_order::seq_cst} accesses.
\end{note}

\pnum
\begin{note}
\tcode{memory_order::seq_cst} ensures sequential consistency only
for a program that is free of data races and
uses exclusively \tcode{memory_order::seq_cst} atomic operations.
Any use of weaker ordering will invalidate this guarantee
unless extreme care is used.
In many cases, \tcode{memory_order::seq_cst} atomic operations are reorderable
with respect to other atomic operations performed by the same thread.
\end{note}

\pnum
Implementations should ensure that no ``out-of-thin-air'' values are computed that
circularly depend on their own computation.

\begin{note}
For example, with \tcode{x} and \tcode{y} initially zero,
\begin{codeblock}
// Thread 1:
r1 = y.load(memory_order::relaxed);
x.store(r1, memory_order::relaxed);
\end{codeblock}

\begin{codeblock}
// Thread 2:
r2 = x.load(memory_order::relaxed);
y.store(r2, memory_order::relaxed);
\end{codeblock}
this recommendation discourages producing \tcode{r1 == r2 == 42}, since the store of 42 to \tcode{y} is only
possible if the store to \tcode{x} stores \tcode{42}, which circularly depends on the
store to \tcode{y} storing \tcode{42}. Note that without this restriction, such an
execution is possible.
\end{note}

\pnum
\begin{note}
The recommendation similarly disallows \tcode{r1 == r2 == 42} in the
following example, with \tcode{x} and \tcode{y} again initially zero:

\begin{codeblock}
// Thread 1:
r1 = x.load(memory_order::relaxed);
if (r1 == 42) y.store(42, memory_order::relaxed);
\end{codeblock}

\begin{codeblock}
// Thread 2:
r2 = y.load(memory_order::relaxed);
if (r2 == 42) x.store(42, memory_order::relaxed);
\end{codeblock}
\end{note}

\pnum
Atomic read-modify-write operations shall always read the last value
(in the modification order) written before the write associated with
the read-modify-write operation.

\pnum
An \defnadj{atomic}{modify-write operation} is
an atomic read-modify-write operation
with weaker synchronization requirements as specified in~\ref{atomics.fences}.
\begin{note}
The intent is for atomic modify-write operations
to be implemented using mechanisms that are not ordered, in hardware,
by the implementation of acquire fences.
No other semantic or hardware property
(e.g., that the mechanism is a far atomic operation) is implied.
\end{note}

\pnum
\recommended
The implementation should make atomic stores visible to atomic loads,
and atomic loads should observe atomic stores,
within a reasonable amount of time.

\rSec2[atomics.lockfree]{Lock-free property}

\indeximpldef{values of various \tcode{ATOMIC_..._LOCK_FREE} macros}
\begin{codeblock}
#define @\libmacro{ATOMIC_BOOL_LOCK_FREE}@ @\unspec@
#define @\libmacro{ATOMIC_CHAR_LOCK_FREE}@ @\unspec@
#define @\libmacro{ATOMIC_CHAR8_T_LOCK_FREE}@ @\unspec@
#define @\libmacro{ATOMIC_CHAR16_T_LOCK_FREE}@ @\unspec@
#define @\libmacro{ATOMIC_CHAR32_T_LOCK_FREE}@ @\unspec@
#define @\libmacro{ATOMIC_WCHAR_T_LOCK_FREE}@ @\unspec@
#define @\libmacro{ATOMIC_SHORT_LOCK_FREE}@ @\unspec@
#define @\libmacro{ATOMIC_INT_LOCK_FREE}@ @\unspec@
#define @\libmacro{ATOMIC_LONG_LOCK_FREE}@ @\unspec@
#define @\libmacro{ATOMIC_LLONG_LOCK_FREE}@ @\unspec@
#define @\libmacro{ATOMIC_POINTER_LOCK_FREE}@ @\unspec@
\end{codeblock}

\pnum
The \tcode{ATOMIC_..._LOCK_FREE} macros indicate the lock-free property of the
corresponding atomic types, with the signed and unsigned variants grouped
together. The properties also apply to the corresponding (partial) specializations of the
\tcode{atomic} template. A value of 0 indicates that the types are never
lock-free. A value of 1 indicates that the types are sometimes lock-free. A
value of 2 indicates that the types are always lock-free.

\pnum
On a hosted implementation\iref{compliance},
at least one signed integral specialization of the \tcode{atomic} template,
along with the specialization
for the corresponding unsigned type\iref{basic.fundamental},
is always lock-free.

\pnum
The functions \tcode{atomic<T>::is_lock_free} and
\tcode{atomic_is_lock_free}\iref{atomics.types.operations}
indicate whether the object is lock-free. In any given program execution, the
result of the lock-free query
is the same for all atomic objects of the same type.

\pnum
Atomic operations that are not lock-free are considered to potentially
block\iref{intro.progress}.

\pnum
\recommended
Operations that are lock-free should also be address-free.
\begin{footnote}
That is,
atomic operations on the same memory location via two different addresses will
communicate atomically.
\end{footnote}
The implementation of these operations should not depend on any per-process state.
\begin{note}
This restriction enables communication by memory that is
mapped into a process more than once and by memory that is shared between two
processes.
\end{note}

\rSec2[atomics.wait]{Waiting and notifying}

\pnum
\defnx{Atomic waiting operations}{atomic!waiting operation}
and \defnx{atomic notifying operations}{atomic!notifying operation}
provide a mechanism to wait for the value of an atomic object to change
more efficiently than can be achieved with polling.
An atomic waiting operation may block until it is unblocked
by an atomic notifying operation, according to each function's effects.
\begin{note}
Programs are not guaranteed to observe transient atomic values,
an issue known as the A-B-A problem,
resulting in continued blocking if a condition is only temporarily met.
\end{note}

\pnum
\begin{note}
The following functions are atomic waiting operations:
\begin{itemize}
\item \tcode{atomic<T>::wait},
\item \tcode{atomic_flag::wait},
\item \tcode{atomic_wait} and \tcode{atomic_wait_explicit},
\item \tcode{atomic_flag_wait} and \tcode{atomic_flag_wait_explicit}, and
\item \tcode{atomic_ref<T>::wait}.
\end{itemize}
\end{note}

\pnum
\begin{note}
The following functions are atomic notifying operations:
\begin{itemize}
\item \tcode{atomic<T>::notify_one} and \tcode{atomic<T>::notify_all},
\item \tcode{atomic_flag::notify_one} and \tcode{atomic_flag::notify_all},
\item \tcode{atomic_notify_one} and \tcode{atomic_notify_all},
\item \tcode{atomic_flag_notify_one} and \tcode{atomic_flag_notify_all}, and
\item \tcode{atomic_ref<T>::notify_one} and \tcode{atomic_ref<T>::notify_all}.
\end{itemize}
\end{note}

\indextext{atomic!waiting operation!eligible to be unblocked}%
\pnum
A call to an atomic waiting operation on an atomic object \tcode{M}
is \defn{eligible to be unblocked}
by a call to an atomic notifying operation on \tcode{M}
if there exist side effects \tcode{X} and \tcode{Y} on \tcode{M} such that:
\begin{itemize}
\item the atomic waiting operation has blocked after observing the result of \tcode{X},
\item \tcode{X} precedes \tcode{Y} in the modification order of \tcode{M}, and
\item \tcode{Y} happens before the call to the atomic notifying operation.
\end{itemize}

\rSec2[atomics.ref.generic]{Class template \tcode{atomic_ref}}

\rSec3[atomics.ref.generic.general]{General}

\indexlibraryglobal{atomic_ref}%
\indexlibrarymember{value_type}{atomic_ref}%
\begin{codeblock}
namespace std {
  template<class T> struct atomic_ref {
  private:
    T* ptr;             // \expos

  public:
    using value_type = remove_cv_t<T>;
    static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@;

    static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@;
    bool is_lock_free() const noexcept;

    constexpr explicit atomic_ref(T&);
    constexpr atomic_ref(const atomic_ref&) noexcept;
    template<class U>
      constexpr atomic_ref(const atomic_ref<U>&) noexcept;
    atomic_ref& operator=(const atomic_ref&) = delete;

    constexpr void store(value_type, memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type operator=(value_type) const noexcept;
    constexpr value_type load(memory_order = memory_order::seq_cst) const noexcept;
    constexpr operator value_type() const noexcept;

    constexpr value_type exchange(value_type,
                                  memory_order = memory_order::seq_cst) const noexcept;
    constexpr bool compare_exchange_weak(value_type&, value_type,
                                         memory_order, memory_order) const noexcept;
    constexpr bool compare_exchange_strong(value_type&, value_type,
                                           memory_order, memory_order) const noexcept;
    constexpr bool compare_exchange_weak(value_type&, value_type,
                                         memory_order = memory_order::seq_cst) const noexcept;
    constexpr bool compare_exchange_strong(value_type&, value_type,
                                           memory_order = memory_order::seq_cst) const noexcept;

    constexpr void wait(value_type, memory_order = memory_order::seq_cst) const noexcept;
    constexpr void notify_one() const noexcept;
    constexpr void notify_all() const noexcept;
    constexpr T* address() const noexcept;
  };
}
\end{codeblock}

\pnum
An \tcode{atomic_ref} object applies atomic operations\iref{atomics.general} to
the object referenced by \tcode{*ptr} such that,
for the lifetime\iref{basic.life} of the \tcode{atomic_ref} object,
the object referenced by \tcode{*ptr} is an atomic object\iref{intro.races}.

\pnum
The program is ill-formed if \tcode{is_trivially_copyable_v<T>} is \tcode{false}.

\pnum
The lifetime\iref{basic.life} of an object referenced by \tcode{*ptr}
shall exceed the lifetime of all \tcode{atomic_ref}s that reference the object.
While any \tcode{atomic_ref} instances exist
that reference the \tcode{*ptr} object,
all accesses to that object shall exclusively occur
through those \tcode{atomic_ref} instances.
No subobject of the object referenced by \tcode{atomic_ref}
shall be concurrently referenced by any other \tcode{atomic_ref} object.

\pnum
Atomic operations applied to an object
through a referencing \tcode{atomic_ref} are atomic with respect to
atomic operations applied through any other \tcode{atomic_ref}
referencing the same object.
\begin{note}
Atomic operations or the \tcode{atomic_ref} constructor can acquire
a shared resource, such as a lock associated with the referenced object,
to enable atomic operations to be applied to the referenced object.
\end{note}

\pnum
The program is ill-formed
if \tcode{is_always_lock_free} is \tcode{false} and
\tcode{is_volatile_v<T>} is \tcode{true}.

\rSec3[atomics.ref.ops]{Operations}

\indexlibrarymember{required_alignment}{atomic_ref}%
\indexlibrarymember{required_alignment}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{required_alignment}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{required_alignment}{atomic_ref<\placeholder{floating-point-type}>}%
\begin{itemdecl}
static constexpr size_t required_alignment;
\end{itemdecl}

\begin{itemdescr}
\pnum
The alignment required for an object to be referenced by an atomic reference,
which is at least \tcode{alignof(T)}.

\pnum
\begin{note}
An implementation can choose to define
\tcode{atomic_ref<T>::required_alignment}
to a value greater than \tcode{alignof(T)} in order to ensure that
operations on all objects of type \tcode{atomic_ref<T>} are lock-free.
\end{note}
\end{itemdescr}

\indexlibrarymember{is_always_lock_free}{atomic_ref}%
\indexlibrarymember{is_always_lock_free}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{is_always_lock_free}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{is_always_lock_free}{atomic_ref<\placeholder{floating-point-type}>}%
\begin{itemdecl}
static constexpr bool is_always_lock_free;
\end{itemdecl}

\begin{itemdescr}
\pnum
The static data member \tcode{is_always_lock_free} is \tcode{true}
if the \tcode{atomic_ref} type's operations are always lock-free,
and \tcode{false} otherwise.
\end{itemdescr}

\indexlibrarymember{is_lock_free}{atomic_ref}%
\indexlibrarymember{is_lock_free}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{is_lock_free}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{is_lock_free}{atomic_ref<\placeholder{floating-point-type}>}%
\begin{itemdecl}
bool is_lock_free() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if operations on all objects of the type \tcode{atomic_ref<T>}
are lock-free,
\tcode{false} otherwise.
\end{itemdescr}

\indexlibraryctor{atomic_ref}%
\indexlibraryctor{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrary{\idxcode{atomic_ref<\placeholder{integral-type}>}!constructor}%
\indexlibrary{\idxcode{atomic_ref<\placeholder{floating-point-type}>}!constructor}%
\begin{itemdecl}
constexpr atomic_ref(T& obj);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The referenced object is aligned to \tcode{required_alignment}.

\pnum
\ensures
\tcode{*this} references \tcode{obj}.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibraryctor{atomic_ref}%
\indexlibraryctor{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrary{\idxcode{atomic_ref<\placeholder{integral-type}>}!constructor}%
\indexlibrary{\idxcode{atomic_ref<\placeholder{floating-point-type}>}!constructor}%
\begin{itemdecl}
constexpr atomic_ref(const atomic_ref& ref) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{*this} references the object referenced by \tcode{ref}.
\end{itemdescr}

\begin{itemdecl}
template<class U>
  constexpr atomic_ref(const atomic_ref<U>&) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\begin{itemize}
\item \tcode{T} and \tcode{U} are similar types\iref{conv.qual}, and
\item \tcode{is_convertible_v<U*, T*>} is \tcode{true}.
\end{itemize}

\pnum
\ensures
\tcode{*this} references the object referenced by \tcode{ref}.
\end{itemdescr}

\indexlibrarymember{store}{atomic_ref}%
\indexlibrarymember{store}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{store}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{store}{atomic_ref<\placeholder{floating-point-type}>}%
\begin{itemdecl}
constexpr void store(value_type desired,
                     memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<T>} is \tcode{false}.

\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::release}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Atomically replaces the value referenced by \tcode{*ptr}
with the value of \tcode{desired}.
Memory is affected according to the value of \tcode{order}.
\end{itemdescr}

\indexlibrarymember{operator=}{atomic_ref}%
\indexlibrarymember{operator=}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{operator=}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{operator=}{atomic_ref<\placeholder{floating-point-type}>}%
\begin{itemdecl}
constexpr value_type operator=(value_type desired) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<T>} is \tcode{false}.

\pnum
\effects
Equivalent to:
\begin{codeblock}
store(desired);
return desired;
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{load}{atomic_ref}%
\indexlibrarymember{load}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{load}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{load}{atomic_ref<\placeholder{floating-point-type}>}%
\begin{itemdecl}
constexpr value_type load(memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::acquire}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Memory is affected according to the value of \tcode{order}.

\pnum
\returns
Atomically returns the value referenced by \tcode{*ptr}.
\end{itemdescr}

\indexlibrarymember{operator \placeholder{type}}{atomic_ref}%
\indexlibrarymember{operator \placeholder{pointer-type}}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{operator \placeholder{integral-type}}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{operator \placeholder{floating-point-type}}{atomic_ref<\placeholder{floating-point-type}>}%
\begin{itemdecl}
constexpr operator value_type() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return load();}
\end{itemdescr}

\indexlibrarymember{exchange}{atomic_ref}%
\indexlibrarymember{exchange}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{exchange}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{exchange}{atomic_ref<\placeholder{floating-point-type}>}%
\begin{itemdecl}
constexpr value_type exchange(value_type desired,
                              memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<T>} is \tcode{false}.

\pnum
\effects
Atomically replaces the value referenced by \tcode{*ptr}
with \tcode{desired}.
Memory is affected according to the value of \tcode{order}.
This operation is an atomic read-modify-write operation\iref{intro.multithread}.

\pnum
\returns
Atomically returns the value referenced by \tcode{*ptr}
immediately before the effects.
\end{itemdescr}

\indexlibrarymember{compare_exchange_weak}{atomic_ref}%
\indexlibrarymember{compare_exchange_weak}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{compare_exchange_weak}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{compare_exchange_weak}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{compare_exchange_strong}{atomic_ref}%
\indexlibrarymember{compare_exchange_strong}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{compare_exchange_strong}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{compare_exchange_strong}{atomic_ref<\placeholder{floating-point-type}>}%
\begin{itemdecl}
constexpr bool compare_exchange_weak(value_type& expected, value_type desired,
                                     memory_order success, memory_order failure) const noexcept;

constexpr bool compare_exchange_strong(value_type& expected, value_type desired,
                                       memory_order success, memory_order failure) const noexcept;

constexpr bool compare_exchange_weak(value_type& expected, value_type desired,
                                     memory_order order = memory_order::seq_cst) const noexcept;

constexpr bool compare_exchange_strong(value_type& expected, value_type desired,
                                       memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<T>} is \tcode{false}.

\pnum
\expects
\tcode{failure} is
\tcode{memory_order::relaxed},
\tcode{memory_order::acquire}, or
\tcode{memory_order::\linebreak seq_cst}.

\pnum
\effects
Retrieves the value in \tcode{expected}.
It then atomically compares the value representation of
the value referenced by \tcode{*ptr} for equality
with that previously retrieved from \tcode{expected},
and if \tcode{true}, replaces the value referenced by \tcode{*ptr}
with that in \tcode{desired}.
If and only if the comparison is \tcode{true},
memory is affected according to the value of \tcode{success}, and
if the comparison is \tcode{false},
memory is affected according to the value of \tcode{failure}.
When only one \tcode{memory_order} argument is supplied,
the value of \tcode{success} is \tcode{order}, and
the value of \tcode{failure} is \tcode{order}
except that a value of \tcode{memory_order::acq_rel} shall be replaced by
the value \tcode{memory_order::acquire} and
a value of \tcode{memory_order::release} shall be replaced by
the value \tcode{memory_order::relaxed}.
If and only if the comparison is \tcode{false} then,
after the atomic operation,
the value in \tcode{expected} is replaced by
the value read from the value referenced by \tcode{*ptr}
during the atomic comparison.
If the operation returns \tcode{true},
these operations are atomic read-modify-write operations\iref{intro.races}
on the value referenced by \tcode{*ptr}.
Otherwise, these operations are atomic load operations on that memory.

\pnum
\returns
The result of the comparison.

\pnum
\remarks
A weak compare-and-exchange operation may fail spuriously.
That is, even when the contents of memory referred to
by \tcode{expected} and \tcode{ptr} are equal,
it may return \tcode{false} and
store back to \tcode{expected} the same memory contents
that were originally there.
\begin{note}
This spurious failure enables implementation of compare-and-exchange
on a broader class of machines, e.g., load-locked store-conditional machines.
A consequence of spurious failure is
that nearly all uses of weak compare-and-exchange will be in a loop.
When a compare-and-exchange is in a loop,
the weak version will yield better performance on some platforms.
When a weak compare-and-exchange would require a loop and
a strong one would not, the strong one is preferable.
\end{note}
\end{itemdescr}

\indexlibrarymember{wait}{atomic_ref<T>}%
\begin{itemdecl}
constexpr void wait(value_type old, memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::acquire}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Repeatedly performs the following steps, in order:
\begin{itemize}
\item
  Evaluates \tcode{load(order)} and
  compares its value representation for equality against that of \tcode{old}.
\item
  If they compare unequal, returns.
\item
  Blocks until it
  is unblocked by an atomic notifying operation or is unblocked spuriously.
\end{itemize}

\pnum
\remarks
This function is an atomic waiting operation\iref{atomics.wait}
on atomic object \tcode{*ptr}.
\end{itemdescr}

\indexlibrarymember{notify_one}{atomic_ref<T>}%
\begin{itemdecl}
constexpr void notify_one() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<T>} is \tcode{false}.

\pnum
\effects
Unblocks the execution of at least one atomic waiting operation on \tcode{*ptr}
that is eligible to be unblocked\iref{atomics.wait} by this call,
if any such atomic waiting operations exist.

\pnum
\remarks
This function is an atomic notifying operation\iref{atomics.wait}
on atomic object \tcode{*ptr}.
\end{itemdescr}

\indexlibrarymember{notify_all}{atomic_ref<T>}%
\begin{itemdecl}
constexpr void notify_all() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<T>} is \tcode{false}.

\pnum
\effects
Unblocks the execution of all atomic waiting operations on \tcode{*ptr}
that are eligible to be unblocked\iref{atomics.wait} by this call.

\pnum
\remarks
This function is an atomic notifying operation\iref{atomics.wait}
on atomic object \tcode{*ptr}.
\end{itemdescr}

\indexlibrarymember{address}{atomic_ref<T>}%
\begin{itemdecl}
constexpr T* address() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ptr}.
\end{itemdescr}

\rSec3[atomics.ref.int]{Specializations for integral types}

\pnum
\indexlibrary{\idxcode{atomic_ref<\placeholder{integral-type}>}}%
There are specializations of the \tcode{atomic_ref} class template
for all integral types except \cv{} \tcode{bool}.
For each such type \tcode{\placeholder{integral-type}},
the specialization \tcode{atomic_ref<\placeholder{integral-type}>} provides
additional atomic operations appropriate to integral types.
\begin{note}
The specialization \tcode{atomic_ref<bool>}
uses the primary template\iref{atomics.ref.generic}.
\end{note}

\pnum
The program is ill-formed
if \tcode{is_always_lock_free} is \tcode{false} and
\tcode{is_volatile_v<\placeholder{integral-type}>} is \tcode{true}.

\begin{codeblock}
namespace std {
  template<> struct atomic_ref<@\placeholder{integral-type}@> {
  private:
    @\placeholder{integral-type}@* ptr;         // \expos

  public:
    using value_type = remove_cv_t<@\placeholder{integral-type}@>;
    using difference_type = value_type;
    static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@;

    static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@;
    bool is_lock_free() const noexcept;

    constexpr explicit atomic_ref(@\placeholder{integral-type}@&);
    constexpr atomic_ref(const atomic_ref&) noexcept;
    template<class U>
      constexpr atomic_ref(const atomic_ref<U>&) noexcept;
    atomic_ref& operator=(const atomic_ref&) = delete;

    constexpr void store(value_type, memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type operator=(value_type) const noexcept;
    constexpr value_type load(memory_order = memory_order::seq_cst) const noexcept;
    constexpr operator value_type() const noexcept;

    constexpr value_type exchange(value_type,
                                  memory_order = memory_order::seq_cst) const noexcept;
    constexpr bool compare_exchange_weak(value_type&, value_type,
                                         memory_order, memory_order) const noexcept;
    constexpr bool compare_exchange_strong(value_type&, value_type,
                                           memory_order, memory_order) const noexcept;
    constexpr bool compare_exchange_weak(value_type&, value_type,
                                         memory_order = memory_order::seq_cst) const noexcept;
    constexpr bool compare_exchange_strong(value_type&, value_type,
                                           memory_order = memory_order::seq_cst) const noexcept;

    constexpr value_type fetch_add(value_type,
                                   memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_sub(value_type,
                                   memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_and(value_type,
                                   memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_or(value_type,
                                  memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_xor(value_type,
                                   memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_max(value_type,
                                   memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_min(value_type,
                                   memory_order = memory_order::seq_cst) const noexcept;

    constexpr void store_add(value_type,
                             memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_sub(value_type,
                             memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_and(value_type,
                             memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_or(value_type,
                            memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_xor(value_type,
                             memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_max(value_type,
                             memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_min(value_type,
                             memory_order = memory_order::seq_cst) const noexcept;

    constexpr value_type operator++(int) const noexcept;
    constexpr value_type operator--(int) const noexcept;
    constexpr value_type operator++() const noexcept;
    constexpr value_type operator--() const noexcept;
    constexpr value_type operator+=(value_type) const noexcept;
    constexpr value_type operator-=(value_type) const noexcept;
    constexpr value_type operator&=(value_type) const noexcept;
    constexpr value_type operator|=(value_type) const noexcept;
    constexpr value_type operator^=(value_type) const noexcept;

    constexpr void wait(value_type, memory_order = memory_order::seq_cst) const noexcept;
    constexpr void notify_one() const noexcept;
    constexpr void notify_all() const noexcept;
    constexpr @\placeholder{integral-type}@* address() const noexcept;
  };
}
\end{codeblock}

\pnum
Descriptions are provided below only for members
that differ from the primary template.

\pnum
The following operations perform arithmetic computations.
The correspondence among key, operator, and computation is specified
in \tref{atomic.types.int.comp}.

\indexlibrarymember{fetch_add}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{fetch_and}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{fetch_max}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{fetch_min}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{fetch_or}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{fetch_sub}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{fetch_xor}{atomic_ref<\placeholder{integral-type}>}%
\begin{itemdecl}
constexpr value_type fetch_@\placeholdernc{key}@(value_type operand,
  memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<\placeholder{integral-type}>} is \tcode{false}.

\pnum
\effects
Atomically replaces the value referenced by \tcode{*ptr} with
the result of the computation applied to the value referenced by \tcode{*ptr}
and the given operand.
Memory is affected according to the value of \tcode{order}.
These operations are atomic read-modify-write operations\iref{intro.races}.

\pnum
\returns
Atomically, the value referenced by \tcode{*ptr}
immediately before the effects.

\pnum
\indextext{signed integer representation!two's complement}%
\remarks
Except for \tcode{fetch_max} and \tcode{fetch_min}, for signed integer types
the result is as if the object value and parameters
were converted to their corresponding unsigned types,
the computation performed on those types, and
the result converted back to the signed type.
\begin{note}
There are no undefined results arising from the computation.
\end{note}

\pnum
For \tcode{fetch_max} and \tcode{fetch_min}, the maximum and minimum
computation is performed as if by \tcode{max} and \tcode{min}
algorithms\iref{alg.min.max}, respectively,
with the object value and the first parameter as the arguments.
\end{itemdescr}

\indexlibrarymember{store_add}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{store_and}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{store_max}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{store_min}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{store_or}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{store_sub}{atomic_ref<\placeholder{integral-type}>}%
\begin{itemdecl}
constexpr void store_@\placeholdernc{key}@(value_type operand,
                         memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<\placeholder{integral-type}>} is \tcode{false}.

\pnum
\expects
\tcode{order} is \tcode{memory_order::relaxed},
\tcode{memory_order::release}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Atomically replaces the value referenced by \tcode{*ptr}
with the result of the computation applied to
the value referenced by \tcode{*ptr} and the given \tcode{operand}.
Memory is affected according to the value of \tcode{order}.
These operations are atomic modify-write operations\iref{atomics.order}.

\pnum
\remarks
Except for \tcode{store_max} and \tcode{store_min},
for signed integer types,
the result is as if \tcode{*ptr} and parameters
were converted to their corresponding unsigned types,
the computation performed on those types, and
the result converted back to the signed type.
\begin{note}
There are no undefined results arising from the computation.
\end{note}
For \tcode{store_max} and \tcode{store_min},
the maximum and minimum computation is performed
as if by \tcode{max} and \tcode{min} algorithms\iref{alg.min.max}, respectively,
with \tcode{*ptr} and the first parameter as the arguments.
\end{itemdescr}

\indexlibrarymember{operator+=}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{operator-=}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{operator\&=}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{operator"|=}{atomic_ref<\placeholder{integral-type}>}%
\indexlibrarymember{operator\caret=}{atomic_ref<\placeholder{integral-type}>}%
\begin{itemdecl}
constexpr value_type operator @\placeholder{op}@=(value_type operand) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<\placeholder{integral-type}>} is \tcode{false}.

\pnum
\effects
Equivalent to:
\tcode{return fetch_\placeholdernc{key}(operand) \placeholder{op} operand;}
\end{itemdescr}

\rSec3[atomics.ref.float]{Specializations for floating-point types}

\pnum
\indexlibrary{\idxcode{atomic_ref<\placeholder{floating-point-type}>}}%
There are specializations of the \tcode{atomic_ref} class template
for all floating-point types.
For each such type \tcode{\placeholder{floating-point-type}},
the specialization \tcode{atomic_ref<\placeholder{floating-\-point-type}>} provides
additional atomic operations appropriate to floating-point types.

\pnum
The program is ill-formed
if \tcode{is_always_lock_free} is \tcode{false} and
\tcode{is_volatile_v<\placeholder{floating-point-type}>} is \tcode{true}.

\begin{codeblock}
namespace std {
  template<> struct atomic_ref<@\placeholder{floating-point-type}@> {
  private:
    @\placeholder{floating-point-type}@* ptr;   // \expos

  public:
    using value_type = remove_cv_t<@\placeholder{floating-point-type}@>;
    using difference_type = value_type;
    static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@;

    static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@;
    bool is_lock_free() const noexcept;

    constexpr explicit atomic_ref(@\placeholder{floating-point-type}@&);
    constexpr atomic_ref(const atomic_ref&) noexcept;
    template<class U>
      constexpr atomic_ref(const atomic_ref<U>&) noexcept;
    atomic_ref& operator=(const atomic_ref&) = delete;

    constexpr void store(value_type,
                         memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type operator=(value_type) const noexcept;
    constexpr value_type load(memory_order = memory_order::seq_cst) const noexcept;
    constexpr operator value_type() const noexcept;

    constexpr value_type exchange(value_type,
                                  memory_order = memory_order::seq_cst) const noexcept;
    constexpr bool compare_exchange_weak(value_type&, value_type,
                                         memory_order, memory_order) const noexcept;
    constexpr bool compare_exchange_strong(value_type&, value_type,
                                           memory_order, memory_order) const noexcept;
    constexpr bool compare_exchange_weak(value_type&, value_type,
                                         memory_order = memory_order::seq_cst) const noexcept;
    constexpr bool compare_exchange_strong(value_type&, value_type,
                                           memory_order = memory_order::seq_cst) const noexcept;

    constexpr value_type fetch_add(value_type,
                                   memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_sub(value_type,
                                   memory_order = memory_order::seq_cst) const noexcept;

    constexpr value_type fetch_max(value_type,
                                   memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_min(value_type,
                                   memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_fmaximum(value_type,
                                        memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_fminimum(value_type,
                                        memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_fmaximum_num(value_type,
                                            memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_fminimum_num(value_type,
                                            memory_order = memory_order::seq_cst) const noexcept;

    constexpr void store_add(value_type, memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_sub(value_type, memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_max(value_type, memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_min(value_type, memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_fmaximum(value_type,
                                  memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_fminimum(value_type,
                                  memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_fmaximum_num(value_type,
                                      memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_fminimum_num(value_type,
                                      memory_order = memory_order::seq_cst) const noexcept;

    constexpr value_type operator+=(value_type) const noexcept;
    constexpr value_type operator-=(value_type) const noexcept;

    constexpr void wait(value_type,
                        memory_order = memory_order::seq_cst) const noexcept;
    constexpr void notify_one() const noexcept;
    constexpr void notify_all() const noexcept;
    constexpr @\placeholder{floating-point-type}@* address() const noexcept;
  };
}
\end{codeblock}

\pnum
Descriptions are provided below only for members
that differ from the primary template.

\pnum
The following operations perform arithmetic computations.
The correspondence among key, operator, and computation is specified
in \tref{atomic.types.int.comp},
except for the keys
\tcode{max},
\tcode{min},
\tcode{fmaximum},
\tcode{fminimum},
\tcode{fmaximum_num}, and
\tcode{fminimum_num},
which are specified below.

\indexlibrarymember{fetch_add}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{fetch_sub}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{fetch_fmaximum}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{fetch_fminimum}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{fetch_fmaximum_num}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{fetch_fminimum_num}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{fetch_max}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{fetch_min}{atomic_ref<\placeholder{floating-point-type}>}%
\begin{itemdecl}
constexpr value_type fetch_@\placeholdernc{key}@(value_type operand,
                          memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<\exposid{floating-point-type}>} is \tcode{false}.

\pnum
\effects
Atomically replaces the value referenced by \tcode{*ptr} with
the result of the computation applied to the value referenced by \tcode{*ptr}
and the given operand.
Memory is affected according to the value of \tcode{order}.
These operations are atomic read-modify-write operations\iref{intro.races}.

\pnum
\returns
Atomically, the value referenced by \tcode{*ptr}
immediately before the effects.

\pnum
\remarks
If the result is not a representable value for its type\iref{expr.pre},
the result is unspecified,
but the operations otherwise have no undefined behavior.
Atomic arithmetic operations on \tcode{\placeholder{floating-point-type}} should conform to
the \tcode{std::numeric_limits<value_type>} traits
associated with the floating-point type\iref{limits.syn}.
The floating-point environment\iref{cfenv}
for atomic arithmetic operations on \tcode{\placeholder{floating-\brk{}point-type}}
may be different than the calling thread's floating-point environment.

\pnum
\begin{itemize}
\item
For \tcode{fetch_fmaximum} and \tcode{fetch_fminimum},
the maximum and minimum computation is performed
as if by \tcode{fmaximum} and \tcode{fminimum}, respectively,
with \tcode{*ptr} and the first parameter as the arguments.
\item
For \tcode{fetch_fmaximum_num} and \tcode{fetch_fminimum_num},
the maximum and minimum computation is performed
as if by \tcode{fmaximum_num} and \tcode{fminimum_num}, respectively,
with \tcode{*ptr} and the first parameter as the arguments.
\item
For \tcode{fetch_max} and \tcode{fetch_min},
the maximum and minimum computation is performed
as if by \tcode{fmaximum_num} and \tcode{fminimum_num}, respectively,
with \tcode{*ptr} and the first parameter as the arguments, except that:
\begin{itemize}
\item
If both arguments are NaN, an unspecified NaN value is stored at \tcode{*ptr}.
\item
If exactly one argument is a NaN,
either the other argument or an unspecified NaN value is stored at \tcode{*ptr};
it is unspecified which.
\item
If the arguments are differently signed zeros,
which of these values is stored at \tcode{*ptr} is unspecified.
\end{itemize}
\end{itemize}

\pnum
\recommended
The implementation of \tcode{fetch_max} and \tcode{fetch_min}
should treat negative zero as smaller than positive zero.
\end{itemdescr}

\indexlibrarymember{store_add}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{store_sub}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{store_min}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{store_max}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{store_fminimum}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{store_fmaximum}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{store_fminimum_num}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{store_fmaximum_num}{atomic_ref<\placeholder{floating-point-type}>}%
\begin{itemdecl}
constexpr void store_@\placeholdernc{key}@(value_type operand,
                          memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<\placeholder{floating-point-type}>} is \tcode{false}.

\pnum
\expects
\tcode{order} is \tcode{memory_order::relaxed},
\tcode{memory_order::release}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Atomically replaces the value referenced by \tcode{*ptr}
with the result of the computation applied to
the value referenced by \tcode{*ptr} and the given \tcode{operand}.
Memory is affected according to the value of \tcode{order}.
These operations are atomic modify-write operations\iref{atomics.order}.

\pnum
\remarks
If the result is not a representable value for its type\iref{expr.pre},
the result is unspecified,
but the operations otherwise have no undefined behavior.
Atomic arithmetic operations on \tcode{\placeholder{floating-point-type}}
should conform to the \tcode{numeric_limits<\placeholder{floating-point-type}>}
traits associated with the floating-point type\iref{limits.syn}.
The floating-point environment\iref{cfenv}
for atomic arithmetic operations on \tcode{\placeholder{floating-point-type}}
may be different than the calling thread's floating-point environment.
The arithmetic rules of floating-point atomic modify-write operations
may be different from operations on floating-point types or
atomic floating-point types.
\begin{note}
Tree reductions are permitted for atomic modify-write operations.
\end{note}

\pnum
\begin{itemize}
\item
For \tcode{store_fmaximum} and \tcode{store_fminimum},
the maximum and minimum computation is performed
as if by \tcode{fmaximum} and \tcode{fminimum}, respectively,
with \tcode{*ptr} and the first parameter as the arguments.
\item
For \tcode{store_fmaximum_num} and \tcode{store_fminimum_num},
the maximum and minimum computation is performed
as if by \tcode{fmaximum_num }and \tcode{fminimum_num}, respectively,
with \tcode{*ptr} and the first parameter as the arguments.
\item
For \tcode{store_max} and \tcode{store_min},
the maximum and minimum computation is performed
as if by \tcode{fmaximum_num} and \tcode{fminimum_num}, respectively,
with \tcode{*ptr} and the first parameter as the arguments, except that:
\begin{itemize}
\item
If both arguments are NaN, an unspecified NaN value is stored at \tcode{*ptr}.
\item
If exactly one argument is a NaN,
either the other argument or an unspecified NaN value is stored at \tcode{*ptr},
it is unspecified which.
\item
If the arguments are differently signed zeros,
which of these values is stored at \tcode{*ptr} is unspecified.
\end{itemize}
\end{itemize}

\pnum
\recommended
The implementation of \tcode{store_max} and \tcode{store_min}
should treat negative zero as smaller than positive zero.
\end{itemdescr}

\indexlibrarymember{operator+=}{atomic_ref<\placeholder{floating-point-type}>}%
\indexlibrarymember{operator-=}{atomic_ref<\placeholder{floating-point-type}>}%
\begin{itemdecl}
constexpr value_type operator @\placeholder{op}@=(value_type operand) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<\exposid{floating-point-type}>} is \tcode{false}.

\pnum
\effects
Equivalent to:
\tcode{return fetch_\placeholder{key}(operand) \placeholdernc{op} operand;}
\end{itemdescr}

\rSec3[atomics.ref.pointer]{Specialization for pointers}
\indexlibraryglobal{atomic_ref<\placeholder{pointer-type}>}%

\pnum
There are specializations of the \tcode{atomic_ref} class template
for all pointer-to-object types.
For each such type \tcode{\placeholder{pointer-type}},
the specialization \tcode{atomic_ref<\placeholder{pointer-type}>} provides
additional atomic operations appropriate to pointer types.

\pnum
The program is ill-formed
if \tcode{is_always_lock_free} is \tcode{false} and
\tcode{is_volatile_v<\placeholder{pointer-type}>} is \tcode{true}.

\begin{codeblock}
namespace std {
  template<> struct atomic_ref<@\placeholder{pointer-type}@> {
  private:
    @\placeholder{pointer-type}@* ptr;        // \expos

  public:
    using value_type = remove_cv_t<@\placeholder{pointer-type}@>;
    using difference_type = ptrdiff_t;
    static constexpr size_t required_alignment = @\impdefx{required alignment for \tcode{atomic_ref} type's operations}@;

    static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic_ref} type's operations are always lock free}@;
    bool is_lock_free() const noexcept;

    constexpr explicit atomic_ref(@\placeholder{pointer-type}@&);
    constexpr atomic_ref(const atomic_ref&) noexcept;
    template<class U>
      constexpr atomic_ref(const atomic_ref<U>&) noexcept;
    atomic_ref& operator=(const atomic_ref&) = delete;

    constexpr void store(value_type, memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type operator=(value_type) const noexcept;
    constexpr value_type load(memory_order = memory_order::seq_cst) const noexcept;
    constexpr operator value_type() const noexcept;

    constexpr value_type exchange(value_type,
                                  memory_order = memory_order::seq_cst) const noexcept;
    constexpr bool compare_exchange_weak(value_type&, value_type,
                                         memory_order, memory_order) const noexcept;
    constexpr bool compare_exchange_strong(value_type&, value_type,
                                           memory_order, memory_order) const noexcept;
    constexpr bool compare_exchange_weak(value_type&, value_type,
                                         memory_order = memory_order::seq_cst) const noexcept;
    constexpr bool compare_exchange_strong(value_type&, value_type,
                                           memory_order = memory_order::seq_cst) const noexcept;

    constexpr value_type fetch_add(difference_type,
                                   memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_sub(difference_type,
                                   memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_max(value_type,
                                   memory_order = memory_order::seq_cst) const noexcept;
    constexpr value_type fetch_min(value_type,
                                   memory_order = memory_order::seq_cst) const noexcept;

    constexpr void store_add(difference_type,
                             memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_sub(difference_type,
                             memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_max(value_type,
                             memory_order = memory_order::seq_cst) const noexcept;
    constexpr void store_min(value_type,
                             memory_order = memory_order::seq_cst) const noexcept;

    constexpr value_type operator++(int) const noexcept;
    constexpr value_type operator--(int) const noexcept;
    constexpr value_type operator++() const noexcept;
    constexpr value_type operator--() const noexcept;
    constexpr value_type operator+=(difference_type) const noexcept;
    constexpr value_type operator-=(difference_type) const noexcept;

    constexpr void wait(value_type, memory_order = memory_order::seq_cst) const noexcept;
    constexpr void notify_one() const noexcept;
    constexpr void notify_all() const noexcept;
    constexpr @\placeholder{pointer-type}@* address() const noexcept;
  };
}
\end{codeblock}

\pnum
Descriptions are provided below only for members
that differ from the primary template.

\pnum
The following operations perform arithmetic computations.
The correspondence among key, operator, and computation is specified
in \tref{atomic.types.pointer.comp}.

\indexlibrarymember{fetch_add}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{fetch_sub}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{fetch_max}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{fetch_min}{atomic_ref<\placeholder{pointer-type}>}%
\begin{itemdecl}
constexpr value_type fetch_@\placeholdernc{key}@(@\seeabovenc@ operand,
                               memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<\placeholder{pointer-type}>} is \tcode{false}.

\pnum
\mandates
\tcode{remove_pointer_t<\placeholder{pointer-type}>} is a complete object type.

\pnum
\effects
Atomically replaces the value referenced by \tcode{*ptr} with
the result of the computation applied to the value referenced by \tcode{*ptr}
and the given operand.
Memory is affected according to the value of \tcode{order}.
These operations are atomic read-modify-write operations\iref{intro.races}.

\pnum
\returns
Atomically, the value referenced by \tcode{*ptr}
immediately before the effects.

\pnum
\remarks
The result may be an undefined address,
but the operations otherwise have no undefined behavior.

\pnum
For \tcode{fetch_max} and \tcode{fetch_min}, the maximum and minimum
computation is performed as if by \tcode{max} and \tcode{min}
algorithms\iref{alg.min.max}, respectively, with the object value and the first
parameter as the arguments.

\begin{note}
If the pointers point to different complete objects (or subobjects thereof),
the \tcode{<} operator does not establish a strict weak ordering
(\tref{cpp17.lessthancomparable}, \ref{expr.rel}).
\end{note}
\end{itemdescr}

\indexlibrarymember{store_add}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{store_sub}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{store_max}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{store_min}{atomic_ref<\placeholder{pointer-type}>}%
\begin{itemdecl}
constexpr void store_@\placeholdernc{key}@(@\seeabovenc@ operand,
                         memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<\placeholder{pointer-type}>} is \tcode{false}.

\pnum
\mandates
\tcode{remove_pointer_t<\placeholder{pointer-type}>} is a complete object type.

\pnum
\expects
\tcode{order} is \tcode{memory_order::relaxed},
\tcode{memory_order::release}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Atomically replaces the value referenced by \tcode{*ptr}
with the result of the computation applied to
the value referenced by \tcode{*ptr} and the given \tcode{operand}.
Memory is affected according to the value of \tcode{order}.
These operations are atomic modify-write operations\iref{atomics.order}.

\pnum
\remarks
The result may be an undefined address,
but the operations otherwise have no undefined behavior.
For \tcode{store_max} and \tcode{store_min},
the \tcode{maximum} and \tcode{minimum} computation is performed
as if by \tcode{max} and \tcode{min} algorithms\iref{alg.min.max}, respectively,
with \tcode{*ptr} and the first parameter as the arguments.
\begin{note}
If the pointers point to different complete objects (or subobjects thereof),
the \tcode{<} operator does not establish
a strict weak ordering~(\tref{cpp17.lessthancomparable}, \ref{expr.rel}).
\end{note}
\end{itemdescr}

\indexlibrarymember{operator+=}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{operator-=}{atomic_ref<\placeholder{pointer-type}>}%
\begin{itemdecl}
constexpr value_type operator @\placeholder{op}@=(difference_type operand) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<\placeholder{pointer-type}>} is \tcode{false}.

\pnum
\effects
Equivalent to:
\tcode{return fetch_\placeholder{key}(operand) \placeholdernc{op} operand;}
\end{itemdescr}

\rSec3[atomics.ref.memop]{Member operators
                          common to integers and pointers to objects}

\pnum
Let \tcode{\placeholder{referred-type}}
be \tcode{\placeholder{pointer-type}}
for the specializations in \ref{atomics.ref.pointer} and
be \tcode{\placeholder{integral-type}}
for the specializations in \ref{atomics.ref.int}.


\indexlibrarymember{operator++}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{operator++}{atomic_ref<\placeholder{integral-type}>}%
\begin{itemdecl}
constexpr value_type operator++(int) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<\placeholder{referred-type}>} is \tcode{false}.

\pnum
\effects
Equivalent to: \tcode{return fetch_add(1);}
\end{itemdescr}

\indexlibrarymember{operator--}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{operator--}{atomic_ref<\placeholder{integral-type}>}%
\begin{itemdecl}
constexpr value_type operator--(int) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<\placeholder{referred-type}>} is \tcode{false}.

\pnum
\effects
Equivalent to: \tcode{return fetch_sub(1);}
\end{itemdescr}

\indexlibrarymember{operator++}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{operator++}{atomic_ref<\placeholder{integral-type}>}%
\begin{itemdecl}
constexpr value_type operator++() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<\placeholder{referred-type}>} is \tcode{false}.

\pnum
\effects
Equivalent to: \tcode{return fetch_add(1) + 1;}
\end{itemdescr}

\indexlibrarymember{operator--}{atomic_ref<\placeholder{pointer-type}>}%
\indexlibrarymember{operator--}{atomic_ref<\placeholder{integral-type}>}%
\begin{itemdecl}
constexpr value_type operator--() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_const_v<\placeholder{referred-type}>} is \tcode{false}.

\pnum
\effects
Equivalent to: \tcode{return fetch_sub(1) - 1;}
\end{itemdescr}

\rSec2[atomics.types.generic]{Class template \tcode{atomic}}

\rSec3[atomics.types.generic.general]{General}

\indexlibraryglobal{atomic}%
\indexlibrarymember{value_type}{atomic}%
\begin{codeblock}
namespace std {
  template<class T> struct atomic {
    using value_type = T;

    static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@;
    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;

    // \ref{atomics.types.operations}, operations on atomic types
    constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>);
    constexpr atomic(T) noexcept;
    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;

    T load(memory_order = memory_order::seq_cst) const volatile noexcept;
    constexpr T load(memory_order = memory_order::seq_cst) const noexcept;
    operator T() const volatile noexcept;
    constexpr operator T() const noexcept;
    void store(T, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store(T, memory_order = memory_order::seq_cst) noexcept;
    T operator=(T) volatile noexcept;
    constexpr T operator=(T) noexcept;

    T exchange(T, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr T exchange(T, memory_order = memory_order::seq_cst) noexcept;
    bool compare_exchange_weak(T&, T, memory_order, memory_order) volatile noexcept;
    constexpr bool compare_exchange_weak(T&, T, memory_order, memory_order) noexcept;
    bool compare_exchange_strong(T&, T, memory_order, memory_order) volatile noexcept;
    constexpr bool compare_exchange_strong(T&, T, memory_order, memory_order) noexcept;
    bool compare_exchange_weak(T&, T, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr bool compare_exchange_weak(T&, T, memory_order = memory_order::seq_cst) noexcept;
    bool compare_exchange_strong(T&, T, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr bool compare_exchange_strong(T&, T, memory_order = memory_order::seq_cst) noexcept;

    void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
    constexpr void wait(T, memory_order = memory_order::seq_cst) const noexcept;
    void notify_one() volatile noexcept;
    constexpr void notify_one() noexcept;
    void notify_all() volatile noexcept;
    constexpr void notify_all() noexcept;
  };
}
\end{codeblock}

\indexlibraryglobal{atomic}%
\pnum
The template argument for \tcode{T} shall meet the
\oldconcept{CopyConstructible} and \oldconcept{CopyAssignable} requirements.
The program is ill-formed if any of
\begin{itemize}
\item \tcode{is_trivially_copyable_v<T>},
\item \tcode{is_copy_constructible_v<T>},
\item \tcode{is_move_constructible_v<T>},
\item \tcode{is_copy_assignable_v<T>},
\item \tcode{is_move_assignable_v<T>}, or
\item \tcode{is_same_v<T, remove_cv_t<T>>},
\end{itemize}
is \tcode{false}.
\begin{note}
Type arguments that are
not also statically initializable can be difficult to use.
\end{note}

\pnum
The specialization \tcode{atomic<bool>} is a standard-layout struct.
It has a trivial destructor.

\pnum
\begin{note}
The representation of an atomic specialization
need not have the same size and alignment requirement as
its corresponding argument type.
\end{note}

\rSec3[atomics.types.operations]{Operations on atomic types}

\indexlibraryctor{atomic}%
\indexlibraryctor{atomic<T*>}%
\indexlibrary{\idxcode{atomic<\placeholder{integral-type}>}!constructor}%
\indexlibrary{\idxcode{atomic<\placeholder{floating-point-type}>}!constructor}%
\begin{itemdecl}
constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_default_constructible_v<T>} is \tcode{true}.

\pnum
\effects
Initializes the atomic object with the value of \tcode{T()}.
Initialization is not an atomic operation\iref{intro.multithread}.
\end{itemdescr}

\indexlibraryctor{atomic}%
\indexlibraryctor{atomic<T*>}%
\indexlibrary{\idxcode{atomic<\placeholder{integral-type}>}!constructor}%
\indexlibrary{\idxcode{atomic<\placeholder{floating-point-type}>}!constructor}%
\begin{itemdecl}
constexpr atomic(T desired) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes the object with the value \tcode{desired}.
Initialization is not an atomic operation\iref{intro.multithread}.
\begin{note}
It is possible to have an access to an atomic object \tcode{A}
race with its construction, for example by communicating the address of the
just-constructed object \tcode{A} to another thread via
\tcode{memory_order::relaxed} operations on a suitable atomic pointer
variable, and then immediately accessing \tcode{A} in the receiving thread.
This results in undefined behavior.
\end{note}
\end{itemdescr}

\indexlibrarymember{is_always_lock_free}{atomic}%
\indexlibrarymember{is_always_lock_free}{atomic<T*>}%
\indexlibrarymember{is_always_lock_free}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{is_always_lock_free}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{is_always_lock_free}{atomic<shared_ptr<T>>}%
\indexlibrarymember{is_always_lock_free}{atomic<weak_ptr<T>>}%
\begin{itemdecl}
static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@;
\end{itemdecl}

\begin{itemdescr}
\pnum
The \keyword{static} data member \tcode{is_always_lock_free} is \tcode{true}
if the atomic type's operations are always lock-free, and \tcode{false} otherwise.
\begin{note}
The value of \tcode{is_always_lock_free} is consistent with the value of
the corresponding \tcode{ATOMIC_..._LOCK_FREE} macro, if defined.
\end{note}
\end{itemdescr}

\indexlibraryglobal{atomic_is_lock_free}%
\indexlibrarymember{is_lock_free}{atomic}%
\indexlibrarymember{is_lock_free}{atomic<T*>}%
\indexlibrarymember{is_lock_free}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{is_lock_free}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{is_lock_free}{atomic<shared_ptr<T>>}%
\indexlibrarymember{is_lock_free}{atomic<weak_ptr<T>>}%
\begin{itemdecl}
bool is_lock_free() const volatile noexcept;
bool is_lock_free() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if the object's operations are lock-free, \tcode{false} otherwise.
\begin{note}
The return value of the \tcode{is_lock_free} member function
is consistent with the value of \tcode{is_always_lock_free} for the same type.
\end{note}
\end{itemdescr}

\indexlibraryglobal{atomic_store}%
\indexlibraryglobal{atomic_store_explicit}%
\indexlibrarymember{store}{atomic}%
\indexlibrarymember{store}{atomic<T*>}%
\indexlibrarymember{store}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{store}{atomic<\placeholder{floating-point-type}>}%
\begin{itemdecl}
void store(T desired, memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr void store(T desired, memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::release}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Atomically replaces the value pointed to by \keyword{this}
with the value of \tcode{desired}. Memory is affected according to the value of
\tcode{order}.
\end{itemdescr}

\indexlibrarymember{operator=}{atomic}%
\indexlibrarymember{operator=}{atomic<T*>}%
\indexlibrarymember{operator=}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{operator=}{atomic<\placeholder{floating-point-type}>}%
\begin{itemdecl}
T operator=(T desired) volatile noexcept;
constexpr T operator=(T desired) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\effects
Equivalent to \tcode{store(desired)}.

\pnum
\returns
\tcode{desired}.
\end{itemdescr}

\indexlibraryglobal{atomic_load}%
\indexlibraryglobal{atomic_load_explicit}%
\indexlibrarymember{load}{atomic}%
\indexlibrarymember{load}{atomic<T*>}%
\indexlibrarymember{load}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{load}{atomic<\placeholder{floating-point-type}>}%
\begin{itemdecl}
T load(memory_order order = memory_order::seq_cst) const volatile noexcept;
constexpr T load(memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::acquire}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Memory is affected according to the value of \tcode{order}.

\pnum
\returns
Atomically returns the value pointed to by \keyword{this}.
\end{itemdescr}

\indexlibrarymember{operator \placeholder{type}}{atomic}%
\indexlibrarymember{operator T*}{atomic<T*>}%
\indexlibrarymember{operator \placeholder{integral-type}}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{operator \placeholder{floating-point-type}}{atomic<\placeholder{floating-point-type}>}%
\begin{itemdecl}
operator T() const volatile noexcept;
constexpr operator T() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\effects
Equivalent to: \tcode{return load();}
\end{itemdescr}


\indexlibraryglobal{atomic_exchange}%
\indexlibraryglobal{atomic_exchange_explicit}%
\indexlibrarymember{exchange}{atomic}%
\indexlibrarymember{exchange}{atomic<T*>}%
\indexlibrarymember{exchange}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{exchange}{atomic<\placeholder{floating-point-type}>}%
\begin{itemdecl}
T exchange(T desired, memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr T exchange(T desired, memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\effects
Atomically replaces the value pointed to by \keyword{this}
with \tcode{desired}.
Memory is affected according to the value of \tcode{order}.
These operations are atomic read-modify-write operations\iref{intro.multithread}.

\pnum
\returns
Atomically returns the value pointed to by \keyword{this} immediately before the effects.
\end{itemdescr}

\indexlibraryglobal{atomic_compare_exchange_weak}%
\indexlibraryglobal{atomic_compare_exchange_strong}%
\indexlibraryglobal{atomic_compare_exchange_weak_explicit}%
\indexlibraryglobal{atomic_compare_exchange_strong_explicit}%
\indexlibrarymember{compare_exchange_weak}{atomic}%
\indexlibrarymember{compare_exchange_weak}{atomic<T*>}%
\indexlibrarymember{compare_exchange_weak}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{compare_exchange_weak}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{compare_exchange_strong}{atomic}%
\indexlibrarymember{compare_exchange_strong}{atomic<T*>}%
\indexlibrarymember{compare_exchange_strong}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{compare_exchange_strong}{atomic<\placeholder{floating-point-type}>}%
\begin{itemdecl}
bool compare_exchange_weak(T& expected, T desired,
                           memory_order success, memory_order failure) volatile noexcept;
constexpr bool compare_exchange_weak(T& expected, T desired,
                                     memory_order success, memory_order failure) noexcept;
bool compare_exchange_strong(T& expected, T desired,
                             memory_order success, memory_order failure) volatile noexcept;
constexpr bool compare_exchange_strong(T& expected, T desired,
                                       memory_order success, memory_order failure) noexcept;
bool compare_exchange_weak(T& expected, T desired,
                           memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr bool compare_exchange_weak(T& expected, T desired,
                                     memory_order order = memory_order::seq_cst) noexcept;
bool compare_exchange_strong(T& expected, T desired,
                             memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr bool compare_exchange_strong(T& expected, T desired,
                                       memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\expects
\tcode{failure} is
\tcode{memory_order::relaxed},
\tcode{memory_order::acquire}, or
\tcode{memory_order::\linebreak seq_cst}.

\pnum
\effects
Retrieves the value in \tcode{expected}. It then atomically
compares the value representation of the value pointed to by \keyword{this}
for equality with that previously retrieved from \tcode{expected},
and if true, replaces the value pointed to
by \keyword{this} with that in \tcode{desired}.
If and only if the comparison is \tcode{true}, memory is affected according to the
value of \tcode{success}, and if the comparison is false, memory is affected according
to the value of \tcode{failure}. When only one \tcode{memory_order} argument is
supplied, the value of \tcode{success} is \tcode{order}, and the value of
\tcode{failure} is \tcode{order} except that a value of \tcode{memory_order::acq_rel}
shall be replaced by the value \tcode{memory_order::acquire} and a value of
\tcode{memory_order::release} shall be replaced by the value
\tcode{memory_order::relaxed}.
If and only if the comparison is false then, after the atomic operation,
the value in \tcode{expected} is replaced by the value
pointed to by \keyword{this} during the atomic comparison.
If the operation returns \tcode{true}, these
operations are atomic read-modify-write
operations\iref{intro.multithread} on the memory
pointed to by \keyword{this}.
Otherwise, these operations are atomic load operations on that memory.

\pnum
\returns
The result of the comparison.

\pnum
\begin{note}
For example, the effect of
\tcode{compare_exchange_strong}
on objects without padding bits\iref{term.padding.bits} is
\begin{codeblock}
if (memcmp(this, &expected, sizeof(*this)) == 0)
  memcpy(this, &desired, sizeof(*this));
else
  memcpy(&expected, this, sizeof(*this));
\end{codeblock}
\end{note}
\begin{example}
The expected use of the compare-and-exchange operations is as follows. The
compare-and-exchange operations will update \tcode{expected} when another iteration of
the loop is needed.
\begin{codeblock}
expected = current.load();
do {
  desired = function(expected);
} while (!current.compare_exchange_weak(expected, desired));
\end{codeblock}
\end{example}
\begin{example}
Because the expected value is updated only on failure,
code releasing the memory containing the \tcode{expected} value on success will work.
For example, list head insertion will act atomically and would not introduce a
data race in the following code:
\begin{codeblock}
do {
  p->next = head;                                   // make new list node point to the current head
} while (!head.compare_exchange_weak(p->next, p));  // try to insert
\end{codeblock}
\end{example}

\pnum
Implementations should ensure that weak compare-and-exchange operations do not
consistently return \tcode{false} unless either the atomic object has value
different from \tcode{expected} or there are concurrent modifications to the
atomic object.

\pnum
\remarks
A weak compare-and-exchange operation may fail spuriously. That is, even when
the contents of memory referred to by \tcode{expected} and \keyword{this} are
equal, it may return \tcode{false} and store back to \tcode{expected} the same memory
contents that were originally there.
\begin{note}
This
spurious failure enables implementation of compare-and-exchange on a broader class of
machines, e.g., load-locked store-conditional machines. A
consequence of spurious failure is that nearly all uses of weak compare-and-exchange
will be in a loop.
When a compare-and-exchange is in a loop, the weak version will yield better performance
on some platforms. When a weak compare-and-exchange would require a loop and a strong one
would not, the strong one is preferable.
\end{note}

\pnum
\begin{note}
Under cases where the \tcode{memcpy} and \tcode{memcmp} semantics of the compare-and-exchange
operations apply, the comparisons can fail for values that compare equal with
\tcode{operator==} if the value representation has trap bits or alternate
representations of the same value. Notably, on implementations conforming to
\IsoFloatUndated{}, floating-point \tcode{-0.0} and \tcode{+0.0}
will not compare equal with \tcode{memcmp} but will compare equal with \tcode{operator==},
and NaNs with the same payload will compare equal with \tcode{memcmp} but will not
compare equal with \tcode{operator==}.
\end{note}
\begin{note}
Because compare-and-exchange acts on an object's value representation,
padding bits that never participate in the object's value representation
are ignored. As a consequence, the following code is guaranteed to avoid
spurious failure:
\begin{codeblock}
struct padded {
  char clank = 0x42;
  // Padding here.
  unsigned biff = 0xC0DEFEFE;
};
atomic<padded> pad = {};

bool zap() {
  padded expected, desired{0, 0};
  return pad.compare_exchange_strong(expected, desired);
}
\end{codeblock}
\end{note}
\begin{note}
For a union with bits that participate in the value representation
of some members but not others, compare-and-exchange might always fail.
This is because such padding bits have an indeterminate value when they
do not participate in the value representation of the active member.
As a consequence, the following code is not guaranteed to ever succeed:
\begin{codeblock}
union pony {
  double celestia = 0.;
  short luna;       // padded
};
atomic<pony> princesses = {};

bool party(pony desired) {
  pony expected;
  return princesses.compare_exchange_strong(expected, desired);
}
\end{codeblock}
\end{note}
\end{itemdescr}

\indexlibrarymember{wait}{atomic}%
\indexlibrarymember{wait}{atomic<T*>}%
\indexlibrarymember{wait}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{wait}{atomic<\placeholder{floating-point-type}>}%
\begin{itemdecl}
void wait(T old, memory_order order = memory_order::seq_cst) const volatile noexcept;
constexpr void wait(T old, memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::acquire}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Repeatedly performs the following steps, in order:
\begin{itemize}
\item
  Evaluates \tcode{load(order)} and
  compares its value representation for equality against that of \tcode{old}.
\item
  If they compare unequal, returns.
\item
  Blocks until it
  is unblocked by an atomic notifying operation or is unblocked spuriously.
\end{itemize}

\pnum
\remarks
This function is an atomic waiting operation\iref{atomics.wait}.
\end{itemdescr}

\indexlibrarymember{notify_one}{atomic}%
\indexlibrarymember{notify_one}{atomic<T*>}%
\indexlibrarymember{notify_one}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{notify_one}{atomic<\placeholder{floating-point-type}>}%
\begin{itemdecl}
void notify_one() volatile noexcept;
constexpr void notify_one() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Unblocks the execution of at least one atomic waiting operation
that is eligible to be unblocked\iref{atomics.wait} by this call,
if any such atomic waiting operations exist.

\pnum
\remarks
This function is an atomic notifying operation\iref{atomics.wait}.
\end{itemdescr}

\indexlibrarymember{notify_all}{atomic}%
\indexlibrarymember{notify_all}{atomic<T*>}%
\indexlibrarymember{notify_all}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{notify_all}{atomic<\placeholder{floating-point-type}>}%
\begin{itemdecl}
void notify_all() volatile noexcept;
constexpr void notify_all() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Unblocks the execution of all atomic waiting operations
that are eligible to be unblocked\iref{atomics.wait} by this call.

\pnum
\remarks
This function is an atomic notifying operation\iref{atomics.wait}.
\end{itemdescr}

\rSec3[atomics.types.int]{Specializations for integers}

\indexlibrary{\idxcode{atomic<\placeholder{integral-type}>}}%
\pnum
There are specializations of the \tcode{atomic}
class template for
each character type\iref{basic.fundamental},
each standard integer type, and
any other types needed by the typedefs in the header \libheaderref{cstdint}.
For each such type \tcode{\placeholder{integral-type}}, the specialization
\tcode{atomic<\placeholder{integral-type}>} provides additional atomic operations appropriate to integral types.
\begin{note}
The specialization \tcode{atomic<bool>}
uses the primary template\iref{atomics.types.generic}.
\end{note}

\begin{codeblock}
namespace std {
  template<> struct atomic<@\placeholder{integral-type}@> {
    using value_type = @\placeholder{integral-type}@;
    using difference_type = value_type;

    static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@;
    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;

    constexpr atomic() noexcept;
    constexpr atomic(@\placeholdernc{integral-type}@) noexcept;
    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;

    void store(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{integral-type}@ operator=(@\placeholdernc{integral-type}@) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ operator=(@\placeholdernc{integral-type}@) noexcept;
    @\placeholdernc{integral-type}@ load(memory_order = memory_order::seq_cst) const volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ load(memory_order = memory_order::seq_cst) const noexcept;
    operator @\placeholdernc{integral-type}@() const volatile noexcept;
    constexpr operator @\placeholdernc{integral-type}@() const noexcept;

    @\placeholdernc{integral-type}@ exchange(@\placeholdernc{integral-type}@,
                           memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ exchange(@\placeholdernc{integral-type}@,
                           memory_order = memory_order::seq_cst) noexcept;
    bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@,
                               memory_order, memory_order) volatile noexcept;
    constexpr bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@,
                               memory_order, memory_order) noexcept;
    bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@,
                                 memory_order, memory_order) volatile noexcept;
    constexpr bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@,
                                 memory_order, memory_order) noexcept;
    bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@,
                               memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr bool compare_exchange_weak(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@,
                               memory_order = memory_order::seq_cst) noexcept;
    bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@,
                                 memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr bool compare_exchange_strong(@\placeholder{integral-type}@&, @\placeholdernc{integral-type}@,
                                 memory_order = memory_order::seq_cst) noexcept;

    @\placeholdernc{integral-type}@ fetch_add(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ fetch_add(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{integral-type}@ fetch_sub(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ fetch_sub(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{integral-type}@ fetch_and(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ fetch_and(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{integral-type}@ fetch_or(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ fetch_or(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{integral-type}@ fetch_xor(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ fetch_xor(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{integral-type}@ fetch_max(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ fetch_max(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{integral-type}@ fetch_min(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ fetch_min(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) noexcept;

    void store_add(@\placeholdernc{integral-type}@,
                   memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_add(@\placeholdernc{integral-type}@,
                             memory_order = memory_order::seq_cst) noexcept;
    void store_sub(@\placeholdernc{integral-type}@,
                   memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_sub(@\placeholdernc{integral-type}@,
                             memory_order = memory_order::seq_cst) noexcept;
    void store_and(@\placeholdernc{integral-type}@,
                   memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_and(@\placeholdernc{integral-type}@,
                             memory_order = memory_order::seq_cst) noexcept;
    void store_or(@\placeholdernc{integral-type}@,
                  memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_or(@\placeholdernc{integral-type}@,
                            memory_order = memory_order::seq_cst) noexcept;
    void store_xor(@\placeholdernc{integral-type}@,
                   memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_xor(@\placeholdernc{integral-type}@,
                             memory_order = memory_order::seq_cst) noexcept;
    void store_max(@\placeholdernc{integral-type}@,
                   memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_max(@\placeholdernc{integral-type}@,
                             memory_order = memory_order::seq_cst) noexcept;
    void store_min(@\placeholdernc{integral-type}@,
                   memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_min(@\placeholdernc{integral-type}@,
                             memory_order = memory_order::seq_cst) noexcept;

    @\placeholdernc{integral-type}@ operator++(int) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ operator++(int) noexcept;
    @\placeholdernc{integral-type}@ operator--(int) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ operator--(int) noexcept;
    @\placeholdernc{integral-type}@ operator++() volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ operator++() noexcept;
    @\placeholdernc{integral-type}@ operator--() volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ operator--() noexcept;
    @\placeholdernc{integral-type}@ operator+=(@\placeholdernc{integral-type}@) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ operator+=(@\placeholdernc{integral-type}@) noexcept;
    @\placeholdernc{integral-type}@ operator-=(@\placeholdernc{integral-type}@) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ operator-=(@\placeholdernc{integral-type}@) noexcept;
    @\placeholdernc{integral-type}@ operator&=(@\placeholdernc{integral-type}@) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ operator&=(@\placeholdernc{integral-type}@) noexcept;
    @\placeholdernc{integral-type}@ operator|=(@\placeholdernc{integral-type}@) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ operator|=(@\placeholdernc{integral-type}@) noexcept;
    @\placeholdernc{integral-type}@ operator^=(@\placeholdernc{integral-type}@) volatile noexcept;
    constexpr @\placeholdernc{integral-type}@ operator^=(@\placeholdernc{integral-type}@) noexcept;

    void wait(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) const volatile noexcept;
    constexpr void wait(@\placeholdernc{integral-type}@, memory_order = memory_order::seq_cst) const noexcept;
    void notify_one() volatile noexcept;
    constexpr void notify_one() noexcept;
    void notify_all() volatile noexcept;
    constexpr void notify_all() noexcept;
  };
}
\end{codeblock}

\pnum
The atomic integral specializations
are standard-layout structs.
They each have
a trivial destructor.

\pnum
Descriptions are provided below only for members that differ from the primary template.

\pnum
The following operations perform arithmetic computations.
The correspondence among key, operator, and computation is specified
in \tref{atomic.types.int.comp}.

\begin{floattable}
{Atomic arithmetic computations}{atomic.types.int.comp}{lll|lll}
\hline
\hdstyle{\tcode{\placeholder{key}}}   &
  \hdstyle{Op}                        &
  \hdstyle{Computation}               &
\hdstyle{\tcode{\placeholder{key}}}   &
  \hdstyle{Op}                        &
  \hdstyle{Computation}  \\ \hline
\tcode{add}       &
  \tcode{+}       &
  addition        &
\tcode{and}       &
  \tcode{\&}      &
  bitwise and     \\
\tcode{sub}       &
  \tcode{-}       &
  subtraction     &
\tcode{or}        &
  \tcode{|}       &
  bitwise inclusive or  \\
\tcode{max}       &
                  &
  maximum         &
\tcode{xor}       &
  \tcode{\caret}        &
  bitwise exclusive or  \\
\tcode{min}       &
                  &
  minimum         &&&\\
\end{floattable}

\indexlibraryglobal{atomic_fetch_add}%
\indexlibraryglobal{atomic_fetch_and}%
\indexlibraryglobal{atomic_fetch_max}%
\indexlibraryglobal{atomic_fetch_min}%
\indexlibraryglobal{atomic_fetch_or}%
\indexlibraryglobal{atomic_fetch_sub}%
\indexlibraryglobal{atomic_fetch_xor}%
\indexlibraryglobal{atomic_fetch_add_explicit}%
\indexlibraryglobal{atomic_fetch_and_explicit}%
\indexlibraryglobal{atomic_fetch_max_explicit}%
\indexlibraryglobal{atomic_fetch_min_explicit}%
\indexlibraryglobal{atomic_fetch_or_explicit}%
\indexlibraryglobal{atomic_fetch_sub_explicit}%
\indexlibraryglobal{atomic_fetch_xor_explicit}%
\indexlibrarymember{fetch_add}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{fetch_and}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{fetch_max}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{fetch_min}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{fetch_or}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{fetch_sub}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{fetch_xor}{atomic<\placeholder{integral-type}>}%
\begin{itemdecl}
@\placeholder{integral-type}@ fetch_@\placeholdernc{key}@(@\placeholder{integral-type}@ operand,
                         memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr @\placeholder{integral-type}@ fetch_@\placeholdernc{key}@(@\placeholder{integral-type}@ operand,
                                   memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\effects
Atomically replaces the value pointed to by
\keyword{this} with the result of the computation applied to the
value pointed to by \keyword{this} and the given \tcode{operand}.
Memory is affected according to the value of \tcode{order}.
These operations are atomic read-modify-write operations\iref{intro.multithread}.

\pnum
\returns
Atomically, the value pointed to by \keyword{this} immediately before the effects.

\pnum
\indextext{signed integer representation!two's complement}%
\remarks
Except for \tcode{fetch_max} and \tcode{fetch_min}, for signed integer types
the result is as if the object value and parameters
were converted to their corresponding unsigned types,
the computation performed on those types, and
the result converted back to the signed type.
\begin{note}
There are no undefined results arising from the computation.
\end{note}

\pnum
For \tcode{fetch_max} and \tcode{fetch_min}, the maximum and minimum
computation is performed as if by \tcode{max} and \tcode{min}
algorithms\iref{alg.min.max}, respectively,
with the object value and the first parameter as the arguments.
\end{itemdescr}

\indexlibraryglobal{atomic_store_add}%
\indexlibraryglobal{atomic_store_and}%
\indexlibraryglobal{atomic_store_max}%
\indexlibraryglobal{atomic_store_min}%
\indexlibraryglobal{atomic_store_or}%
\indexlibraryglobal{atomic_store_sub}%
\indexlibraryglobal{atomic_store_add_explicit}%
\indexlibraryglobal{atomic_store_and_explicit}%
\indexlibraryglobal{atomic_store_max_explicit}%
\indexlibraryglobal{atomic_store_min_explicit}%
\indexlibraryglobal{atomic_store_or_explicit}%
\indexlibraryglobal{atomic_store_sub_explicit}%
\indexlibrarymember{store_add}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{store_and}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{store_max}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{store_min}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{store_or}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{store_sub}{atomic<\placeholder{integral-type}>}%
\begin{itemdecl}
void store_@\placeholdernc{key}@(@\placeholder{integral-type}@ operand,
                memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr void store_@\placeholdernc{key}@(@\placeholder{integral-type}@ operand,
                          memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::release}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Atomically replaces the value pointed to by \tcode{this}
with the result of the computation applied to
the value pointed to by \tcode{this} and the given \tcode{operand}.
Memory is affected according to the value of \tcode{order}.
These operations are atomic modify-write operations\iref{atomics.order}.

\pnum
\remarks
Except for \tcode{store_max} and \tcode{store_min},
for signed integer types, the result is as if
the value pointed to by \tcode{this} and parameters
were converted to their corresponding unsigned types,
the computation performed on those types, and
the result converted back to the signed type.
\begin{note}
There are no undefined results arising from the computation.
\end{note}
For \tcode{store_max} and \tcode{store_min},
the maximum and minimum computation is performed
as if by \tcode{max} and \tcode{min} algorithms\iref{alg.min.max}, respectively,
with the value pointed to by \tcode{this} and the first parameter as the arguments.
\end{itemdescr}

\indexlibrarymember{operator+=}{atomic<T*>}%
\indexlibrarymember{operator-=}{atomic<T*>}%
\indexlibrarymember{operator+=}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{operator-=}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{operator\&=}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{operator"|=}{atomic<\placeholder{integral-type}>}%
\indexlibrarymember{operator\caret=}{atomic<\placeholder{integral-type}>}%
\begin{itemdecl}
@\placeholder{integral-type}@ operator @\placeholder{op}@=(@\placeholder{integral-type}@ operand) volatile noexcept;
constexpr @\placeholder{integral-type}@ operator @\placeholder{op}@=(@\placeholder{integral-type}@ operand) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\effects
Equivalent to: \tcode{return fetch_\placeholder{key}(operand) \placeholder{op} operand;}
\end{itemdescr}

\rSec3[atomics.types.float]{Specializations for floating-point types}

\indexlibrary{\idxcode{atomic<\placeholder{floating-point-type}>}}%
\pnum
There are specializations of the \tcode{atomic}
class template for all cv-unqualified floating-point types.
For each such type \tcode{\placeholdernc{floating-point-type}},
the specialization \tcode{atomic<\placeholder{floating-point-type}>}
provides additional atomic operations appropriate to floating-point types.

\begin{codeblock}
namespace std {
  template<> struct atomic<@\placeholder{floating-point-type}@> {
    using value_type = @\placeholdernc{floating-point-type}@;
    using difference_type = value_type;

    static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@;
    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;

    constexpr atomic() noexcept;
    constexpr atomic(@\placeholder{floating-point-type}@) noexcept;
    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;

    void store(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{floating-point-type}@ operator=(@\placeholder{floating-point-type}@) volatile noexcept;
    constexpr @\placeholdernc{floating-point-type}@ operator=(@\placeholder{floating-point-type}@) noexcept;
    @\placeholdernc{floating-point-type}@ load(memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{floating-point-type}@ load(memory_order = memory_order::seq_cst) noexcept;
    operator @\placeholdernc{floating-point-type}@() volatile noexcept;
    constexpr operator @\placeholdernc{floating-point-type}@() noexcept;

    @\placeholdernc{floating-point-type}@ exchange(@\placeholdernc{floating-point-type}@,
                                 memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{floating-point-type}@ exchange(@\placeholdernc{floating-point-type}@,
                                           memory_order = memory_order::seq_cst) noexcept;
    bool compare_exchange_weak(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@,
                               memory_order, memory_order) volatile noexcept;
    constexpr bool compare_exchange_weak(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@,
                                         memory_order, memory_order) noexcept;
    bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@,
                                 memory_order, memory_order) volatile noexcept;
    constexpr bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@,
                                           memory_order, memory_order) noexcept;
    bool compare_exchange_weak(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@,
                               memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr bool compare_exchange_weak(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@,
                                         memory_order = memory_order::seq_cst) noexcept;
    bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@,
                                 memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr bool compare_exchange_strong(@\placeholder{floating-point-type}@&, @\placeholdernc{floating-point-type}@,
                                           memory_order = memory_order::seq_cst) noexcept;

    @\placeholdernc{floating-point-type}@ fetch_add(@\placeholdernc{floating-point-type}@,
                                  memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{floating-point-type}@ fetch_add(@\placeholdernc{floating-point-type}@,
                                            memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{floating-point-type}@ fetch_sub(@\placeholdernc{floating-point-type}@,
                                  memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{floating-point-type}@ fetch_sub(@\placeholdernc{floating-point-type}@,
                                            memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{floating-point-type}@ fetch_max(@\placeholdernc{floating-point-type}@,
                                  memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{floating-point-type}@ fetch_max(@\placeholdernc{floating-point-type}@,
                                            memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{floating-point-type}@ fetch_min(@\placeholdernc{floating-point-type}@,
                                  memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{floating-poin-type}@t fetch_min(@\placeholdernc{floating-point-type}@,
                                            memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{floating-point-type}@ fetch_fmaximum(@\placeholdernc{floating-point-type}@,
                                       memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{floating-point-type}@ fetch_fmaximum(@\placeholdernc{floating-point-type}@,
                                                 memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{floating-point-type}@ fetch_fminimum(@\placeholdernc{floating-point-type}@,
                                       memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{floating-point-type}@ fetch_fminimum(@\placeholdernc{floating-point-type}@,
                                                 memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{floating-point-type}@ fetch_fmaximum_num(
      @\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{floating-point-type}@ fetch_fmaximum_num(
      @\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) noexcept;
    @\placeholdernc{floating-point-type}@ fetch_fminimum_num(
      @\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr @\placeholdernc{floating-point-type}@ fetch_fminimum_num(
      @\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) noexcept;

    void store_add(@\placeholdernc{floating-point-type}@,
                   memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_add(@\placeholdernc{floating-point-type}@,
                             memory_order = memory_order::seq_cst) noexcept;
    void store_sub(@\placeholdernc{floating-point-type}@,
                   memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_sub(@\placeholdernc{floating-point-type}@,
                             memory_order = memory_order::seq_cst) noexcept;
    void store_max(@\placeholdernc{floating-point-type}@,
                   memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_max(@\placeholdernc{floating-point-type}@,
                             memory_order = memory_order::seq_cst) noexcept;
    void store_min(@\placeholdernc{floating-point-type}@,
                   memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_min(@\placeholdernc{floating-point-type}@,
                             memory_order = memory_order::seq_cst) noexcept;
    void store_fmaximum(@\placeholdernc{floating-point-type}@,
                        memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_fmaximum(@\placeholdernc{floating-point-type}@,
                                  memory_order = memory_order::seq_cst) noexcept;
    void store_fminimum(@\placeholdernc{floating-point-type}@,
                        memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_fminimum(@\placeholdernc{floating-point-type}@,
                                  memory_order = memory_order::seq_cst) noexcept;
    void store_fmaximum_num(@\placeholdernc{floating-point-type}@,
                            memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_fmaximum_num(@\placeholdernc{floating-point-type}@,
                                      memory_order = memory_order::seq_cst) noexcept;
    void store_fminimum_num(@\placeholdernc{floating-point-type}@,
                            memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_fminimum_num(@\placeholdernc{floating-point-type}@,
                                      memory_order = memory_order::seq_cst) noexcept;

    @\placeholdernc{floating-point-type}@ operator+=(@\placeholder{floating-point-type}@) volatile noexcept;
    constexpr @\placeholdernc{floating-point-type}@ operator+=(@\placeholder{floating-point-type}@) noexcept;
    @\placeholdernc{floating-point-type}@ operator-=(@\placeholder{floating-point-type}@) volatile noexcept;
    constexpr @\placeholdernc{floating-point-type}@ operator-=(@\placeholder{floating-point-type}@) noexcept;

    void wait(@\placeholdernc{floating-point-type}@, memory_order = memory_order::seq_cst) const volatile noexcept;
    constexpr void wait(@\placeholdernc{floating-point-type}@,
                        memory_order = memory_order::seq_cst) const noexcept;
    void notify_one() volatile noexcept;
    constexpr void notify_one() noexcept;
    void notify_all() volatile noexcept;
    constexpr void notify_all() noexcept;
  };
}
\end{codeblock}

\pnum
The atomic floating-point specializations
are standard-layout structs.
They each have
a trivial destructor.

\pnum
Descriptions are provided below only for members that differ from the primary template.

\pnum
The following operations perform arithmetic addition and subtraction computations.
The correspondence among key, operator, and computation is specified
in \tref{atomic.types.int.comp},
except for the keys
\tcode{max},
\tcode{min},
\tcode{fmaximum},
\tcode{fminimum},
\tcode{fmaximum_num}, and
\tcode{fminimum_num},
which are specified below.

\indexlibraryglobal{atomic_fetch_add}%
\indexlibraryglobal{atomic_fetch_sub}%
\indexlibraryglobal{atomic_fetch_add_explicit}%
\indexlibraryglobal{atomic_fetch_sub_explicit}%
\indexlibrarymember{fetch_add}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{fetch_sub}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{fetch_fmaximum}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{fetch_fminimum}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{fetch_fmaximum_num}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{fetch_fminimum_num}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{fetch_max}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{fetch_min}{atomic<\placeholder{floating-point-type}>}%
\begin{itemdecl}
@\placeholdernc{floating-point-type}@ fetch_@\placeholdernc{key}@(@\placeholder{floating-point-type}@ operand,
                              memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr @\placeholdernc{floating-point-type}@ fetch_@\placeholdernc{key}@(@\placeholder{floating-point-type}@ operand,
                                        memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\effects
Atomically replaces the value pointed to by \keyword{this}
with the result of the computation applied to the value pointed
to by \keyword{this} and the given \tcode{operand}.
Memory is affected according to the value of \tcode{order}.
These operations are atomic read-modify-write operations\iref{intro.multithread}.

\pnum
\returns
Atomically, the value pointed to by \keyword{this} immediately before the effects.

\pnum
\remarks
If the result is not a representable value for its type\iref{expr.pre}
the result is unspecified, but the operations otherwise have no undefined
behavior. Atomic arithmetic operations on \tcode{\placeholder{floating-point-type}}
should conform to the \tcode{std::numeric_limits<\placeholder{floating-point-type}>}
traits associated with the floating-point type\iref{limits.syn}.
The floating-point environment\iref{cfenv} for atomic arithmetic operations
on \tcode{\placeholder{floating-point-type}} may be different than the
calling thread's floating-point environment.

\pnum
\begin{itemize}
\item
For \tcode{fetch_fmaximum} and \tcode{fetch_fminimum},
the maximum and minimum computation is performed
as if by \tcode{fmaximum} and \tcode{fminimum}, respectively,
with the value pointed to by \tcode{this} and the first parameter
as the arguments.
\item
For \tcode{fetch_fmaximum_num} and \tcode{fetch_fminimum_num},
the maximum and minimum computation is performed
as if by \tcode{fmaximum_num} and \tcode{fminimum_num}, respectively,
with the value pointed to by \tcode{this} and the first parameter
as the arguments.
\item
For \tcode{fetch_max} and \tcode{fetch_min},
the maximum and minimum computation is performed
as if by \tcode{fmaximum_num} and \tcode{fminimum_num}, respectively,
with the value pointed to by \tcode{this} and the first parameter
as the arguments, except that:
\begin{itemize}
\item
If both arguments are NaN,
an unspecified NaN value replaces the value pointed to by \tcode{this}.
\item
If exactly one argument is a NaN,
either the other argument or an unspecified NaN value
replaces the value pointed to by \tcode{this}; it is unspecified which.
\item
If the arguments are differently signed zeros,
which of these values replaces the value pointed to by this is unspecified.
\end{itemize}
\end{itemize}

\pnum
\recommended
The implementation of \tcode{fetch_max} and \tcode{fetch_min}
should treat negative zero as smaller than positive zero.
\end{itemdescr}

\indexlibrarymember{store_max}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{store_min}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{store_fmaximum}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{store_fminimum}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{store_fmaximum_num}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{store_fminimum_num}{atomic<\placeholder{floating-point-type}>}%
\begin{itemdecl}
void store_@\placeholdernc{key}@(@\placeholdernc{floating-point-type}@ operand,
               memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr void store_@\placeholdernc{key}@(@\placeholdernc{floating-point-type}@ operand,
                         memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::release}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Atomically replaces the value pointed to by \tcode{this}
with the result of the computation applied to
the value pointed to by \tcode{this} and the given operand.
Memory is affected according to the value of \tcode{order}.
These operations are atomic modify-write operations\iref{atomics.order}.

\pnum
\remarks
If the result is not a representable value for its type\iref{expr.pre}
the result is unspecified,
but the operations otherwise have no undefined behavior.
Atomic arithmetic operations on \tcode{\placeholder{floating-point-type}}
should conform to the \tcode{numeric_limits<\placeholder{floating-point-type}>}
traits associated with the floating-point type\iref{limits.syn}.
The floating-point environment\iref{cfenv} for
atomic arithmetic operations on \tcode{\placeholder{floating-point-type}}
may be different than the calling thread's floating-point environment.
The arithmetic rules of floating-point atomic modify-write operations
may be different from operations on
floating-point types or atomic floating-point types.
\begin{note}
Tree reductions are permitted for atomic modify-write operations.
\end{note}

\pnum
\begin{itemize}
\item
For \tcode{store_fmaximum} and \tcode{store_fminimum},
the maximum and minimum computation is performed
as if by \tcode{fmaximum} and \tcode{fminimum}, respectively,
with the value pointed to by \tcode{this} and
the first parameter as the arguments.
\item
For \tcode{store_fmaximum_num} and \tcode{store_fminimum_num},
the maximum and minimum computation is performed
as if by \tcode{fmaximum_num} and \tcode{fminimum_num}, respectively,
with the value pointed to by \tcode{this} and
the first parameter as the arguments.
\item
For \tcode{store_max} and \tcode{store_min},
the maximum and minimum computation is performed
as if by \tcode{fmaximum_num} and \tcode{fminimum_num}, respectively,
with the value pointed to by \tcode{this} and
the first parameter as the arguments, except that:
\begin{itemize}
\item
If both arguments are NaN,
an unspecified NaN value replaces the value pointed to by \tcode{this}.
\item
If exactly one argument is a NaN,
either the other argument or an unspecified NaN value replaces
the value pointed to by \tcode{this};
it is unspecified which.
\item
If the arguments are differently signed zeros,
which of these values replaces the value pointed to by \tcode{this} is unspecified.
\end{itemize}
\end{itemize}

\pnum
\recommended
The implementation of \tcode{store_max} and \tcode{store_min}
should treat negative zero as smaller than positive zero.
\end{itemdescr}

\indexlibrarymember{operator+=}{atomic<T*>}%
\indexlibrarymember{operator-=}{atomic<T*>}%
\indexlibrarymember{operator+=}{atomic<\placeholder{floating-point-type}>}%
\indexlibrarymember{operator-=}{atomic<\placeholder{floating-point-type}>}%
\begin{itemdecl}
@\placeholder{floating-point-type}@ operator @\placeholder{op}@=(@\placeholder{floating-point-type}@ operand) volatile noexcept;
constexpr @\placeholder{floating-point-type}@ operator @\placeholder{op}@=(@\placeholder{floating-point-type}@ operand) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\effects
Equivalent to: \tcode{return fetch_\placeholder{key}(operand) \placeholder{op} operand;}

\pnum
\remarks
If the result is not a representable value for its type\iref{expr.pre}
the result is unspecified, but the operations otherwise have no undefined
behavior. Atomic arithmetic operations on \tcode{\placeholder{floating-point-type}}
should conform to the \tcode{std::numeric_limits<\placeholder{floating-point-type}>}
traits associated with the floating-point type\iref{limits.syn}.
The floating-point environment\iref{cfenv} for atomic arithmetic operations
on \tcode{\placeholder{floating-point-type}} may be different than the
calling thread's floating-point environment.
\end{itemdescr}

\rSec3[atomics.types.pointer]{Partial specialization for pointers}
\indexlibraryglobal{atomic<T*>}%

\begin{codeblock}
namespace std {
  template<class T> struct atomic<T*> {
    using value_type = T*;
    using difference_type = ptrdiff_t;

    static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@;
    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;

    constexpr atomic() noexcept;
    constexpr atomic(T*) noexcept;
    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;

    void store(T*, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store(T*, memory_order = memory_order::seq_cst) noexcept;
    T* operator=(T*) volatile noexcept;
    constexpr T* operator=(T*) noexcept;
    T* load(memory_order = memory_order::seq_cst) const volatile noexcept;
    constexpr T* load(memory_order = memory_order::seq_cst) const noexcept;
    operator T*() const volatile noexcept;
    constexpr operator T*() const noexcept;

    T* exchange(T*, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr T* exchange(T*, memory_order = memory_order::seq_cst) noexcept;
    bool compare_exchange_weak(T*&, T*, memory_order, memory_order) volatile noexcept;
    constexpr bool compare_exchange_weak(T*&, T*, memory_order, memory_order) noexcept;
    bool compare_exchange_strong(T*&, T*, memory_order, memory_order) volatile noexcept;
    constexpr bool compare_exchange_strong(T*&, T*, memory_order, memory_order) noexcept;
    bool compare_exchange_weak(T*&, T*,
                               memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr bool compare_exchange_weak(T*&, T*,
                                         memory_order = memory_order::seq_cst) noexcept;
    bool compare_exchange_strong(T*&, T*,
                                 memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr bool compare_exchange_strong(T*&, T*,
                                           memory_order = memory_order::seq_cst) noexcept;

    T* fetch_add(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr T* fetch_add(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept;
    T* fetch_sub(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr T* fetch_sub(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept;
    T* fetch_max(T*, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr T* fetch_max(T*, memory_order = memory_order::seq_cst) noexcept;
    T* fetch_min(T*, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr T* fetch_min(T*, memory_order = memory_order::seq_cst) noexcept;

    void store_add(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_add(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept;
    void store_sub(ptrdiff_t, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_sub(ptrdiff_t, memory_order = memory_order::seq_cst) noexcept;
    void store_max(T*, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_max(T*, memory_order = memory_order::seq_cst) noexcept;
    void store_min(T*, memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void store_min(T*, memory_order = memory_order::seq_cst) noexcept;

    T* operator++(int) volatile noexcept;
    constexpr T* operator++(int) noexcept;
    T* operator--(int) volatile noexcept;
    constexpr T* operator--(int) noexcept;
    T* operator++() volatile noexcept;
    constexpr T* operator++() noexcept;
    T* operator--() volatile noexcept;
    constexpr T* operator--() noexcept;
    T* operator+=(ptrdiff_t) volatile noexcept;
    constexpr T* operator+=(ptrdiff_t) noexcept;
    T* operator-=(ptrdiff_t) volatile noexcept;
    constexpr T* operator-=(ptrdiff_t) noexcept;

    void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
    constexpr void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
    void notify_one() volatile noexcept;
    constexpr void notify_one() noexcept;
    void notify_all() volatile noexcept;
    constexpr void notify_all() noexcept;
  };
}
\end{codeblock}

\indexlibraryglobal{atomic<T*>}%
\pnum
There is a partial specialization of the \tcode{atomic} class template for pointers.
Specializations of this partial specialization are standard-layout structs.
They each have a trivial destructor.

\pnum
Descriptions are provided below only for members that differ from the primary template.

\pnum
The following operations perform pointer arithmetic.
The correspondence among key, operator, and computation is specified
in \tref{atomic.types.pointer.comp}.

\begin{floattable}
{Atomic pointer computations}{atomic.types.pointer.comp}{lll|lll}
\hline
\hdstyle{\tcode{\placeholder{key}}}  &
  \hdstyle{Op}                       &
  \hdstyle{Computation}              &
\hdstyle{\tcode{\placeholder{key}}}  &
  \hdstyle{Op}                       &
  \hdstyle{Computation}  \\ \hline
\tcode{add}       &
  \tcode{+}       &
  addition        &
\tcode{sub}       &
  \tcode{-}       &
  subtraction     \\
\tcode{max}       &
                  &
  maximum         &
\tcode{min}       &
                  &
  minimum         \\
\end{floattable}

\indexlibraryglobal{atomic_fetch_add}%
\indexlibraryglobal{atomic_fetch_max}%
\indexlibraryglobal{atomic_fetch_min}%
\indexlibraryglobal{atomic_fetch_sub}%
\indexlibraryglobal{atomic_fetch_add_explicit}%
\indexlibraryglobal{atomic_fetch_max_explicit}%
\indexlibraryglobal{atomic_fetch_min_explicit}%
\indexlibraryglobal{atomic_fetch_sub_explicit}%
\indexlibrarymember{fetch_add}{atomic<T*>}%
\indexlibrarymember{fetch_max}{atomic<T*>}%
\indexlibrarymember{fetch_min}{atomic<T*>}%
\indexlibrarymember{fetch_sub}{atomic<T*>}%
\begin{itemdecl}
T* fetch_@\placeholdernc{key}@(@\seeabovenc@ operand, memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr T* fetch_@\placeholdernc{key}@(@\seeabovenc@ operand, memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\mandates
\tcode{T} is a complete object type.
\begin{note}
Pointer arithmetic on \tcode{void*} or function pointers is ill-formed.
\end{note}

\pnum
\effects
Atomically replaces the value pointed to by
\keyword{this} with the result of the computation applied to the
value pointed to by \keyword{this} and the given \tcode{operand}.
Memory is affected according to the value of \tcode{order}.
These operations are atomic read-modify-write operations\iref{intro.multithread}.

\pnum
\returns
Atomically, the value pointed to by \keyword{this} immediately before the effects.

\pnum
\remarks
The result may be an undefined address,
but the operations otherwise have no undefined behavior.

\pnum
For \tcode{fetch_max} and \tcode{fetch_min}, the maximum and minimum
computation is performed as if by \tcode{max} and \tcode{min}
algorithms\iref{alg.min.max}, respectively, with the object value and the first
parameter as the arguments.

\begin{note}
If the pointers point to different complete objects (or subobjects thereof),
the \tcode{<} operator does not establish a strict weak ordering
(\tref{cpp17.lessthancomparable}, \ref{expr.rel}).
\end{note}
\end{itemdescr}

\indexlibraryglobal{atomic_store_add}%
\indexlibraryglobal{atomic_store_max}%
\indexlibraryglobal{atomic_store_min}%
\indexlibraryglobal{atomic_store_sub}%
\indexlibraryglobal{atomic_store_add_explicit}%
\indexlibraryglobal{atomic_store_max_explicit}%
\indexlibraryglobal{atomic_store_min_explicit}%
\indexlibraryglobal{atomic_store_sub_explicit}%
\indexlibrarymember{store_add}{atomic<T*>}%
\indexlibrarymember{store_max}{atomic<T*>}%
\indexlibrarymember{store_min}{atomic<T*>}%
\indexlibrarymember{store_sub}{atomic<T*>}%
\begin{itemdecl}
void store_@\placeholdernc{key}@(@\seeabovenc@ operand, memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr void store_@\placeholdernc{key}@(@\seeabovenc@ operand, memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\mandates
\tcode{T} is a complete object type.
\begin{note}
Pointer arithmetic on \tcode{void*} or function pointers is ill-formed.
\end{note}

\pnum
\effects
Atomically replaces the value pointed to by \tcode{this}
with the result of the computation applied to
the value pointed to by \tcode{this} and the given \tcode{operand}.
Memory is affected according to the value of \tcode{order}.
These operations are atomic modify-write operations\iref{atomics.order}.

\pnum
\remarks
The result may be an undefined address,
but the operations otherwise have no undefined behavior.
For \tcode{store_max} and \tcode{store_min},
the maximum and minimum computation is performed
as if by \tcode{max} and \tcode{min} algorithms\iref{alg.min.max}, respectively,
with the value pointed to by \tcode{this} and
the first parameter as the arguments.
\begin{note}
If the pointers point to different complete objects (or subobjects thereof),
the \tcode{<} operator does not establish
a strict weak ordering~(\tref{cpp17.lessthancomparable}, \ref{expr.rel}).
\end{note}
\end{itemdescr}

\indexlibrarymember{operator+=}{atomic<T*>}%
\indexlibrarymember{operator-=}{atomic<T*>}%
\begin{itemdecl}
T* operator @\placeholder{op}@=(ptrdiff_t operand) volatile noexcept;
constexpr T* operator @\placeholder{op}@=(ptrdiff_t operand) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\effects
Equivalent to: \tcode{return fetch_\placeholder{key}(operand) \placeholder{op} operand;}
\end{itemdescr}

\rSec3[atomics.types.memop]{Member operators common to integers and pointers to objects}

\indexlibrarymember{operator++}{atomic<T*>}%
\indexlibrarymember{operator++}{atomic<\placeholder{integral-type}>}%
\begin{itemdecl}
value_type operator++(int) volatile noexcept;
constexpr value_type operator++(int) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\effects
Equivalent to: \tcode{return fetch_add(1);}
\end{itemdescr}

\indexlibrarymember{operator--}{atomic<T*>}%
\indexlibrarymember{operator--}{atomic<\placeholder{integral-type}>}%
\begin{itemdecl}
value_type operator--(int) volatile noexcept;
constexpr value_type operator--(int) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\effects
Equivalent to: \tcode{return fetch_sub(1);}
\end{itemdescr}

\indexlibrarymember{operator++}{atomic<T*>}%
\indexlibrarymember{operator++}{atomic<\placeholder{integral-type}>}%
\begin{itemdecl}
value_type operator++() volatile noexcept;
constexpr value_type operator++() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\effects
Equivalent to: \tcode{return fetch_add(1) + 1;}
\end{itemdescr}

\indexlibrarymember{operator--}{atomic<T*>}%
\indexlibrarymember{operator--}{atomic<\placeholder{integral-type}>}%
\begin{itemdecl}
value_type operator--() volatile noexcept;
constexpr value_type operator--() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
For the \tcode{volatile} overload of this function,
\tcode{is_always_lock_free} is \tcode{true}.

\pnum
\effects
Equivalent to: \tcode{return fetch_sub(1) - 1;}
\end{itemdescr}

\rSec3[util.smartptr.atomic]{Partial specializations for smart pointers}%
\indextext{atomic!smart pointers|(}%

\rSec4[util.smartptr.atomic.general]{General}

\pnum
The library provides partial specializations of the \tcode{atomic} template
for shared-ownership smart pointers\iref{util.sharedptr}.
\begin{note}
The partial specializations are declared in header \libheaderref{memory}.
\end{note}
The behavior of all operations is as specified in \ref{atomics.types.generic},
unless specified otherwise.
The template parameter \tcode{T} of these partial specializations
may be an incomplete type.

\pnum
All changes to an atomic smart pointer in \ref{util.smartptr.atomic}, and
all associated \tcode{use_count} increments,
are guaranteed to be performed atomically.
Associated \tcode{use_count} decrements
are sequenced after the atomic operation,
but are not required to be part of it.
Any associated deletion and deallocation
are sequenced after the atomic update step and
are not part of the atomic operation.
\begin{note}
If the atomic operation uses locks,
locks acquired by the implementation
will be held when any \tcode{use_count} adjustments are performed, and
will not be held when any destruction or deallocation
resulting from this is performed.
\end{note}

\pnum
\begin{example}
\begin{codeblock}
template<typename T> class atomic_list {
  struct node {
    T t;
    shared_ptr<node> next;
  };
  atomic<shared_ptr<node>> head;

public:
  shared_ptr<node> find(T t) const {
    auto p = head.load();
    while (p && p->t != t)
      p = p->next;

    return p;
  }

  void push_front(T t) {
    auto p = make_shared<node>();
    p->t = t;
    p->next = head;
    while (!head.compare_exchange_weak(p->next, p)) {}
  }
};
\end{codeblock}
\end{example}

\rSec4[util.smartptr.atomic.shared]{Partial specialization for \tcode{shared_ptr}}
\indexlibraryglobal{atomic<shared_ptr<T>>}%
\begin{codeblock}
namespace std {
  template<class T> struct atomic<shared_ptr<T>> {
    using value_type = shared_ptr<T>;

    static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@;
    bool is_lock_free() const noexcept;

    constexpr atomic() noexcept;
    constexpr atomic(nullptr_t) noexcept : atomic() { }
    constexpr atomic(shared_ptr<T> desired) noexcept;
    atomic(const atomic&) = delete;
    void operator=(const atomic&) = delete;

    constexpr shared_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
    constexpr operator shared_ptr<T>() const noexcept;
    constexpr void store(shared_ptr<T> desired,
                         memory_order order = memory_order::seq_cst) noexcept;
    constexpr void operator=(shared_ptr<T> desired) noexcept;
    constexpr void operator=(nullptr_t) noexcept;

    constexpr shared_ptr<T> exchange(shared_ptr<T> desired,
                                     memory_order order = memory_order::seq_cst) noexcept;
    constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
                                         memory_order success, memory_order failure) noexcept;
    constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
                                           memory_order success, memory_order failure) noexcept;
    constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
                                         memory_order order = memory_order::seq_cst) noexcept;
    constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
                                           memory_order order = memory_order::seq_cst) noexcept;

    constexpr void wait(shared_ptr<T> old,
                        memory_order order = memory_order::seq_cst) const noexcept;
    constexpr void notify_one() noexcept;
    constexpr void notify_all() noexcept;

  private:
    shared_ptr<T> p;            // \expos
  };
}
\end{codeblock}

\indexlibraryctor{atomic<shared_ptr<T>>}%
\begin{itemdecl}
constexpr atomic() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Value-initializes \tcode{p}.
\end{itemdescr}

\indexlibraryctor{atomic<shared_ptr<T>>}%
\begin{itemdecl}
constexpr atomic(shared_ptr<T> desired) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes the object with the value \tcode{desired}.
Initialization is not an atomic operation\iref{intro.multithread}.
\begin{note}
It is possible to have an access to
an atomic object \tcode{A} race with its construction,
for example,
by communicating the address of the just-constructed object \tcode{A}
to another thread via \tcode{memory_order::relaxed} operations
on a suitable atomic pointer variable, and
then immediately accessing \tcode{A} in the receiving thread.
This results in undefined behavior.
\end{note}
\end{itemdescr}

\indexlibrarymember{store}{atomic<shared_ptr<T>>}%
\begin{itemdecl}
constexpr void store(shared_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::release}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Atomically replaces the value pointed to by \keyword{this} with
the value of \tcode{desired} as if by \tcode{p.swap(desired)}.
Memory is affected according to the value of \tcode{order}.
\end{itemdescr}

\indexlibrarymember{operator=}{atomic<shared_ptr<T>>}%
\begin{itemdecl}
constexpr void operator=(shared_ptr<T> desired) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to \tcode{store(desired)}.
\end{itemdescr}

\indexlibrarymember{operator=}{atomic<shared_ptr<T>>}%
\begin{itemdecl}
constexpr void operator=(nullptr_t) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to \tcode{store(nullptr)}.
\end{itemdescr}

\indexlibrarymember{load}{atomic<shared_ptr<T>>}%
\begin{itemdecl}
constexpr shared_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::acquire}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Memory is affected according to the value of \tcode{order}.

\pnum
\returns
Atomically returns \tcode{p}.
\end{itemdescr}

\indexlibrarymember{operator shared_ptr<T>}{atomic<shared_ptr<T>>}%
\begin{itemdecl}
constexpr operator shared_ptr<T>() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return load();}
\end{itemdescr}

\indexlibrarymember{exchange}{atomic<shared_ptr<T>>}%
\begin{itemdecl}
constexpr shared_ptr<T> exchange(shared_ptr<T> desired,
                                 memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Atomically replaces \tcode{p} with \tcode{desired}
as if by \tcode{p.swap(desired)}.
Memory is affected according to the value of \tcode{order}.
This is an atomic read-modify-write operation\iref{intro.races}.

\pnum
\returns
Atomically returns the value of \tcode{p} immediately before the effects.
\end{itemdescr}

\indexlibrarymember{compare_exchange_weak}{atomic<shared_ptr<T>>}%
\indexlibrarymember{compare_exchange_strong}{atomic<shared_ptr<T>>}%
\begin{itemdecl}
constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
                                     memory_order success, memory_order failure) noexcept;
constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
                                       memory_order success, memory_order failure) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{failure} is
\tcode{memory_order::relaxed},
\tcode{memory_order::acquire}, or
\tcode{memory_order::\linebreak seq_cst}.

\pnum
\effects
If \tcode{p} is equivalent to \tcode{expected},
assigns \tcode{desired} to \tcode{p} and
has synchronization semantics corresponding to the value of \tcode{success},
otherwise assigns \tcode{p} to \tcode{expected} and
has synchronization semantics corresponding to the value of \tcode{failure}.

\pnum
\returns
\tcode{true} if \tcode{p} was equivalent to \tcode{expected},
\tcode{false} otherwise.

\pnum
\remarks
Two \tcode{shared_ptr} objects are equivalent if
they store the same pointer value and
either share ownership or are both empty.
The weak form may fail spuriously. See \ref{atomics.types.operations}.

\pnum
If the operation returns \tcode{true},
\tcode{expected} is not accessed after the atomic update and
the operation is an atomic read-modify-write operation\iref{intro.multithread}
on the memory pointed to by \keyword{this}.
Otherwise, the operation is an atomic load operation on that memory, and
\tcode{expected} is updated with the existing value
read from the atomic object in the attempted atomic update.
The \tcode{use_count} update corresponding to the write to \tcode{expected}
is part of the atomic operation.
The write to \tcode{expected} itself
is not required to be part of the atomic operation.
\end{itemdescr}

\indexlibrarymember{compare_exchange_weak}{atomic<shared_ptr<T>>}%
\begin{itemdecl}
constexpr bool compare_exchange_weak(shared_ptr<T>& expected, shared_ptr<T> desired,
                                     memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return compare_exchange_weak(expected, desired, order, fail_order);
\end{codeblock}
where \tcode{fail_order} is the same as \tcode{order}
except that a value of \tcode{memory_order::acq_rel}
shall be replaced by the value \tcode{memory_order::acquire} and
a value of \tcode{memory_order::release}
shall be replaced by the value \tcode{memory_order::relaxed}.
\end{itemdescr}

\indexlibrarymember{compare_exchange_strong}{atomic<shared_ptr<T>>}%
\begin{itemdecl}
constexpr bool compare_exchange_strong(shared_ptr<T>& expected, shared_ptr<T> desired,
                                       memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return compare_exchange_strong(expected, desired, order, fail_order);
\end{codeblock}
where \tcode{fail_order} is the same as \tcode{order}
except that a value of \tcode{memory_order::acq_rel}
shall be replaced by the value \tcode{memory_order::acquire} and
a value of \tcode{memory_order::release}
shall be replaced by the value \tcode{memory_order::relaxed}.
\end{itemdescr}

\indexlibrarymember{wait}{atomic<shared_ptr<T>>}%
\begin{itemdecl}
constexpr void wait(shared_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::acquire}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Repeatedly performs the following steps, in order:
\begin{itemize}
\item
  Evaluates \tcode{load(order)} and compares it to \tcode{old}.
\item
  If the two are not equivalent, returns.
\item
  Blocks until it
  is unblocked by an atomic notifying operation or is unblocked spuriously.
\end{itemize}

\pnum
\remarks
Two \tcode{shared_ptr} objects are equivalent
if they store the same pointer and either share ownership or are both empty.
This function is an atomic waiting operation\iref{atomics.wait}.
\end{itemdescr}

\indexlibrarymember{notify_one}{atomic<shared_ptr<T>>}%
\begin{itemdecl}
constexpr void notify_one() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Unblocks the execution of at least one atomic waiting operation
that is eligible to be unblocked\iref{atomics.wait} by this call,
if any such atomic waiting operations exist.

\pnum
\remarks
This function is an atomic notifying operation\iref{atomics.wait}.
\end{itemdescr}

\indexlibrarymember{notify_all}{atomic<shared_ptr<T>>}%
\begin{itemdecl}
constexpr void notify_all() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Unblocks the execution of all atomic waiting operations
that are eligible to be unblocked\iref{atomics.wait} by this call.

\pnum
\remarks
This function is an atomic notifying operation\iref{atomics.wait}.
\end{itemdescr}

\rSec4[util.smartptr.atomic.weak]{Partial specialization for \tcode{weak_ptr}}

\indexlibraryglobal{atomic<weak_ptr<T>>}%
\begin{codeblock}
namespace std {
  template<class T> struct atomic<weak_ptr<T>> {
    using value_type = weak_ptr<T>;

    static constexpr bool is_always_lock_free = @\impdefx{whether a given \tcode{atomic} type's operations are always lock free}@;
    bool is_lock_free() const noexcept;

    constexpr atomic() noexcept;
    constexpr atomic(weak_ptr<T> desired) noexcept;
    atomic(const atomic&) = delete;
    void operator=(const atomic&) = delete;

    constexpr weak_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
    constexpr operator weak_ptr<T>() const noexcept;
    constexpr void store(weak_ptr<T> desired,
                         memory_order order = memory_order::seq_cst) noexcept;
    constexpr void operator=(weak_ptr<T> desired) noexcept;

    constexpr weak_ptr<T> exchange(weak_ptr<T> desired,
                                   memory_order order = memory_order::seq_cst) noexcept;
    constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
                                         memory_order success, memory_order failure) noexcept;
    constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
                                           memory_order success, memory_order failure) noexcept;
    constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
                                         memory_order order = memory_order::seq_cst) noexcept;
    constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
                                           memory_order order = memory_order::seq_cst) noexcept;

    constexpr void wait(weak_ptr<T> old,
                        memory_order order = memory_order::seq_cst) const noexcept;
    constexpr void notify_one() noexcept;
    constexpr void notify_all() noexcept;

  private:
    weak_ptr<T> p;              // \expos
  };
}
\end{codeblock}

\indexlibraryctor{atomic<weak_ptr<T>>}%
\begin{itemdecl}
constexpr atomic() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Value-initializes \tcode{p}.
\end{itemdescr}

\indexlibraryctor{atomic<weak_ptr<T>>}%
\begin{itemdecl}
constexpr atomic(weak_ptr<T> desired) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes the object with the value \tcode{desired}.
Initialization is not an atomic operation\iref{intro.multithread}.
\begin{note}
It is possible to have an access to
an atomic object \tcode{A} race with its construction,
for example,
by communicating the address of the just-constructed object \tcode{A}
to another thread via \tcode{memory_order::relaxed} operations
on a suitable atomic pointer variable, and
then immediately accessing \tcode{A} in the receiving thread.
This results in undefined behavior.
\end{note}
\end{itemdescr}

\indexlibrarymember{store}{atomic<weak_ptr<T>>}%
\begin{itemdecl}
constexpr void store(weak_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::release}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Atomically replaces the value pointed to by \keyword{this} with
the value of \tcode{desired} as if by \tcode{p.swap(desired)}.
Memory is affected according to the value of \tcode{order}.
\end{itemdescr}

\indexlibrarymember{operator=}{atomic<weak_ptr<T>>}%
\begin{itemdecl}
constexpr void operator=(weak_ptr<T> desired) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to \tcode{store(desired)}.
\end{itemdescr}

\indexlibrarymember{load}{atomic<weak_ptr<T>>}%
\begin{itemdecl}
constexpr weak_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::acquire}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Memory is affected according to the value of \tcode{order}.

\pnum
\returns
Atomically returns \tcode{p}.
\end{itemdescr}

\indexlibrarymember{operator weak_ptr<T>}{atomic<weak_ptr<T>>}%
\begin{itemdecl}
constexpr operator weak_ptr<T>() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return load();}
\end{itemdescr}

\indexlibrarymember{exchange}{atomic<weak_ptr<T>>}%
\begin{itemdecl}
constexpr weak_ptr<T> exchange(weak_ptr<T> desired,
                               memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Atomically replaces \tcode{p} with \tcode{desired}
as if by \tcode{p.swap(desired)}.
Memory is affected according to the value of \tcode{order}.
This is an atomic read-modify-write operation\iref{intro.races}.

\pnum
\returns
Atomically returns the value of \tcode{p} immediately before the effects.
\end{itemdescr}

\indexlibrarymember{compare_exchange_weak}{atomic<weak_ptr<T>>}%
\begin{itemdecl}
constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
                                     memory_order success, memory_order failure) noexcept;
constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
                                       memory_order success, memory_order failure) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{failure} is
\tcode{memory_order::relaxed},
\tcode{memory_order::acquire}, or
\tcode{memory_order::\linebreak seq_cst}.

\pnum
\effects
If \tcode{p} is equivalent to \tcode{expected},
assigns \tcode{desired} to \tcode{p} and
has synchronization semantics corresponding to the value of \tcode{success},
otherwise assigns \tcode{p} to \tcode{expected} and
has synchronization semantics corresponding to the value of \tcode{failure}.

\pnum
\returns
\tcode{true} if \tcode{p} was equivalent to \tcode{expected},
\tcode{false} otherwise.

\pnum
\remarks
Two \tcode{weak_ptr} objects are equivalent if
they store the same pointer value and
either share ownership or are both empty.
The weak form may fail spuriously. See \ref{atomics.types.operations}.

\pnum
If the operation returns \tcode{true},
\tcode{expected} is not accessed after the atomic update and
the operation is an atomic read-modify-write operation\iref{intro.multithread}
on the memory pointed to by \keyword{this}.
Otherwise, the operation is an atomic load operation on that memory, and
\tcode{expected} is updated with the existing value
read from the atomic object in the attempted atomic update.
The \tcode{use_count} update corresponding to the write to \tcode{expected}
is part of the atomic operation.
The write to \tcode{expected} itself
is not required to be part of the atomic operation.
\end{itemdescr}

\indexlibrarymember{compare_exchange_weak}{atomic<weak_ptr<T>>}%
\begin{itemdecl}
constexpr bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
                                     memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return compare_exchange_weak(expected, desired, order, fail_order);
\end{codeblock}
where \tcode{fail_order} is the same as \tcode{order}
except that a value of \tcode{memory_order::acq_rel}
shall be replaced by the value \tcode{memory_order::acquire} and
a value of \tcode{memory_order::release}
shall be replaced by the value \tcode{memory_order::relaxed}.
\end{itemdescr}

\indexlibrarymember{compare_exchange_strong}{atomic<weak_ptr<T>>}%
\begin{itemdecl}
constexpr bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
                                       memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return compare_exchange_strong(expected, desired, order, fail_order);
\end{codeblock}
where \tcode{fail_order} is the same as \tcode{order}
except that a value of \tcode{memory_order::acq_rel}
shall be replaced by the value \tcode{memory_order::acquire} and
a value of \tcode{memory_order::release}
shall be replaced by the value \tcode{memory_order::relaxed}.
\end{itemdescr}

\indexlibrarymember{wait}{atomic<weak_ptr<T>>}%
\begin{itemdecl}
constexpr void wait(weak_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::acquire}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Repeatedly performs the following steps, in order:
\begin{itemize}
\item
  Evaluates \tcode{load(order)} and compares it to \tcode{old}.
\item
  If the two are not equivalent, returns.
\item
  Blocks until it
  is unblocked by an atomic notifying operation or is unblocked spuriously.
\end{itemize}

\pnum
\remarks
Two \tcode{weak_ptr} objects are equivalent
if they store the same pointer and either share ownership or are both empty.
This function is an atomic waiting operation\iref{atomics.wait}.
\end{itemdescr}


\indexlibrarymember{notify_one}{atomic<weak_ptr<T>>}%
\begin{itemdecl}
constexpr void notify_one() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Unblocks the execution of at least one atomic waiting operation
that is eligible to be unblocked\iref{atomics.wait} by this call,
if any such atomic waiting operations exist.

\pnum
\remarks
This function is an atomic notifying operation\iref{atomics.wait}.
\end{itemdescr}

\indexlibrarymember{notify_all}{atomic<weak_ptr<T>>}%
\begin{itemdecl}
constexpr void notify_all() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Unblocks the execution of all atomic waiting operations
that are eligible to be unblocked\iref{atomics.wait} by this call.

\pnum
\remarks
This function is an atomic notifying operation\iref{atomics.wait}.
\end{itemdescr}
\indextext{atomic!smart pointers|)}

\rSec2[atomics.nonmembers]{Non-member functions}

\pnum
A non-member function template whose name matches the pattern
\tcode{atomic_\placeholder{f}} or the pattern \tcode{atomic_\placeholder{f}_explicit}
invokes the member function \tcode{\placeholder{f}}, with the value of the
first parameter as the object expression and the values of the remaining parameters
(if any) as the arguments of the member function call, in order. An argument
for a parameter of type \tcode{atomic<T>::value_type*} is dereferenced when
passed to the member function call.
If no such member function exists, the program is ill-formed.

\pnum
\begin{note}
The non-member functions enable programmers to write code that can be
compiled as either C or \Cpp{}, for example in a shared header file.
\end{note}

\rSec2[atomics.flag]{Flag type and operations}

\begin{codeblock}
namespace std {
  struct atomic_flag {
    constexpr atomic_flag() noexcept;
    atomic_flag(const atomic_flag&) = delete;
    atomic_flag& operator=(const atomic_flag&) = delete;
    atomic_flag& operator=(const atomic_flag&) volatile = delete;

    bool test(memory_order = memory_order::seq_cst) const volatile noexcept;
    constexpr bool test(memory_order = memory_order::seq_cst) const noexcept;
    bool test_and_set(memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr bool test_and_set(memory_order = memory_order::seq_cst) noexcept;
    void clear(memory_order = memory_order::seq_cst) volatile noexcept;
    constexpr void clear(memory_order = memory_order::seq_cst) noexcept;

    void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
    constexpr void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
    void notify_one() volatile noexcept;
    constexpr void notify_one() noexcept;
    void notify_all() volatile noexcept;
    constexpr void notify_all() noexcept;
  };
}
\end{codeblock}

\pnum
The \tcode{atomic_flag} type provides the classic test-and-set functionality. It has two states, set and clear.

\pnum
Operations on an object of type \tcode{atomic_flag} shall be lock-free.
The operations should also be address-free.

\pnum
The \tcode{atomic_flag} type is a standard-layout struct.
It has a trivial destructor.

\indexlibraryctor{atomic_flag}%
\begin{itemdecl}
constexpr atomic_flag::atomic_flag() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{*this} to the clear state.
\end{itemdescr}

\indexlibraryglobal{atomic_flag_test}%
\indexlibraryglobal{atomic_flag_test_explicit}%
\indexlibrarymember{test}{atomic_flag}%
\begin{itemdecl}
bool atomic_flag_test(const volatile atomic_flag* object) noexcept;
constexpr bool atomic_flag_test(const atomic_flag* object) noexcept;
bool atomic_flag_test_explicit(const volatile atomic_flag* object,
                               memory_order order) noexcept;
constexpr bool atomic_flag_test_explicit(const atomic_flag* object,
                               memory_order order) noexcept;
bool atomic_flag::test(memory_order order = memory_order::seq_cst) const volatile noexcept;
constexpr bool atomic_flag::test(memory_order order = memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
For \tcode{atomic_flag_test}, let \tcode{order} be \tcode{memory_order::seq_cst}.

\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::acquire}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Memory is affected according to the value of \tcode{order}.

\pnum
\returns
Atomically returns the value pointed to by \tcode{object} or \keyword{this}.
\end{itemdescr}

\indexlibraryglobal{atomic_flag_test_and_set}%
\indexlibraryglobal{atomic_flag_test_and_set_explicit}%
\indexlibrarymember{test_and_set}{atomic_flag}%
\begin{itemdecl}
bool atomic_flag_test_and_set(volatile atomic_flag* object) noexcept;
constexpr bool atomic_flag_test_and_set(atomic_flag* object) noexcept;
bool atomic_flag_test_and_set_explicit(volatile atomic_flag* object, memory_order order) noexcept;
constexpr bool atomic_flag_test_and_set_explicit(atomic_flag* object, memory_order order) noexcept;
bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Atomically sets the value pointed to by \tcode{object} or by \keyword{this} to \tcode{true}. Memory is affected according to the value of
\tcode{order}. These operations are atomic read-modify-write operations\iref{intro.multithread}.

\pnum
\returns
Atomically, the value of the object immediately before the effects.
\end{itemdescr}

\indexlibraryglobal{atomic_flag_clear}%
\indexlibraryglobal{atomic_flag_clear_explicit}%
\indexlibrarymember{clear}{atomic_flag}%
\begin{itemdecl}
void atomic_flag_clear(volatile atomic_flag* object) noexcept;
constexpr void atomic_flag_clear(atomic_flag* object) noexcept;
void atomic_flag_clear_explicit(volatile atomic_flag* object, memory_order order) noexcept;
constexpr void atomic_flag_clear_explicit(atomic_flag* object, memory_order order) noexcept;
void atomic_flag::clear(memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr void atomic_flag::clear(memory_order order = memory_order::seq_cst) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::release}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Atomically sets the value pointed to by \tcode{object} or by \keyword{this} to
\tcode{false}. Memory is affected according to the value of \tcode{order}.
\end{itemdescr}

\indexlibraryglobal{atomic_flag_wait}%
\indexlibraryglobal{atomic_flag_wait_explicit}%
\indexlibrarymember{wait}{atomic_flag}%
\begin{itemdecl}
void atomic_flag_wait(const volatile atomic_flag* object, bool old) noexcept;
constexpr void atomic_flag_wait(const atomic_flag* object, bool old) noexcept;
void atomic_flag_wait_explicit(const volatile atomic_flag* object,
                               bool old, memory_order order) noexcept;
constexpr void atomic_flag_wait_explicit(const atomic_flag* object,
                               bool old, memory_order order) noexcept;
void atomic_flag::wait(bool old, memory_order order =
                                   memory_order::seq_cst) const volatile noexcept;
constexpr void atomic_flag::wait(bool old, memory_order order =
                                   memory_order::seq_cst) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
For \tcode{atomic_flag_wait},
let \tcode{order} be \tcode{memory_order::seq_cst}.
Let \tcode{flag} be \tcode{object} for the non-member functions and
\keyword{this} for the member functions.

\pnum
\expects
\tcode{order} is
\tcode{memory_order::relaxed},
\tcode{memory_order::acquire}, or
\tcode{memory_order::seq_cst}.

\pnum
\effects
Repeatedly performs the following steps, in order:
\begin{itemize}
\item
  Evaluates \tcode{flag->test(order) != old}.
\item
  If the result of that evaluation is \tcode{true}, returns.
\item
  Blocks until it
  is unblocked by an atomic notifying operation or is unblocked spuriously.
\end{itemize}

\pnum
\remarks
This function is an atomic waiting operation\iref{atomics.wait}.
\end{itemdescr}

\begin{itemdecl}
void atomic_flag_notify_one(volatile atomic_flag* object) noexcept;
constexpr void atomic_flag_notify_one(atomic_flag* object) noexcept;
void atomic_flag::notify_one() volatile noexcept;
constexpr void atomic_flag::notify_one() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Unblocks the execution of at least one atomic waiting operation
that is eligible to be unblocked\iref{atomics.wait} by this call,
if any such atomic waiting operations exist.

\pnum
\remarks
This function is an atomic notifying operation\iref{atomics.wait}.
\end{itemdescr}

\begin{itemdecl}
void atomic_flag_notify_all(volatile atomic_flag* object) noexcept;
constexpr void atomic_flag_notify_all(atomic_flag* object) noexcept;
void atomic_flag::notify_all() volatile noexcept;
constexpr void atomic_flag::notify_all() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Unblocks the execution of all atomic waiting operations
that are eligible to be unblocked\iref{atomics.wait} by this call.

\pnum
\remarks
This function is an atomic notifying operation\iref{atomics.wait}.
\end{itemdescr}

\begin{itemdecl}
#define @\libmacro{ATOMIC_FLAG_INIT}@ @\seebelow@
\end{itemdecl}

\begin{itemdescr}
\pnum
\remarks
The macro \tcode{ATOMIC_FLAG_INIT} is defined in such a way that
it can be used to initialize an object of type \tcode{atomic_flag}
to the clear state.
The macro can be used in the form:
\begin{codeblock}
atomic_flag guard = ATOMIC_FLAG_INIT;
\end{codeblock}
It is unspecified whether the macro can be used
in other initialization contexts.
For a complete static-duration object, that initialization shall be static.
\end{itemdescr}

\rSec2[atomics.fences]{Fences}

\pnum
This subclause introduces synchronization primitives called \term{fences}. Fences can have
acquire semantics, release semantics, or both. A fence with acquire semantics is called
an \term{acquire fence}. A fence with release semantics is called a \term{release
fence}.

\pnum
A release fence $A$ synchronizes with an acquire fence $B$ if there exist
atomic operations $X$ and $Y$,
where $Y$ is not an atomic modify-write operation\iref{atomics.order},
both operating on some atomic object
$M$, such that $A$ is sequenced before $X$, $X$ modifies
$M$, $Y$ is sequenced before $B$, and $Y$ reads the value
written by $X$ or a value written by any side effect in the hypothetical release
sequence $X$ would head if it were a release operation.

\pnum
A release fence $A$ synchronizes with an atomic operation $B$ that
performs an acquire operation on an atomic object $M$ if there exists an atomic
operation $X$ such that $A$ is sequenced before $X$, $X$
modifies $M$, and $B$ reads the value written by $X$ or a value
written by any side effect in the hypothetical release sequence $X$ would head if
it were a release operation.

\pnum
An atomic operation $A$ that is a release operation on an atomic object
$M$ synchronizes with an acquire fence $B$ if there exists some atomic
operation $X$ on $M$ such that $X$ is sequenced before $B$
and reads the value written by $A$ or a value written by any side effect in the
release sequence headed by $A$.

\indexlibraryglobal{atomic_thread_fence}%
\begin{itemdecl}
extern "C" constexpr void atomic_thread_fence(memory_order order) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Depending on the value of \tcode{order}, this operation:
\begin{itemize}
\item has no effects, if \tcode{order == memory_order::relaxed};

\item is an acquire fence, if \tcode{order == memory_order::acquire};

\item is a release fence, if \tcode{order == memory_order::release};

\item is both an acquire fence and a release fence, if \tcode{order == memory_order::acq_rel};

\item is a sequentially consistent acquire and release fence, if \tcode{order == memory_order::seq_cst}.
\end{itemize}
\end{itemdescr}

\indexlibraryglobal{atomic_signal_fence}%
\begin{itemdecl}
extern "C" constexpr void atomic_signal_fence(memory_order order) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to \tcode{atomic_thread_fence(order)}, except that
the resulting ordering constraints are established only between a thread and a
signal handler executed in the same thread.

\pnum
\begin{note}
\tcode{atomic_signal_fence} can be used to specify the order in which actions
performed by the thread become visible to the signal handler.
Compiler optimizations and reorderings of loads and stores are inhibited in
the same way as with \tcode{atomic_thread_fence}, but the hardware fence instructions
that \tcode{atomic_thread_fence} would have inserted are not emitted.
\end{note}
\end{itemdescr}

\rSec2[stdatomic.h.syn]{C compatibility}

The header \libheaderdef{stdatomic.h} provides the following definitions:

\begin{codeblock}
template<class T>
  using @\exposid{std-atomic}@ = std::atomic<T>;        // \expos

#define @\libmacro{_Atomic}@(T) @\exposid{std-atomic}@<T>

#define @\libmacro{ATOMIC_BOOL_LOCK_FREE}@ @\seebelow@
#define @\libmacro{ATOMIC_CHAR_LOCK_FREE}@ @\seebelow@
#define @\libmacro{ATOMIC_CHAR16_T_LOCK_FREE}@ @\seebelow@
#define @\libmacro{ATOMIC_CHAR32_T_LOCK_FREE}@ @\seebelow@
#define @\libmacro{ATOMIC_WCHAR_T_LOCK_FREE}@ @\seebelow@
#define @\libmacro{ATOMIC_SHORT_LOCK_FREE}@ @\seebelow@
#define @\libmacro{ATOMIC_INT_LOCK_FREE}@ @\seebelow@
#define @\libmacro{ATOMIC_LONG_LOCK_FREE}@ @\seebelow@
#define @\libmacro{ATOMIC_LLONG_LOCK_FREE}@ @\seebelow@
#define @\libmacro{ATOMIC_POINTER_LOCK_FREE}@ @\seebelow@

using std::@\libglobal{memory_order}@;             // \seebelow
using std::@\libglobal{memory_order_relaxed}@;     // \seebelow
using std::@\libglobal{memory_order_consume}@;     // \seebelow
using std::@\libglobal{memory_order_acquire}@;     // \seebelow
using std::@\libglobal{memory_order_release}@;     // \seebelow
using std::@\libglobal{memory_order_acq_rel}@;     // \seebelow
using std::@\libglobal{memory_order_seq_cst}@;     // \seebelow

using std::@\libglobal{atomic_flag}@;              // \seebelow

using std::@\libglobal{atomic_bool}@;              // \seebelow
using std::@\libglobal{atomic_char}@;              // \seebelow
using std::@\libglobal{atomic_schar}@;             // \seebelow
using std::@\libglobal{atomic_uchar}@;             // \seebelow
using std::@\libglobal{atomic_short}@;             // \seebelow
using std::@\libglobal{atomic_ushort}@;            // \seebelow
using std::@\libglobal{atomic_int}@;               // \seebelow
using std::@\libglobal{atomic_uint}@;              // \seebelow
using std::@\libglobal{atomic_long}@;              // \seebelow
using std::@\libglobal{atomic_ulong}@;             // \seebelow
using std::@\libglobal{atomic_llong}@;             // \seebelow
using std::@\libglobal{atomic_ullong}@;            // \seebelow
using std::@\libglobal{atomic_char8_t}@;           // \seebelow
using std::@\libglobal{atomic_char16_t}@;          // \seebelow
using std::@\libglobal{atomic_char32_t}@;          // \seebelow
using std::@\libglobal{atomic_wchar_t}@;           // \seebelow
using std::@\libglobal{atomic_int8_t}@;            // \seebelow
using std::@\libglobal{atomic_uint8_t}@;           // \seebelow
using std::@\libglobal{atomic_int16_t}@;           // \seebelow
using std::@\libglobal{atomic_uint16_t}@;          // \seebelow
using std::@\libglobal{atomic_int32_t}@;           // \seebelow
using std::@\libglobal{atomic_uint32_t}@;          // \seebelow
using std::@\libglobal{atomic_int64_t}@;           // \seebelow
using std::@\libglobal{atomic_uint64_t}@;          // \seebelow
using std::@\libglobal{atomic_int_least8_t}@;      // \seebelow
using std::@\libglobal{atomic_uint_least8_t}@;     // \seebelow
using std::@\libglobal{atomic_int_least16_t}@;     // \seebelow
using std::@\libglobal{atomic_uint_least16_t}@;    // \seebelow
using std::@\libglobal{atomic_int_least32_t}@;     // \seebelow
using std::@\libglobal{atomic_uint_least32_t}@;    // \seebelow
using std::@\libglobal{atomic_int_least64_t}@;     // \seebelow
using std::@\libglobal{atomic_uint_least64_t}@;    // \seebelow
using std::@\libglobal{atomic_int_fast8_t}@;       // \seebelow
using std::@\libglobal{atomic_uint_fast8_t}@;      // \seebelow
using std::@\libglobal{atomic_int_fast16_t}@;      // \seebelow
using std::@\libglobal{atomic_uint_fast16_t}@;     // \seebelow
using std::@\libglobal{atomic_int_fast32_t}@;      // \seebelow
using std::@\libglobal{atomic_uint_fast32_t}@;     // \seebelow
using std::@\libglobal{atomic_int_fast64_t}@;      // \seebelow
using std::@\libglobal{atomic_uint_fast64_t}@;     // \seebelow
using std::@\libglobal{atomic_intptr_t}@;          // \seebelow
using std::@\libglobal{atomic_uintptr_t}@;         // \seebelow
using std::@\libglobal{atomic_size_t}@;            // \seebelow
using std::@\libglobal{atomic_ptrdiff_t}@;         // \seebelow
using std::@\libglobal{atomic_intmax_t}@;          // \seebelow
using std::@\libglobal{atomic_uintmax_t}@;         // \seebelow

using std::@\libglobal{atomic_is_lock_free}@;                          // \seebelow
using std::@\libglobal{atomic_load}@;                                  // \seebelow
using std::@\libglobal{atomic_load_explicit}@;                         // \seebelow
using std::@\libglobal{atomic_store}@;                                 // \seebelow
using std::@\libglobal{atomic_store_explicit}@;                        // \seebelow
using std::@\libglobal{atomic_exchange}@;                              // \seebelow
using std::@\libglobal{atomic_exchange_explicit}@;                     // \seebelow
using std::@\libglobal{atomic_compare_exchange_strong}@;               // \seebelow
using std::@\libglobal{atomic_compare_exchange_strong_explicit}@;      // \seebelow
using std::@\libglobal{atomic_compare_exchange_weak}@;                 // \seebelow
using std::@\libglobal{atomic_compare_exchange_weak_explicit}@;        // \seebelow
using std::@\libglobal{atomic_fetch_add}@;                             // \seebelow
using std::@\libglobal{atomic_fetch_add_explicit}@;                    // \seebelow
using std::@\libglobal{atomic_fetch_sub}@;                             // \seebelow
using std::@\libglobal{atomic_fetch_sub_explicit}@;                    // \seebelow
using std::@\libglobal{atomic_fetch_and}@;                             // \seebelow
using std::@\libglobal{atomic_fetch_and_explicit}@;                    // \seebelow
using std::@\libglobal{atomic_fetch_or}@;                              // \seebelow
using std::@\libglobal{atomic_fetch_or_explicit}@;                     // \seebelow
using std::@\libglobal{atomic_fetch_xor}@;                             // \seebelow
using std::@\libglobal{atomic_fetch_xor_explicit}@;                    // \seebelow
using std::@\libglobal{atomic_flag_test_and_set}@;                     // \seebelow
using std::@\libglobal{atomic_flag_test_and_set_explicit}@;            // \seebelow
using std::@\libglobal{atomic_flag_clear}@;                            // \seebelow
using std::@\libglobal{atomic_flag_clear_explicit}@;                   // \seebelow
#define @\libmacro{ATOMIC_FLAG_INIT}@ @\seebelow@

using std::@\libglobal{atomic_thread_fence}@;                          // \seebelow
using std::@\libglobal{atomic_signal_fence}@;                          // \seebelow
\end{codeblock}

\pnum
Each \grammarterm{using-declaration} for some name $A$ in the synopsis above
makes available the same entity as \tcode{std::$A$}
declared in \libheaderrefx{atomic}{atomics.syn}.
Each macro listed above other than \tcode{\libmacro{_Atomic}(T)}
is defined as in \libheader{atomic}.
It is unspecified whether \libheader{stdatomic.h} makes available
any declarations in namespace \tcode{std}.

\pnum
Each of the \grammarterm{using-declaration}s for
\tcode{int$N$_t}, \tcode{uint$N$_t}, \tcode{intptr_t}, and \tcode{uintptr_t}
listed above is declared if and only if the implementation declares
the corresponding \grammarterm{typedef-name} in \ref{atomics.syn}.

\pnum
Neither the \tcode{_Atomic} macro,
nor any of the non-macro global namespace declarations,
are provided by any \Cpp{} standard library header
other than \libheader{stdatomic.h}.

\pnum
\recommended
Implementations should ensure
that C and \Cpp{} representations of atomic objects are compatible,
so that the same object can be accessed as both an \tcode{_Atomic(T)}
from C code and an \tcode{atomic<T>} from \Cpp{} code.
The representations should be the same, and
the mechanisms used to ensure atomicity and memory ordering
should be compatible.

\rSec1[thread.mutex]{Mutual exclusion}

\rSec2[thread.mutex.general]{General}

\pnum
Subclause \ref{thread.mutex} provides mechanisms for mutual exclusion: mutexes, locks, and call
once. These mechanisms ease the production of race-free
programs\iref{intro.multithread}.

\rSec2[mutex.syn]{Header \tcode{<mutex>} synopsis}

\indexheader{mutex}%
\begin{codeblock}
namespace std {
  // \ref{thread.mutex.class}, class \tcode{mutex}
  class mutex;
  // \ref{thread.mutex.recursive}, class \tcode{recursive_mutex}
  class recursive_mutex;
  // \ref{thread.timedmutex.class}, class \tcode{timed_mutex}
  class timed_mutex;
  // \ref{thread.timedmutex.recursive}, class \tcode{recursive_timed_mutex}
  class recursive_timed_mutex;

  struct defer_lock_t { explicit defer_lock_t() = default; };
  struct try_to_lock_t { explicit try_to_lock_t() = default; };
  struct adopt_lock_t { explicit adopt_lock_t() = default; };

  inline constexpr defer_lock_t  defer_lock { };
  inline constexpr try_to_lock_t try_to_lock { };
  inline constexpr adopt_lock_t  adopt_lock { };

  // \ref{thread.lock}, locks
  template<class Mutex> class lock_guard;
  template<class... MutexTypes> class scoped_lock;
  template<class Mutex> class unique_lock;

  template<class Mutex>
    void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;

  // \ref{thread.lock.algorithm}, generic locking algorithms
  template<class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);
  template<class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);

  struct once_flag;

  template<class Callable, class... Args>
    void call_once(once_flag& flag, Callable&& func, Args&&... args);
}
\end{codeblock}

\rSec2[shared.mutex.syn]{Header \tcode{<shared_mutex>} synopsis}

\indexheader{shared_mutex}%
\begin{codeblock}
namespace std {
  // \ref{thread.sharedmutex.class}, class \tcode{shared_mutex}
  class shared_mutex;
  // \ref{thread.sharedtimedmutex.class}, class \tcode{shared_timed_mutex}
  class shared_timed_mutex;
  // \ref{thread.lock.shared}, class template \tcode{shared_lock}
  template<class Mutex> class shared_lock;
  template<class Mutex>
    void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
}
\end{codeblock}

\rSec2[thread.mutex.requirements]{Mutex requirements}

\rSec3[thread.mutex.requirements.general]{General}

\pnum
A mutex object facilitates protection against data races and allows safe synchronization of
data between execution agents\iref{thread.req.lockable}.
An execution agent \term{owns} a mutex from the time it successfully calls one of the
lock functions until it calls unlock. Mutexes can be either recursive or non-recursive, and can
grant simultaneous ownership to one or many execution agents. Both
recursive and non-recursive mutexes are supplied.

\rSec3[thread.mutex.requirements.mutex]{Mutex types}

\rSec4[thread.mutex.requirements.mutex.general]{General}

\pnum
The \defn{mutex types} are the standard library types \tcode{mutex},
\tcode{recursive_mutex}, \tcode{timed_mutex}, \tcode{recursive_timed_mutex},
\tcode{shared_mutex}, and \tcode{shared_timed_mutex}.
They meet the requirements set out in \ref{thread.mutex.requirements.mutex}.
In this description, \tcode{m} denotes an object of a mutex type.
\begin{note}
The mutex types meet the \oldconcept{Lockable} requirements\iref{thread.req.lockable.req}.
\end{note}

\pnum
The mutex types meet \oldconcept{DefaultConstructible} and \oldconcept{Destructible}.
If initialization of an object of a mutex type fails,
an exception of type \tcode{system_error} is thrown.
The mutex types are neither copyable nor movable.

\pnum
The error conditions for error codes, if any, reported by member functions of the mutex types
are as follows:
\begin{itemize}
\item \tcode{resource_unavailable_try_again} --- if any native handle type manipulated is not available.
\item \tcode{operation_not_permitted} --- if the thread does not have the
privilege to perform the operation.
\item \tcode{invalid_argument} --- if any native handle type manipulated as part of mutex
construction is incorrect.
\end{itemize}

\pnum
The implementation provides lock and unlock operations, as described below.
For purposes of determining the existence of a data race, these behave as
atomic operations\iref{intro.multithread}. The lock and unlock operations on
a single mutex appear to occur in a single total order.
\begin{note}
This
can be viewed as the modification order\iref{intro.multithread} of the
mutex.
\end{note}
\begin{note}
Construction and
destruction of an object of a mutex type need not be thread-safe; other
synchronization can be used to ensure that mutex objects are initialized
and visible to other threads.
\end{note}

\pnum
The expression \tcode{m.lock()} is well-formed and has the following semantics:

\begin{itemdescr}
\pnum
\expects
If \tcode{m} is of type \tcode{mutex}, \tcode{timed_mutex},
\tcode{shared_mutex}, or \tcode{shared_timed_mutex}, the calling
thread does not own the mutex.

\pnum
\indextext{block (execution)}%
\effects
Blocks the calling thread until ownership of the mutex can be obtained for the calling thread.

\pnum
\sync
Prior \tcode{unlock()} operations on the same object
\term{synchronize with}\iref{intro.multithread} this operation.

\pnum
\ensures
The calling thread owns the mutex.

\pnum
\returntype \keyword{void}.

\pnum
\throws
\tcode{system_error} when
an exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{operation_not_permitted} --- if the thread does not have the
privilege to perform the operation.

\item \tcode{resource_deadlock_would_occur} --- if the implementation detects
that a deadlock would occur.
\end{itemize}
\end{itemdescr}

\pnum
The expression \tcode{m.try_lock()} is well-formed and has the following semantics:

\begin{itemdescr}
\pnum
\expects
If \tcode{m} is of type \tcode{mutex}, \tcode{timed_mutex},
\tcode{shared_mutex}, or \tcode{shared_timed_mutex}, the calling
thread does not own the mutex.

\pnum
\effects
Attempts to obtain ownership of the mutex for the calling thread without
blocking. If ownership is not obtained, there is no effect and \tcode{try_lock()}
immediately returns. An implementation may fail to obtain the lock even if it is not
held by any other thread.
\begin{note}
This spurious failure is normally uncommon, but
allows interesting implementations based on a simple
compare and exchange\iref{atomics}.
\end{note}
An implementation should ensure that \tcode{try_lock()} does not consistently return \tcode{false}
in the absence of contending mutex acquisitions.

\pnum
\sync
If \tcode{try_lock()} returns \tcode{true}, prior \tcode{unlock()} operations
on the same object \term{synchronize with}\iref{intro.multithread} this operation.
\begin{note}
Since \tcode{lock()} does not synchronize with a failed subsequent
\tcode{try_lock()}, the visibility rules are weak enough that little would be
known about the state after a failure, even in the absence of spurious failures.
\end{note}

\pnum
\returntype \tcode{bool}.

\pnum
\returns
\tcode{true} if ownership was obtained, otherwise \tcode{false}.

\pnum
\throws
Nothing.
\end{itemdescr}

\pnum
The expression \tcode{m.unlock()} is well-formed and has the following semantics:

\begin{itemdescr}
\pnum
\expects
The calling thread owns the mutex.

\pnum
\effects
Releases the calling thread's ownership of the mutex.

\pnum
\returntype \keyword{void}.

\pnum
\sync
This operation synchronizes with\iref{intro.multithread} subsequent
lock operations that obtain ownership on the same object.

\pnum
\throws
Nothing.
\end{itemdescr}

\rSec4[thread.mutex.class]{Class \tcode{mutex}}

\indexlibraryglobal{mutex}%
\begin{codeblock}
namespace std {
  class mutex {
  public:
    constexpr mutex() noexcept;
    ~mutex();

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

    void lock();
    bool try_lock();
    void unlock();

    using native_handle_type = @\impdefnc@;          // see~\ref{thread.req.native}
    native_handle_type native_handle();                         // see~\ref{thread.req.native}
  };
}
\end{codeblock}

\pnum
\indextext{block (execution)}%
The class \tcode{mutex} provides a non-recursive mutex with exclusive ownership
semantics. If one thread owns a mutex object, attempts by another thread to acquire
ownership of that object will fail (for \tcode{try_lock()}) or block (for
\tcode{lock()}) until the owning thread has released ownership with a call to
\tcode{unlock()}.

\pnum
\begin{note}
After a thread \tcode{A} has called \tcode{unlock()}, releasing a mutex, it is possible for another
thread \tcode{B} to lock the same mutex, observe that it is no longer in use, unlock it, and
destroy it, before thread \tcode{A} appears to have returned from its unlock call. Conforming implementations
handle such scenarios correctly, as long as thread \tcode{A} does not access the
mutex after the unlock call returns. These cases typically occur when a reference-counted object
contains a mutex that is used to protect the reference count.
\end{note}

\pnum
The class \tcode{mutex} meets
all of the mutex requirements\iref{thread.mutex.requirements}.
It is a standard-layout class\iref{class.prop}.

\pnum
\begin{note}
A program can deadlock if the thread that owns a \tcode{mutex} object calls
\tcode{lock()} on that object. If the implementation can detect the deadlock,
a \tcode{resource_deadlock_would_occur} error condition might be observed.
\end{note}

\pnum
The behavior of a program is undefined if
it destroys a \tcode{mutex} object owned by any thread or
a thread terminates while owning a \tcode{mutex} object.

\rSec4[thread.mutex.recursive]{Class \tcode{recursive_mutex}}

\indexlibraryglobal{recursive_mutex}%
\begin{codeblock}
namespace std {
  class recursive_mutex {
  public:
    recursive_mutex();
    ~recursive_mutex();

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

    void lock();
    bool try_lock() noexcept;
    void unlock();

    using native_handle_type = @\impdefnc@;          // see~\ref{thread.req.native}
    native_handle_type native_handle();                         // see~\ref{thread.req.native}
  };
}
\end{codeblock}

\pnum
\indextext{block (execution)}%
The class \tcode{recursive_mutex} provides a recursive mutex with exclusive ownership
semantics. If one thread owns a \tcode{recursive_mutex} object, attempts by another
thread to acquire ownership of that object will fail (for \tcode{try_lock()}) or block
(for \tcode{lock()}) until the first thread has completely released ownership.

\pnum
The class \tcode{recursive_mutex} meets
all of the mutex requirements\iref{thread.mutex.requirements}.
It is a standard-layout class\iref{class.prop}.

\pnum
A thread that owns a \tcode{recursive_mutex} object may acquire additional levels of
ownership by calling \tcode{lock()} or \tcode{try_lock()} on that object. It is
unspecified how many levels of ownership may be acquired by a single thread. If a thread
has already acquired the maximum level of ownership for a \tcode{recursive_mutex}
object, additional calls to \tcode{try_lock()} fail, and additional calls to
\tcode{lock()} throw an exception of type \tcode{system_error}. A thread
shall call \tcode{unlock()} once for each level of ownership acquired by calls to
\tcode{lock()} and \tcode{try_lock()}. Only when all levels of ownership have been
released may ownership be acquired by another thread.

\pnum
The behavior of a program is undefined if
\begin{itemize}
\item it destroys a \tcode{recursive_mutex} object owned by any thread or
\item a thread terminates while owning a \tcode{recursive_mutex} object.
\end{itemize}

\rSec3[thread.timedmutex.requirements]{Timed mutex types}

\rSec4[thread.timedmutex.requirements.general]{General}

\pnum
The \defn{timed mutex types} are the standard library types \tcode{timed_mutex},
\tcode{recursive_timed_mutex}, and \tcode{shared_timed_mutex}. They
meet the requirements set out below.
In this description, \tcode{m} denotes an object of a mutex type,
\tcode{rel_time} denotes an object of a
specialization of \tcode{duration}\iref{time.duration}, and \tcode{abs_time} denotes an
object of a
specialization of \tcode{time_point}\iref{time.point}.
\begin{note}
The timed mutex types meet the \oldconcept{TimedLockable}
requirements\iref{thread.req.lockable.timed}.
\end{note}

\pnum
The expression \tcode{m.try_lock_for(rel_time)} is well-formed
and has the following semantics:

\begin{itemdescr}
\pnum
\expects
If \tcode{m} is of type \tcode{timed_mutex} or
\tcode{shared_timed_mutex}, the calling thread does not
own the mutex.

\pnum
\effects
The function attempts to obtain ownership of the mutex within the
relative timeout\iref{thread.req.timing}
specified by \tcode{rel_time}. If the time specified by \tcode{rel_time} is less than or
equal to \tcode{rel_time.zero()}, the function attempts to obtain ownership without blocking (as if by calling
\tcode{try_lock()}). The function returns within the timeout specified by
\tcode{rel_time} only if it has obtained ownership of the mutex object.
\begin{note}
As
with \tcode{try_lock()}, there is no guarantee that ownership will be obtained if the
lock is available, but implementations are expected to make a strong effort to do so.
\end{note}

\pnum
\sync
If \tcode{try_lock_for()} returns \tcode{true}, prior \tcode{unlock()} operations
on the same object \term{synchronize with}\iref{intro.multithread} this operation.

\pnum
\returntype \tcode{bool}.

\pnum
\returns
\tcode{true} if ownership was obtained, otherwise \tcode{false}.

\pnum
\throws
Timeout-related exceptions\iref{thread.req.timing}.
\end{itemdescr}

\pnum
The expression \tcode{m.try_lock_until(abs_time)} is well-formed
and has the following semantics:

\begin{itemdescr}
\pnum
\expects
If \tcode{m} is of type \tcode{timed_mutex} or
\tcode{shared_timed_mutex}, the calling thread does not own the
mutex.

\pnum
\effects
The function attempts to obtain ownership of the mutex. If
\tcode{abs_time} has already passed, the function attempts to obtain ownership
without blocking (as if by calling \tcode{try_lock()}). The function
returns before the absolute timeout\iref{thread.req.timing} specified by
\tcode{abs_time} only if it has obtained ownership of the mutex object.
\begin{note}
As with \tcode{try_lock()}, there is no guarantee that ownership will
be obtained if the lock is available, but implementations are expected to make a
strong effort to do so.
\end{note}

\pnum
\sync
If \tcode{try_lock_until()} returns \tcode{true}, prior \tcode{unlock()}
operations on the same object \term{synchronize with}\iref{intro.multithread}
this operation.

\pnum
\returntype \tcode{bool}.

\pnum
\returns
\tcode{true} if ownership was obtained, otherwise \tcode{false}.

\pnum
\throws
Timeout-related exceptions\iref{thread.req.timing}.
\end{itemdescr}

\rSec4[thread.timedmutex.class]{Class \tcode{timed_mutex}}

\indexlibraryglobal{timed_mutex}%
\begin{codeblock}
namespace std {
  class timed_mutex {
  public:
    timed_mutex();
    ~timed_mutex();

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

    void lock();    // blocking
    bool try_lock();
    template<class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
    template<class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
    void unlock();

    using native_handle_type = @\impdefnc@;          // see~\ref{thread.req.native}
    native_handle_type native_handle();                         // see~\ref{thread.req.native}
  };
}
\end{codeblock}

\pnum
\indextext{block (execution)}%
The class \tcode{timed_mutex} provides a non-recursive mutex with exclusive ownership
semantics. If one thread owns a \tcode{timed_mutex} object, attempts by another thread
to acquire ownership of that object will fail (for \tcode{try_lock()}) or block
(for \tcode{lock()}, \tcode{try_lock_for()}, and \tcode{try_lock_until()}) until
the owning thread has released ownership with a call to \tcode{unlock()} or the
call to \tcode{try_lock_for()} or \tcode{try_lock_until()} times out (having
failed to obtain ownership).

\pnum
The class \tcode{timed_mutex} meets
all of the timed mutex requirements\iref{thread.timedmutex.requirements}.
It is a standard-layout class\iref{class.prop}.

\pnum
The behavior of a program is undefined if
\begin{itemize}
\item it destroys a \tcode{timed_mutex} object owned by any thread,
\item a thread that owns a \tcode{timed_mutex} object calls \tcode{lock()},
\tcode{try_lock()}, \tcode{try_lock_for()}, or \tcode{try_lock_until()} on that object, or
\item a thread terminates while owning a \tcode{timed_mutex} object.
\end{itemize}

\rSec4[thread.timedmutex.recursive]{Class \tcode{recursive_timed_mutex}}

\indexlibraryglobal{recursive_timed_mutex}%
\begin{codeblock}
namespace std {
  class recursive_timed_mutex {
  public:
    recursive_timed_mutex();
    ~recursive_timed_mutex();

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

    void lock();    // blocking
    bool try_lock() noexcept;
    template<class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
    template<class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
    void unlock();

    using native_handle_type = @\impdefnc@;          // see~\ref{thread.req.native}
    native_handle_type native_handle();                         // see~\ref{thread.req.native}
  };
}
\end{codeblock}

\pnum
\indextext{block (execution)}%
The class \tcode{recursive_timed_mutex} provides a recursive mutex with exclusive
ownership semantics. If one thread owns a \tcode{recursive_timed_mutex} object,
attempts by another thread to acquire ownership of that object will fail (for
\tcode{try_lock()}) or block (for \tcode{lock()}, \tcode{try_lock_for()}, and
\tcode{try_lock_until()}) until the owning thread has completely released
ownership or the call to \tcode{try_lock_for()} or \tcode{try_lock_until()}
times out (having failed to obtain ownership).

\pnum
The class \tcode{recursive_timed_mutex} meets
all of the timed mutex requirements\iref{thread.timedmutex.requirements}.
It is a standard-layout class\iref{class.prop}.

\pnum
A thread that owns a \tcode{recursive_timed_mutex} object may acquire additional
levels of ownership by calling \tcode{lock()}, \tcode{try_lock()},
\tcode{try_lock_for()}, or \tcode{try_lock_until()} on that object. It is
unspecified how many levels of ownership may be acquired by a single thread. If
a thread has already acquired the maximum level of ownership for a
\tcode{recursive_timed_mutex} object, additional calls to \tcode{try_lock()},
\tcode{try_lock_for()}, or \tcode{try_lock_until()} fail, and additional
calls to \tcode{lock()} throw an exception of type \tcode{system_error}. A
thread shall call \tcode{unlock()} once for each level of ownership acquired by
calls to \tcode{lock()}, \tcode{try_lock()}, \tcode{try_lock_for()}, and
\tcode{try_lock_until()}. Only when all levels of ownership have been released
may ownership of the object be acquired by another thread.

\pnum
The behavior of a program is undefined if
\begin{itemize}
\item it destroys a \tcode{recursive_timed_mutex} object owned by any thread, or
\item a thread terminates while owning a \tcode{recursive_timed_mutex} object.
\end{itemize}


\rSec3[thread.sharedmutex.requirements]{Shared mutex types}

\rSec4[thread.sharedmutex.requirements.general]{General}

\pnum
The standard library types \tcode{shared_mutex} and \tcode{shared_timed_mutex}
are \defn{shared mutex types}. Shared mutex types meet the requirements of
mutex types\iref{thread.mutex.requirements.mutex} and additionally
meet the requirements set out below. In this description,
\tcode{m} denotes an object of a shared mutex type.
\begin{note}
The shared mutex types meet the \oldconcept{SharedLockable}
requirements\iref{thread.req.lockable.shared}.
\end{note}

\pnum
\indextext{block (execution)}%
In addition to the exclusive lock ownership mode specified
in~\ref{thread.mutex.requirements.mutex}, shared mutex types provide a
\defn{shared lock} ownership mode. Multiple execution agents can
simultaneously hold a shared lock ownership of a shared mutex type. But no
execution agent holds a shared lock while another execution agent holds an
exclusive lock on the same shared mutex type, and vice-versa. The maximum
number of execution agents which can share a shared lock on a single shared
mutex type is unspecified, but is at least 10000. If more than the
maximum number of execution agents attempt to obtain a shared lock, the
excess execution agents block until the number of shared locks are
reduced below the maximum amount by other execution agents releasing their
shared lock.

\pnum
The expression \tcode{m.lock_shared()} is well-formed and has the
following semantics:

\begin{itemdescr}
\pnum
\expects
The calling thread has no ownership of the mutex.

\pnum
\indextext{block (execution)}%
\effects
Blocks the calling thread until shared ownership of the mutex can be obtained for the calling thread.
If an exception is thrown then a shared lock has not been acquired for the current thread.

\pnum
\sync
Prior \tcode{unlock()} operations on the same object synchronize with\iref{intro.multithread} this operation.

\pnum
\ensures
The calling thread has a shared lock on the mutex.

\pnum
\returntype \keyword{void}.

\pnum
\throws
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{operation_not_permitted} --- if the thread does not have the privilege to perform the operation.
\item \tcode{resource_deadlock_would_occur} --- if the implementation detects that a deadlock would occur.
\end{itemize}
\end{itemdescr}

\pnum
The expression \tcode{m.unlock_shared()} is well-formed and has the following semantics:

\begin{itemdescr}
\pnum
\expects
The calling thread holds a shared lock on the mutex.

\pnum
\effects
Releases a shared lock on the mutex held by the calling thread.

\pnum
\returntype \keyword{void}.

\pnum
\sync
This operation synchronizes with\iref{intro.multithread} subsequent
\tcode{lock()} operations that obtain ownership on the same object.

\pnum
\throws
Nothing.
\end{itemdescr}

\pnum
The expression \tcode{m.try_lock_shared()} is well-formed and has the following semantics:

\begin{itemdescr}
\pnum
\expects
The calling thread has no ownership of the mutex.

\pnum
\effects
Attempts to obtain shared ownership of the mutex for the calling
thread without blocking. If shared ownership is not obtained, there is no
effect and \tcode{try_lock_shared()} immediately returns. An implementation
may fail to obtain the lock even if it is not held by any other thread.

\pnum
\sync
If \tcode{try_lock_shared()} returns \tcode{true}, prior \tcode{unlock()}
operations on the same object synchronize with\iref{intro.multithread} this
operation.

\pnum
\returntype \tcode{bool}.

\pnum
\returns
\tcode{true} if the shared lock was acquired, otherwise \tcode{false}.

\pnum
\throws
Nothing.
\end{itemdescr}

\rSec4[thread.sharedmutex.class]{Class \tcode{shared_mutex}}

\indexlibraryglobal{shared_mutex}%
\begin{codeblock}
namespace std {
  class shared_mutex {
  public:
    shared_mutex();
    ~shared_mutex();

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

    // exclusive ownership
    void lock();                // blocking
    bool try_lock();
    void unlock();

    // shared ownership
    void lock_shared();         // blocking
    bool try_lock_shared();
    void unlock_shared();

    using native_handle_type = @\impdefnc@;          // see~\ref{thread.req.native}
    native_handle_type native_handle();                         // see~\ref{thread.req.native}
  };
}
\end{codeblock}

\pnum
The class \tcode{shared_mutex} provides a non-recursive mutex
with shared ownership semantics.

\pnum
The class \tcode{shared_mutex} meets
all of the shared mutex requirements\iref{thread.sharedmutex.requirements}.
It is a standard-layout class\iref{class.prop}.

\pnum
The behavior of a program is undefined if
\begin{itemize}
\item it destroys a \tcode{shared_mutex} object owned by any thread,
\item a thread attempts to recursively gain any ownership of a \tcode{shared_mutex}, or
\item a thread terminates while possessing any ownership of a \tcode{shared_mutex}.
\end{itemize}

\pnum
\tcode{shared_mutex} may be a synonym for \tcode{shared_timed_mutex}.

\rSec3[thread.sharedtimedmutex.requirements]{Shared timed mutex types}

\rSec4[thread.sharedtimedmutex.requirements.general]{General}

\pnum
The standard library type \tcode{shared_timed_mutex} is a
\defn{shared timed mutex type}. Shared timed mutex types meet the requirements of
timed mutex types\iref{thread.timedmutex.requirements},
shared mutex types\iref{thread.sharedmutex.requirements}, and additionally
meet the requirements set out below. In this description,
\tcode{m} denotes an object of a shared timed mutex type,
\tcode{rel_time} denotes an object of a specialization of
\tcode{duration}\iref{time.duration}, and
\tcode{abs_time} denotes an object of a specialization of
\tcode{time_point}\iref{time.point}.
\begin{note}
The shared timed mutex types meet the \oldconcept{SharedTimedLockable}
requirements\iref{thread.req.lockable.shared.timed}.
\end{note}

\pnum
The expression \tcode{m.try_lock_shared_for(rel_time)} is well-formed and
has the following semantics:

\begin{itemdescr}
\pnum
\expects
The calling thread has no ownership of the mutex.

\pnum
\effects
Attempts to obtain
shared lock ownership for the calling thread within the relative
timeout\iref{thread.req.timing} specified by \tcode{rel_time}. If the time
specified by \tcode{rel_time} is less than or equal to \tcode{rel_time.zero()},
the function attempts to obtain ownership without blocking (as if by calling
\tcode{try_lock_shared()}). The function returns within the timeout
specified by \tcode{rel_time} only if it has obtained shared ownership of the
mutex object.
\begin{note}
As with \tcode{try_lock()}, there is no guarantee that
ownership will be obtained if the lock is available, but implementations are
expected to make a strong effort to do so.
\end{note}
If an exception is thrown then a shared lock has not been acquired for
the current thread.

\pnum
\sync
If \tcode{try_lock_shared_for()} returns \tcode{true}, prior
\tcode{unlock()} operations on the same object synchronize
with\iref{intro.multithread} this operation.

\pnum
\returntype \tcode{bool}.

\pnum
\returns
\tcode{true} if the shared lock was acquired, otherwise \tcode{false}.

\pnum
\throws
Timeout-related exceptions\iref{thread.req.timing}.
\end{itemdescr}

\pnum
The expression \tcode{m.try_lock_shared_until(abs_time)} is well-formed
and has the following semantics:

\begin{itemdescr}
\pnum
\expects
The calling thread has no ownership of the mutex.

\pnum
\effects
The function attempts to obtain shared ownership of the mutex. If
\tcode{abs_time} has already passed, the function attempts to obtain shared
ownership without blocking (as if by calling \tcode{try_lock_shared()}). The
function returns before the absolute timeout\iref{thread.req.timing}
specified by \tcode{abs_time} only if it has obtained shared ownership of the
mutex object.
\begin{note}
As with \tcode{try_lock()}, there is no guarantee that
ownership will be obtained if the lock is available, but implementations are
expected to make a strong effort to do so.
\end{note}
If an exception is thrown then a shared lock has not been acquired for
the current thread.

\pnum
\sync
If \tcode{try_lock_shared_until()} returns \tcode{true}, prior
\tcode{unlock()} operations on the same object synchronize
with\iref{intro.multithread} this operation.

\pnum
\returntype \tcode{bool}.

\pnum
\returns
\tcode{true} if the shared lock was acquired, otherwise \tcode{false}.

\pnum
\throws
Timeout-related exceptions\iref{thread.req.timing}.
\end{itemdescr}

\rSec4[thread.sharedtimedmutex.class]{Class \tcode{shared_timed_mutex}}

\indexlibraryglobal{shared_timed_mutex}%
\begin{codeblock}
namespace std {
  class shared_timed_mutex {
  public:
    shared_timed_mutex();
    ~shared_timed_mutex();

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

    // exclusive ownership
    void lock();                // blocking
    bool try_lock();
    template<class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
    template<class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
    void unlock();

    // shared ownership
    void lock_shared();         // blocking
    bool try_lock_shared();
    template<class Rep, class Period>
      bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);
    template<class Clock, class Duration>
      bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);
    void unlock_shared();
  };
}
\end{codeblock}

\pnum
The class \tcode{shared_timed_mutex} provides a non-recursive mutex with shared
ownership semantics.

\pnum
The class \tcode{shared_timed_mutex} meets
all of the shared timed mutex requirements\iref{thread.sharedtimedmutex.requirements}.
It is a standard-layout class\iref{class.prop}.

\pnum
The behavior of a program is undefined if
\begin{itemize}
\item it destroys a \tcode{shared_timed_mutex} object owned by any thread,
\item a thread attempts to recursively gain any ownership of a \tcode{shared_timed_mutex}, or
\item a thread terminates while possessing any ownership of a \tcode{shared_timed_mutex}.
\end{itemize}

\rSec2[thread.lock]{Locks}

\rSec3[thread.lock.general]{General}

\pnum
A \term{lock} is an object that holds a reference to a lockable object and may unlock the
lockable object during the lock's destruction (such as when leaving block scope). An execution
agent may use a lock to aid in managing ownership of a lockable object in an exception safe
manner. A lock is said to \term{own} a lockable object if it is currently managing the
ownership of that lockable object for an execution agent. A lock does not manage the lifetime
of the lockable object it references.
\begin{note}
Locks are intended to ease the burden of
unlocking the lockable object under both normal and exceptional circumstances.
\end{note}

\pnum
Some lock constructors take tag types which describe what should be done with the lockable
object during the lock's construction.

\indexlibraryglobal{defer_lock_t}%
\indexlibraryglobal{try_to_lock_t}%
\indexlibraryglobal{adopt_lock_t}%
\indexlibraryglobal{defer_lock}%
\indexlibraryglobal{try_to_lock}%
\indexlibraryglobal{adopt_lock}%
\begin{codeblock}
namespace std {
  struct defer_lock_t  { };     // do not acquire ownership of the mutex
  struct try_to_lock_t { };     // try to acquire ownership of the mutex
                                // without blocking
  struct adopt_lock_t  { };     // assume the calling thread has already
                                // obtained mutex ownership and manage it

  inline constexpr defer_lock_t  defer_lock { };
  inline constexpr try_to_lock_t try_to_lock { };
  inline constexpr adopt_lock_t  adopt_lock { };
}
\end{codeblock}

\rSec3[thread.lock.guard]{Class template \tcode{lock_guard}}

\indexlibraryglobal{lock_guard}%
\begin{codeblock}
namespace std {
  template<class Mutex>
  class lock_guard {
  public:
    using mutex_type = Mutex;

    explicit lock_guard(mutex_type& m);
    lock_guard(mutex_type& m, adopt_lock_t);
    ~lock_guard();

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

  private:
    mutex_type& pm;             // \expos
  };
}
\end{codeblock}

\pnum
An object of type \tcode{lock_guard} controls the ownership of a lockable object
within a scope. A \tcode{lock_guard} object maintains ownership of a lockable
object throughout the \tcode{lock_guard} object's lifetime\iref{basic.life}.
The behavior of a program is undefined if the lockable object referenced by
\tcode{pm} does not exist for the entire lifetime of the \tcode{lock_guard}
object. The supplied \tcode{Mutex} type shall meet the \oldconcept{BasicLockable}
requirements\iref{thread.req.lockable.basic}.

\indexlibraryctor{lock_guard}%
\begin{itemdecl}
explicit lock_guard(mutex_type& m);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{pm} with \tcode{m}. Calls \tcode{m.lock()}.
\end{itemdescr}

\indexlibraryctor{lock_guard}%
\begin{itemdecl}
lock_guard(mutex_type& m, adopt_lock_t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The calling thread holds a non-shared lock on \tcode{m}.

\pnum
\effects
Initializes \tcode{pm} with \tcode{m}.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibrarydtor{lock_guard}%
\begin{itemdecl}
~lock_guard();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{pm.unlock()}
\end{itemdescr}

\rSec3[thread.lock.scoped]{Class template \tcode{scoped_lock}}

\indexlibraryglobal{scoped_lock}%
\begin{codeblock}
namespace std {
  template<class... MutexTypes>
  class scoped_lock {
  public:
    using mutex_type = @\seebelow@;     // Only if \tcode{sizeof...(MutexTypes) == 1} is \tcode{true}

    explicit scoped_lock(MutexTypes&... m);
    explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
    ~scoped_lock();

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

  private:
    tuple<MutexTypes&...> pm;   // \expos
  };
}
\end{codeblock}

\pnum
An object of type \tcode{scoped_lock} controls the ownership of lockable objects
within a scope. A \tcode{scoped_lock} object maintains ownership of lockable
objects throughout the \tcode{scoped_lock} object's lifetime\iref{basic.life}.
The behavior of a program is undefined if the lockable objects referenced by
\tcode{pm} do not exist for the entire lifetime of the \tcode{scoped_lock}
object.
\begin{itemize}
\item
If \tcode{sizeof...(MutexTypes)} is one,
let \tcode{Mutex} denote the sole type constituting the pack \tcode{MutexTypes}.
\tcode{Mutex}
shall meet the \oldconcept{BasicLockable} requirements\iref{thread.req.lockable.basic}.
The member \grammarterm{typedef-name} \tcode{mutex_type}
denotes the same type as \tcode{Mutex}.
\item
Otherwise, all types in the template parameter pack \tcode{MutexTypes}
shall meet the \oldconcept{Lockable} requirements\iref{thread.req.lockable.req}
and there is no member \tcode{mutex_type}.
\end{itemize}

\indexlibraryctor{scoped_lock}%
\begin{itemdecl}
explicit scoped_lock(MutexTypes&... m);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{pm} with \tcode{tie(m...)}.
Then if \tcode{sizeof...(MutexTypes)} is \tcode{0}, no effects.
Otherwise if \tcode{sizeof...(MutexTypes)} is \tcode{1}, then \tcode{m.lock()}.
Otherwise, \tcode{lock(m...)}.
\end{itemdescr}

\indexlibraryctor{scoped_lock}%
\begin{itemdecl}
explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The calling thread holds a non-shared lock on each element of \tcode{m}.

\pnum
\effects
Initializes \tcode{pm} with \tcode{tie(m...)}.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibrarydtor{scoped_lock}%
\begin{itemdecl}
~scoped_lock();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
For all \tcode{i} in \range{0}{sizeof...(MutexTypes)},
\tcode{get<i>(pm).unlock()}.
\end{itemdescr}

\rSec3[thread.lock.unique]{Class template \tcode{unique_lock}}

\rSec4[thread.lock.unique.general]{General}

\indexlibraryglobal{unique_lock}%
\begin{codeblock}
namespace std {
  template<class Mutex>
  class unique_lock {
  public:
    using mutex_type = Mutex;

    // \ref{thread.lock.unique.cons}, construct/copy/destroy
    unique_lock() noexcept;
    explicit unique_lock(mutex_type& m);
    unique_lock(mutex_type& m, defer_lock_t) noexcept;
    unique_lock(mutex_type& m, try_to_lock_t);
    unique_lock(mutex_type& m, adopt_lock_t);
    template<class Clock, class Duration>
      unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
    template<class Rep, class Period>
      unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
    ~unique_lock();

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

    unique_lock(unique_lock&& u) noexcept;
    unique_lock& operator=(unique_lock&& u) noexcept;

    // \ref{thread.lock.unique.locking}, locking
    void lock();
    bool try_lock();

    template<class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
    template<class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);

    void unlock();

    // \ref{thread.lock.unique.mod}, modifiers
    void swap(unique_lock& u) noexcept;
    mutex_type* release() noexcept;

    // \ref{thread.lock.unique.obs}, observers
    bool owns_lock() const noexcept;
    explicit operator bool() const noexcept;
    mutex_type* mutex() const noexcept;

  private:
    mutex_type* pm;             // \expos
    bool owns;                  // \expos
  };
}
\end{codeblock}

\pnum
An object of type \tcode{unique_lock} controls the ownership of a lockable
object within a scope. Ownership of the lockable object may be acquired at
construction or after construction, and may be transferred, after
acquisition, to another \tcode{unique_lock} object. Objects of type \tcode{unique_lock} are not
copyable but are movable. The behavior of a program is undefined if the contained pointer
\tcode{pm} is not null and the lockable object pointed
to by \tcode{pm} does not exist for the entire remaining
lifetime\iref{basic.life} of the \tcode{unique_lock} object. The supplied
\tcode{Mutex} type shall meet the \oldconcept{BasicLockable}
requirements\iref{thread.req.lockable.basic}.

\pnum
\begin{note}
\tcode{unique_lock<Mutex>} meets the \oldconcept{BasicLockable} requirements. If \tcode{Mutex}
meets the \oldconcept{Lockable} requirements\iref{thread.req.lockable.req},
\tcode{unique_lock<Mutex>} also meets the \oldconcept{Lockable} requirements;
if \tcode{Mutex}
meets the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed},
\tcode{unique_lock<Mutex>} also meets the \oldconcept{TimedLockable} requirements.
\end{note}

\rSec4[thread.lock.unique.cons]{Constructors, destructor, and assignment}

\indexlibraryctor{unique_lock}%
\begin{itemdecl}
unique_lock() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{pm == nullptr} and \tcode{owns == false}.
\end{itemdescr}

\indexlibraryctor{unique_lock}%
\begin{itemdecl}
explicit unique_lock(mutex_type& m);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Calls \tcode{m.lock()}.

\pnum
\ensures
\tcode{pm == addressof(m)} and \tcode{owns == true}.
\end{itemdescr}

\indexlibraryctor{unique_lock}%
\begin{itemdecl}
unique_lock(mutex_type& m, defer_lock_t) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{pm == addressof(m)} and \tcode{owns == false}.
\end{itemdescr}

\indexlibraryctor{unique_lock}%
\begin{itemdecl}
unique_lock(mutex_type& m, try_to_lock_t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The supplied \tcode{Mutex} type meets the \oldconcept{Lockable}
requirements\iref{thread.req.lockable.req}.

\pnum
\effects
Calls \tcode{m.try_lock()}.

\pnum
\ensures
\tcode{pm == addressof(m)} and \tcode{owns == res},
where \tcode{res} is the value returned by the call to \tcode{m.try_lock()}.
\end{itemdescr}

\indexlibraryctor{unique_lock}%
\begin{itemdecl}
unique_lock(mutex_type& m, adopt_lock_t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The calling thread holds a non-shared lock on \tcode{m}.

\pnum
\ensures
\tcode{pm == addressof(m)} and \tcode{owns == true}.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibraryctor{unique_lock}%
\begin{itemdecl}
template<class Clock, class Duration>
  unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The supplied \tcode{Mutex} type meets the
\oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}.

\pnum
\effects
Calls \tcode{m.try_lock_until(abs_time)}.

\pnum
\ensures
\tcode{pm == addressof(m)} and \tcode{owns == res},
where \tcode{res} is
the value returned by the call to \tcode{m.try_lock_until(abs_time)}.
\end{itemdescr}

\indexlibraryctor{unique_lock}%
\begin{itemdecl}
template<class Rep, class Period>
  unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The supplied \tcode{Mutex} type meets the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}.

\pnum
\effects
Calls \tcode{m.try_lock_for(rel_time)}.

\pnum
\ensures
\tcode{pm == addressof(m)} and \tcode{owns == res},
where \tcode{res} is the value returned by the call to \tcode{m.try_lock_for(rel_time)}.
\end{itemdescr}

\indexlibraryctor{unique_lock}%
\begin{itemdecl}
unique_lock(unique_lock&& u) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{pm == u_p.pm} and \tcode{owns == u_p.owns} (where \tcode{u_p} is the state of \tcode{u} just prior to this construction),  \tcode{u.pm == 0} and \tcode{u.owns == false}.
\end{itemdescr}

\indexlibrarymember{operator=}{unique_lock}%
\begin{itemdecl}
unique_lock& operator=(unique_lock&& u) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{unique_lock(std::move(u)).swap(*this)}

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarydtor{unique_lock}%
\begin{itemdecl}
~unique_lock();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{owns} calls \tcode{pm->unlock()}.
\end{itemdescr}

\rSec4[thread.lock.unique.locking]{Locking}

\indexlibrarymember{lock}{unique_lock}%
\begin{itemdecl}
void lock();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
As if by \tcode{pm->lock()}.

\pnum
\ensures
\tcode{owns == true}.

\pnum
\throws
Any exception thrown by \tcode{pm->lock()}. \tcode{system_error} when an exception
is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}.
\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns}
is \tcode{true}.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{try_lock}{unique_lock}%
\begin{itemdecl}
bool try_lock();
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The supplied \tcode{Mutex} meets the \oldconcept{Lockable}
requirements\iref{thread.req.lockable.req}.

\pnum
\effects
As if by \tcode{pm->try_lock()}.

\pnum
\ensures
\tcode{owns == res}, where \tcode{res} is the value returned by
\tcode{pm->try_lock()}.

\pnum
\returns
The value returned by \tcode{pm->try_lock()}.

\pnum
\throws
Any exception thrown by \tcode{pm->try_lock()}. \tcode{system_error} when an exception
is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}.
\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns}
is \tcode{true}.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{try_lock_until}{unique_lock}%
\begin{itemdecl}
template<class Clock, class Duration>
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The supplied \tcode{Mutex} type meets the \oldconcept{TimedLockable}
requirements\iref{thread.req.lockable.timed}.

\pnum
\effects
As if by \tcode{pm->try_lock_until(abs_time)}.

\pnum
\ensures
\tcode{owns == res}, where \tcode{res} is the value returned by
\tcode{pm->try_lock_until(abs_time)}.

\pnum
\returns
The value returned by \tcode{pm->try_lock_until(abs_time)}.

\pnum
\throws
Any exception thrown by \tcode{pm->try_lock_until(abstime)}. \tcode{system_error} when an
exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}.
\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns} is
\tcode{true}.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{try_lock_for}{unique_lock}%
\begin{itemdecl}
template<class Rep, class Period>
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The supplied \tcode{Mutex} type meets the \oldconcept{TimedLockable} requirements\iref{thread.req.lockable.timed}.

\pnum
\effects
As if by \tcode{pm->try_lock_for(rel_time)}.

\pnum
\ensures
\tcode{owns == res}, where \tcode{res} is the value returned by \tcode{pm->try_lock_for(rel_time)}.

\pnum
\returns
The value returned by \tcode{pm->try_lock_for(rel_time)}.

\pnum
\throws
Any exception thrown by \tcode{pm->try_lock_for(rel_time)}. \tcode{system_error} when an
exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}.
\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns} is
\tcode{true}.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{unlock}{unique_lock}%
\begin{itemdecl}
void unlock();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
As if by \tcode{pm->unlock()}.

\pnum
\ensures
\tcode{owns == false}.

\pnum
\throws
\tcode{system_error} when
an exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{operation_not_permitted} --- if on entry \tcode{owns} is \tcode{false}.
\end{itemize}
\end{itemdescr}

\rSec4[thread.lock.unique.mod]{Modifiers}

\indexlibrarymember{swap}{unique_lock}%
\begin{itemdecl}
void swap(unique_lock& u) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Swaps the data members of \tcode{*this} and \tcode{u}.
\end{itemdescr}

\indexlibrarymember{release}{unique_lock}%
\begin{itemdecl}
mutex_type* release() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{pm == 0} and \tcode{owns == false}.

\pnum
\returns
The previous value of \tcode{pm}.
\end{itemdescr}

\indexlibrarymember{swap}{unique_lock}%
\begin{itemdecl}
template<class Mutex>
  void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
As if by \tcode{x.swap(y)}.
\end{itemdescr}

\rSec4[thread.lock.unique.obs]{Observers}

\indexlibrarymember{owns_lock}{unique_lock}%
\begin{itemdecl}
bool owns_lock() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{owns}.
\end{itemdescr}

\indexlibrarymember{operator bool}{unique_lock}%
\begin{itemdecl}
explicit operator bool() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{owns}.
\end{itemdescr}

\indexlibrarymember{mutex}{unique_lock}%
\begin{itemdecl}
mutex_type *mutex() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{pm}.
\end{itemdescr}

\rSec3[thread.lock.shared]{Class template \tcode{shared_lock}}

\rSec4[thread.lock.shared.general]{General}

\indexlibraryglobal{shared_lock}%
\begin{codeblock}
namespace std {
  template<class Mutex>
  class shared_lock {
  public:
    using mutex_type = Mutex;

    // \ref{thread.lock.shared.cons}, construct/copy/destroy
    shared_lock() noexcept;
    explicit shared_lock(mutex_type& m);        // blocking
    shared_lock(mutex_type& m, defer_lock_t) noexcept;
    shared_lock(mutex_type& m, try_to_lock_t);
    shared_lock(mutex_type& m, adopt_lock_t);
    template<class Clock, class Duration>
      shared_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
    template<class Rep, class Period>
      shared_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
    ~shared_lock();

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

    shared_lock(shared_lock&& u) noexcept;
    shared_lock& operator=(shared_lock&& u) noexcept;

    // \ref{thread.lock.shared.locking}, locking
    void lock();                                // blocking
    bool try_lock();
    template<class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
    template<class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
    void unlock();

    // \ref{thread.lock.shared.mod}, modifiers
    void swap(shared_lock& u) noexcept;
    mutex_type* release() noexcept;

    // \ref{thread.lock.shared.obs}, observers
    bool owns_lock() const noexcept;
    explicit operator bool() const noexcept;
    mutex_type* mutex() const noexcept;

  private:
    mutex_type* pm;                             // \expos
    bool owns;                                  // \expos
  };
}
\end{codeblock}

\pnum
An object of type \tcode{shared_lock} controls the shared ownership of a
lockable object within a scope. Shared ownership of the lockable object may be
acquired at construction or after construction, and may be transferred, after
acquisition, to another \tcode{shared_lock} object. Objects of type
\tcode{shared_lock} are not copyable but are movable. The behavior of a program
is undefined if the contained pointer \tcode{pm} is not null and the lockable
object pointed to by \tcode{pm} does not exist for the entire remaining
lifetime\iref{basic.life} of the \tcode{shared_lock} object. The supplied
\tcode{Mutex} type shall meet the \oldconcept{SharedLockable}
requirements\iref{thread.req.lockable.shared}.

\pnum
\begin{note}
\tcode{shared_lock<Mutex>} meets the \oldconcept{Lockable}
requirements\iref{thread.req.lockable.req}.
If \tcode{Mutex} meets the \oldconcept{Shared\-TimedLockable}
requirements\iref{thread.req.lockable.shared.timed},
\tcode{shared_lock<Mutex>} also meets the \oldconcept{TimedLockable}
requirements\iref{thread.req.lockable.timed}.
\end{note}

\rSec4[thread.lock.shared.cons]{Constructors, destructor, and assignment}

\indexlibraryctor{shared_lock}%
\begin{itemdecl}
shared_lock() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{pm == nullptr} and \tcode{owns == false}.
\end{itemdescr}

\indexlibraryctor{shared_lock}%
\begin{itemdecl}
explicit shared_lock(mutex_type& m);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Calls \tcode{m.lock_shared()}.

\pnum
\ensures
\tcode{pm == addressof(m)} and \tcode{owns == true}.
\end{itemdescr}

\indexlibraryctor{shared_lock}%
\begin{itemdecl}
shared_lock(mutex_type& m, defer_lock_t) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{pm == addressof(m)} and \tcode{owns == false}.
\end{itemdescr}

\indexlibraryctor{shared_lock}%
\begin{itemdecl}
shared_lock(mutex_type& m, try_to_lock_t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Calls \tcode{m.try_lock_shared()}.

\pnum
\ensures
\tcode{pm == addressof(m)} and \tcode{owns == res}
where \tcode{res} is the
value returned by the call to \tcode{m.try_lock_shared()}.
\end{itemdescr}

\indexlibraryctor{shared_lock}%
\begin{itemdecl}
shared_lock(mutex_type& m, adopt_lock_t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The calling thread holds a shared lock on \tcode{m}.

\pnum
\ensures
\tcode{pm == addressof(m)} and \tcode{owns == true}.
\end{itemdescr}

\indexlibraryctor{shared_lock}%
\begin{itemdecl}
template<class Clock, class Duration>
  shared_lock(mutex_type& m,
              const chrono::time_point<Clock, Duration>& abs_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{Mutex} meets the \oldconcept{SharedTimedLockable}
requirements\iref{thread.req.lockable.shared.timed}.

\pnum
\effects
Calls \tcode{m.try_lock_shared_until(abs_time)}.

\pnum
\ensures
\tcode{pm == addressof(m)} and \tcode{owns == res}
where \tcode{res}
is the value returned by the call to \tcode{m.try_lock_shared_until(abs_time)}.
\end{itemdescr}

\indexlibraryctor{shared_lock}%
\begin{itemdecl}
template<class Rep, class Period>
  shared_lock(mutex_type& m,
              const chrono::duration<Rep, Period>& rel_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{Mutex} meets the \oldconcept{SharedTimedLockable}
requirements\iref{thread.req.lockable.shared.timed}.

\pnum
\effects
Calls \tcode{m.try_lock_shared_for(rel_time)}.

\pnum
\ensures
\tcode{pm == addressof(m)} and \tcode{owns == res}
where \tcode{res} is
the value returned by the call to \tcode{m.try_lock_shared_for(rel_time)}.
\end{itemdescr}

\indexlibrarydtor{shared_lock}%
\begin{itemdecl}
~shared_lock();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{owns} calls \tcode{pm->unlock_shared()}.
\end{itemdescr}

\indexlibraryctor{shared_lock}%
\begin{itemdecl}
shared_lock(shared_lock&& sl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{pm == sl_p.pm} and \tcode{owns == sl_p.owns} (where
\tcode{sl_p} is the state of \tcode{sl} just prior to this construction),
\tcode{sl.pm == nullptr} and \tcode{sl.owns == false}.
\end{itemdescr}

\indexlibrarymember{operator=}{shared_lock}%
\begin{itemdecl}
shared_lock& operator=(shared_lock&& sl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{shared_lock(std::move(sl)).swap(*this)}

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\rSec4[thread.lock.shared.locking]{Locking}

\indexlibrarymember{lock}{shared_lock}%
\begin{itemdecl}
void lock();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
As if by \tcode{pm->lock_shared()}.

\pnum
\ensures
\tcode{owns == true}.

\pnum
\throws
Any exception thrown by \tcode{pm->lock_shared()}.
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}.
\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns} is
\tcode{true}.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{try_lock}{shared_lock}%
\begin{itemdecl}
bool try_lock();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
As if by \tcode{pm->try_lock_shared()}.

\pnum
\ensures
\tcode{owns == res}, where \tcode{res} is the value returned by
the call to \tcode{pm->try_lock_shared()}.

\pnum
\returns
The value returned by the call to \tcode{pm->try_lock_shared()}.

\pnum
\throws
Any exception thrown by \tcode{pm->try_lock_shared()}.
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}.
\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns} is
\tcode{true}.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{try_lock_until}{shared_lock}%
\begin{itemdecl}
template<class Clock, class Duration>
  bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{Mutex} meets the \oldconcept{SharedTimedLockable}
requirements\iref{thread.req.lockable.shared.timed}.

\pnum
\effects
As if by \tcode{pm->try_lock_shared_until(abs_time)}.

\pnum
\ensures
\tcode{owns == res}, where \tcode{res} is the value returned by
the call to \tcode{pm->try_lock_shared_until(abs_time)}.

\pnum
\returns
The value returned by the call to
\tcode{pm->try_lock_shared_until(abs_time)}.

\pnum
\throws
Any exception thrown by \tcode{pm->try_lock_shared_until(abs_time)}.
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}.
\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns} is
\tcode{true}.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{try_lock_for}{shared_lock}%
\begin{itemdecl}
template<class Rep, class Period>
  bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{Mutex} meets the \oldconcept{SharedTimedLockable}
requirements\iref{thread.req.lockable.shared.timed}.

\pnum
\effects
As if by \tcode{pm->try_lock_shared_for(rel_time)}.

\pnum
\ensures
\tcode{owns == res}, where \tcode{res} is the value returned by the call to \tcode{pm->try_lock_shared_for(rel_time)}.

\pnum
\returns
The value returned by the call to \tcode{pm->try_lock_shared_for(rel_time)}.

\pnum
\throws
Any exception thrown by \tcode{pm->try_lock_shared_for(rel_time)}. \tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{operation_not_permitted} --- if \tcode{pm} is \keyword{nullptr}.
\item \tcode{resource_deadlock_would_occur} --- if on entry \tcode{owns} is
\tcode{true}.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{unlock}{shared_lock}%
\begin{itemdecl}
void unlock();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
As if by \tcode{pm->unlock_shared()}.

\pnum
\ensures
\tcode{owns == false}.

\pnum
\throws
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{operation_not_permitted} --- if on entry \tcode{owns} is
\tcode{false}.
\end{itemize}
\end{itemdescr}

\rSec4[thread.lock.shared.mod]{Modifiers}

\indexlibrarymember{swap}{shared_lock}%
\begin{itemdecl}
void swap(shared_lock& sl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Swaps the data members of \tcode{*this} and \tcode{sl}.
\end{itemdescr}

\indexlibrarymember{release}{shared_lock}%
\begin{itemdecl}
mutex_type* release() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{pm == nullptr} and \tcode{owns == false}.

\pnum
\returns
The previous value of \tcode{pm}.
\end{itemdescr}

\indexlibrarymember{swap}{shared_lock}%
\begin{itemdecl}
template<class Mutex>
  void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
As if by \tcode{x.swap(y)}.
\end{itemdescr}

\rSec4[thread.lock.shared.obs]{Observers}

\indexlibrarymember{owns_lock}{shared_lock}%
\begin{itemdecl}
bool owns_lock() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{owns}.
\end{itemdescr}

\indexlibrarymember{operator bool}{shared_lock}%
\begin{itemdecl}
explicit operator bool() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{owns}.
\end{itemdescr}

\indexlibrarymember{mutex}{shared_lock}%
\begin{itemdecl}
mutex_type* mutex() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{pm}.
\end{itemdescr}

\rSec2[thread.lock.algorithm]{Generic locking algorithms}

\indexlibraryglobal{try_lock}%
\begin{itemdecl}
template<class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
Each template parameter type meets the \oldconcept{Lockable} requirements.
\begin{note}
The
\tcode{unique_lock} class template meets these requirements when suitably instantiated.
\end{note}

\pnum
\effects
Calls \tcode{try_lock()} for each argument in order beginning with the
first until all arguments have been processed or a call to \tcode{try_lock()} fails,
either by returning \tcode{false} or by throwing an exception. If a call to
\tcode{try_lock()} fails, \tcode{unlock()} is called for all prior arguments
with no further calls to \tcode{try_lock()}.

\pnum
\returns
\tcode{-1} if all calls to \tcode{try_lock()} returned \tcode{true},
otherwise a zero-based index value that indicates the argument for which \tcode{try_lock()}
returned \tcode{false}.
\end{itemdescr}

\indexlibraryglobal{lock}%
\begin{itemdecl}
template<class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
Each template parameter type meets the \oldconcept{Lockable} requirements.
\begin{note}
The
\tcode{unique_lock} class template meets these requirements when suitably instantiated.
\end{note}

\pnum
\effects
All arguments are locked via a sequence of calls to \tcode{lock()},
\tcode{try_lock()}, or \tcode{unlock()} on each argument. The sequence of calls does
not result in deadlock, but is otherwise unspecified.
\begin{note}
A deadlock avoidance
algorithm such as try-and-back-off can be used, but the specific algorithm is not
specified to avoid over-constraining implementations.
\end{note}
If a call to
\tcode{lock()} or \tcode{try_lock()} throws an exception, \tcode{unlock()} is
called for any argument that had been locked by a call to \tcode{lock()} or
\tcode{try_lock()}.
\end{itemdescr}

\rSec2[thread.once]{Call once}

\rSec3[thread.once.onceflag]{Struct \tcode{once_flag}}

\indexlibraryglobal{once_flag}%
\begin{codeblock}
namespace std {
  struct once_flag {
    constexpr once_flag() noexcept;

    once_flag(const once_flag&) = delete;
    once_flag& operator=(const once_flag&) = delete;
  };
}
\end{codeblock}

\pnum
The class \tcode{once_flag} is an opaque data structure that \tcode{call_once} uses to
initialize data without causing a data race or deadlock.

\indexlibraryglobal{once_flag}%
\begin{itemdecl}
constexpr once_flag() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\sync
The construction of a \tcode{once_flag} object is not synchronized.

\pnum
\ensures
The object's internal state is set to indicate to an invocation of
\tcode{call_once} with the object as its initial argument that no function has been
called.
\end{itemdescr}

\rSec3[thread.once.callonce]{Function \tcode{call_once}}

\indexlibraryglobal{call_once}%
\begin{itemdecl}
template<class Callable, class... Args>
  void call_once(once_flag& flag, Callable&& func, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
\tcode{is_invocable_v<Callable, Args...>} is \tcode{true}.

\pnum
\effects
An execution of \tcode{call_once} that does not call its \tcode{func} is a
\term{passive} execution. An execution of \tcode{call_once} that calls its \tcode{func}
is an \term{active} execution. An active execution evaluates
\tcode{\placeholdernc{INVOKE}(\brk{}%
std::forward<Callable>(func),
std::forward<Args>(args)...)}\iref{func.require}. If such a call to \tcode{func}
throws an exception the execution is \term{exceptional}, otherwise it is \term{returning}.
An exceptional execution propagates the exception to the caller of
\tcode{call_once}. Among all executions of \tcode{call_once} for any given
\tcode{once_flag}: at most one is a returning execution; if there is a
returning execution, it is the last active execution; and there are
passive executions only if there is a returning execution.
\begin{note}
Passive
executions allow other threads to reliably observe the results produced by the
earlier returning execution.
\end{note}

\pnum
\sync
For any given \tcode{once_flag}: all active executions occur in a total
order; completion of an active execution synchronizes with\iref{intro.multithread}
the start of the next one in this total order; and the returning execution
synchronizes with the return from all passive executions.

\pnum
\throws
\tcode{system_error} when
an exception is required\iref{thread.req.exception}, or any exception thrown by \tcode{func}.

\pnum
\begin{example}
\begin{codeblock}
// global flag, regular function
void init();
std::once_flag flag;

void f() {
  std::call_once(flag, init);
}

// function static flag, function object
struct initializer {
  void operator()();
};

void g() {
  static std::once_flag flag2;
  std::call_once(flag2, initializer());
}

// object flag, member function
class information {
  std::once_flag verified;
  void verifier();
public:
  void verify() { std::call_once(verified, &information::verifier, *this); }
};
\end{codeblock}
\end{example}
\end{itemdescr}


\rSec1[thread.condition]{Condition variables}

\rSec2[thread.condition.general]{General}

\pnum
Condition variables provide synchronization primitives used to block a thread until
notified by some other thread that some condition is met or until a system time is
reached. Class \tcode{condition_variable} provides a condition variable that can only
wait on an object of type \tcode{unique_lock<mutex>}, allowing the implementation
to be more efficient. Class \tcode{condition_variable_any} provides a general
condition variable that can wait on objects of user-supplied lock types.

\pnum
Condition variables permit concurrent invocation of the \tcode{wait}, \tcode{wait_for},
\tcode{wait_until}, \tcode{notify_one} and \tcode{notify_all} member functions.

\pnum
The executions of \tcode{notify_one} and \tcode{notify_all}
are atomic.
The executions of \tcode{wait}, \tcode{wait_for}, and \tcode{wait_until} are performed
in three atomic parts:
\begin{enumerate}
\item the release of the mutex and entry into the waiting state;
\item the unblocking of the wait; and
\item the reacquisition of the lock.
\end{enumerate}

\pnum
The implementation behaves as if all executions of \tcode{notify_one}, \tcode{notify_all}, and each
part of the \tcode{wait}, \tcode{wait_for}, and \tcode{wait_until} executions are
executed in a single unspecified total order consistent with the ``happens before'' order.

\pnum
Condition variable construction and destruction need not be synchronized.

\rSec2[condition.variable.syn]{Header \tcode{<condition_variable>} synopsis}

\indexheader{condition_variable}%
\begin{codeblock}
namespace std {
  // \ref{thread.condition.condvar}, class \tcode{condition_variable}
  class condition_variable;
  // \ref{thread.condition.condvarany}, class \tcode{condition_variable_any}
  class condition_variable_any;

  // \ref{thread.condition.nonmember}, non-member functions
  void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);

  enum class @\libglobal{cv_status}@ { @\libmember{no_timeout}{cv_status}@, @\libmember{timeout}{cv_status}@ };
}
\end{codeblock}

\rSec2[thread.condition.nonmember]{Non-member functions}
\indexlibraryglobal{notify_all_at_thread_exit}%
\begin{itemdecl}
void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{lk} is locked by the calling thread and either
\begin{itemize}
\item no other thread is waiting on \tcode{cond}, or
\item \tcode{lk.mutex()} returns the same value for each of the lock arguments
supplied by all concurrently waiting (via \tcode{wait}, \tcode{wait_for},
or \tcode{wait_until}) threads.
\end{itemize}

\pnum
\effects
Transfers ownership of the lock associated with \tcode{lk} into
internal storage and schedules \tcode{cond} to be notified when the current
thread exits.
This notification is sequenced after
all objects with thread storage duration associated with
the current thread have been destroyed and
is equivalent to:
\begin{codeblock}
cond.notify_all();
lk.unlock();
\end{codeblock}

\pnum
\sync
The implied \tcode{lk.unlock()} call is sequenced after the destruction of
all objects with thread storage duration associated with the current thread.

\pnum
\begin{note}
The supplied lock is held until the thread exits,
which might cause deadlock due to lock ordering issues.
\end{note}

\pnum
\begin{note}
It is the user's responsibility to ensure that waiting threads
do not incorrectly assume that the thread has finished if they experience
spurious wakeups. This typically requires that the condition being waited
for is satisfied while holding the lock on \tcode{lk}, and that this lock
is not released and reacquired prior to calling \tcode{notify_all_at_thread_exit}.
\end{note}
\end{itemdescr}

\rSec2[thread.condition.condvar]{Class \tcode{condition_variable}}

\indexlibraryglobal{condition_variable}%
\begin{codeblock}
namespace std {
  class condition_variable {
  public:
    condition_variable();
    ~condition_variable();

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

    void notify_one() noexcept;
    void notify_all() noexcept;
    void wait(unique_lock<mutex>& lock);
    template<class Predicate>
      void wait(unique_lock<mutex>& lock, Predicate pred);
    template<class Clock, class Duration>
      cv_status wait_until(unique_lock<mutex>& lock,
                           chrono::time_point<Clock, Duration> abs_time);
    template<class Clock, class Duration, class Predicate>
      bool wait_until(unique_lock<mutex>& lock,
                      chrono::time_point<Clock, Duration> abs_time,
                      Predicate pred);
    template<class Rep, class Period>
      cv_status wait_for(unique_lock<mutex>& lock,
                         chrono::duration<Rep, Period> rel_time);
    template<class Rep, class Period, class Predicate>
      bool wait_for(unique_lock<mutex>& lock,
                    chrono::duration<Rep, Period> rel_time,
                    Predicate pred);

    using native_handle_type = @\impdefnc@;          // see~\ref{thread.req.native}
    native_handle_type native_handle();                         // see~\ref{thread.req.native}
  };
}
\end{codeblock}

\pnum
The class \tcode{condition_variable} is a standard-layout class\iref{class.prop}.

\indexlibraryctor{condition_variable}%
\begin{itemdecl}
condition_variable();
\end{itemdecl}

\begin{itemdescr}
\pnum
\throws
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{resource_unavailable_try_again} --- if some non-memory resource
limitation prevents initialization.
\end{itemize}
\end{itemdescr}

\indexlibrarydtor{condition_variable}%
\begin{itemdecl}
~condition_variable();
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
There is no thread blocked on \tcode{*this}.
\begin{note}
That is, all
threads have been notified; they can subsequently block on the lock specified in the
wait.
This relaxes the usual rules, which would have required all wait calls to happen before
destruction. Only the notification to unblock the wait needs to happen before destruction.
Undefined behavior ensues if a thread waits on \tcode{*this} once the destructor has
been started, especially when the waiting threads are calling the wait functions in a loop or
using the overloads of \tcode{wait}, \tcode{wait_for}, or \tcode{wait_until} that take a predicate.
\end{note}
\end{itemdescr}

\indexlibrarymember{notify_one}{condition_variable}%
\begin{itemdecl}
void notify_one() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If any threads are blocked waiting for \tcode{*this}, unblocks one of those threads.
\end{itemdescr}

\indexlibrarymember{notify_all}{condition_variable}%
\begin{itemdecl}
void notify_all() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Unblocks all threads that are blocked waiting for \tcode{*this}.
\end{itemdescr}

\indexlibrarymember{wait}{condition_variable}%
\begin{itemdecl}
void wait(unique_lock<mutex>& lock);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()}
is locked by the calling thread, and either
\begin{itemize}
\item no other thread is waiting on this \tcode{condition_variable} object or
\item \tcode{lock.mutex()} returns the same value for each of the \tcode{lock}
arguments supplied by all concurrently waiting (via \tcode{wait},
\tcode{wait_for}, or \tcode{wait_until}) threads.
\end{itemize}

\pnum
\indextext{block (execution)}%
\effects
\begin{itemize}
\item Atomically calls \tcode{lock.unlock()} and blocks on \tcode{*this}.
\item When unblocked, calls \tcode{lock.lock()} (possibly blocking on the lock), then returns.
\item The function will unblock when signaled by a call to \tcode{notify_one()}
or a call to \tcode{notify_all()}, or spuriously.
\end{itemize}

\pnum
\ensures
\tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()}
is locked by the calling thread.

\pnum
\throws
Nothing.

\pnum
\remarks
If the function fails to meet the postcondition, \tcode{terminate()}
is invoked\iref{except.terminate}.
\begin{note}
This can happen if the re-locking of the mutex throws an exception.
\end{note}
\end{itemdescr}

\indexlibrarymember{wait}{condition_variable}%
\begin{itemdecl}
template<class Predicate>
  void wait(unique_lock<mutex>& lock, Predicate pred);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()} is
locked by the calling thread, and either
\begin{itemize}
\item no other thread is waiting on this \tcode{condition_variable} object or
\item \tcode{lock.mutex()} returns the same value for each of the \tcode{lock}
arguments supplied by all concurrently waiting (via \tcode{wait},
\tcode{wait_for}, or \tcode{wait_until}) threads.
\end{itemize}

\pnum
\effects
Equivalent to:
\begin{codeblock}
while (!pred())
  wait(lock);
\end{codeblock}

\pnum
\ensures
\tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()}
is locked by the calling thread.

\pnum
\throws
Any exception thrown by \tcode{pred}.

\pnum
\remarks
If the function fails to meet the postcondition, \tcode{terminate()}
is invoked\iref{except.terminate}.
\begin{note}
This can happen if the re-locking of the mutex throws an exception.
\end{note}
\end{itemdescr}

\indexlibrarymember{wait_until}{condition_variable}%
\begin{itemdecl}
template<class Clock, class Duration>
  cv_status wait_until(unique_lock<mutex>& lock,
                       chrono::time_point<Clock, Duration> abs_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()}
is locked by the calling thread, and either
\begin{itemize}
\item no other thread is waiting on this \tcode{condition_variable} object or
\item \tcode{lock.mutex()} returns the same value for each of the \tcode{lock}
arguments supplied by all concurrently waiting (via \tcode{wait},
\tcode{wait_for}, or \tcode{wait_until}) threads.
\end{itemize}

\pnum
\effects
\begin{itemize}
\item
Atomically calls \tcode{lock.unlock()} and blocks on \tcode{*this}.

\item
When unblocked, calls \tcode{lock.lock()} (possibly blocking on the lock), then returns.

\item
The function will unblock when signaled by a call to \tcode{notify_one()}, a call to \tcode{notify_all()},
expiration of the absolute timeout\iref{thread.req.timing} specified by \tcode{abs_time},
or spuriously.

\item
If the function exits via an exception, \tcode{lock.lock()} is called prior to exiting the function.
\end{itemize}

\pnum
\ensures
\tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()}
is locked by the calling thread.

\pnum
\returns
\tcode{cv_status::timeout} if
the absolute timeout\iref{thread.req.timing} specified by \tcode{abs_time} expired,
otherwise \tcode{cv_status::no_timeout}.

\pnum
\throws
Timeout-related
exceptions\iref{thread.req.timing}.

\pnum
\remarks
If the function fails to meet the postcondition, \tcode{terminate()}
is invoked\iref{except.terminate}.
\begin{note}
This can happen if the re-locking of the mutex throws an exception.
\end{note}
\end{itemdescr}

\indexlibrarymember{wait_for}{condition_variable}%
\begin{itemdecl}
template<class Rep, class Period>
  cv_status wait_for(unique_lock<mutex>& lock,
                     chrono::duration<Rep, Period> rel_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()}
is locked by the calling thread, and either
\begin{itemize}
\item no other thread is waiting on this \tcode{condition_variable} object or
\item \tcode{lock.mutex()} returns the same value for each of the \tcode{lock} arguments
supplied by all concurrently waiting (via \tcode{wait}, \tcode{wait_for}, or
\tcode{wait_until}) threads.
\end{itemize}

\pnum
\effects
Equivalent to:
\begin{codeblock}
return wait_until(lock, chrono::steady_clock::now() + rel_time);
\end{codeblock}

\pnum
\ensures
\tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()}
is locked by the calling thread.

\pnum
\returns
\tcode{cv_status::timeout} if
the relative timeout\iref{thread.req.timing} specified by \tcode{rel_time} expired,
otherwise \tcode{cv_status::no_timeout}.

\pnum
\throws
Timeout-related
exceptions\iref{thread.req.timing}.

\pnum
\remarks
If the function fails to meet the postcondition, \tcode{terminate}
is invoked\iref{except.terminate}.
\begin{note}
This can happen if the re-locking of the mutex throws an exception.
\end{note}
\end{itemdescr}

\indexlibrarymember{wait_until}{condition_variable}%
\begin{itemdecl}
template<class Clock, class Duration, class Predicate>
  bool wait_until(unique_lock<mutex>& lock,
                  chrono::time_point<Clock, Duration> abs_time,
                  Predicate pred);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()} is
locked by the calling thread, and either
\begin{itemize}
\item no other thread is waiting on this \tcode{condition_variable} object or
\item \tcode{lock.mutex()} returns the same value for each of the \tcode{lock}
arguments supplied by all concurrently waiting (via \tcode{wait},
\tcode{wait_for}, or \tcode{wait_until}) threads.
\end{itemize}

\pnum
\effects
Equivalent to:
\begin{codeblock}
while (!pred())
  if (wait_until(lock, abs_time) == cv_status::timeout)
    return pred();
return true;
\end{codeblock}

\pnum
\ensures
\tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()}
is locked by the calling thread.

\pnum
\begin{note}
The returned value indicates whether the predicate evaluated to
\tcode{true} regardless of whether the timeout was triggered.
\end{note}

\pnum
\throws
Timeout-related
exceptions\iref{thread.req.timing} or any exception thrown by \tcode{pred}.

\pnum
\remarks
If the function fails to meet the postcondition, \tcode{terminate()}
is invoked\iref{except.terminate}.
\begin{note}
This can happen if the re-locking of the mutex throws an exception.
\end{note}
\end{itemdescr}

\indexlibrarymember{wait_for}{condition_variable}%
\begin{itemdecl}
template<class Rep, class Period, class Predicate>
  bool wait_for(unique_lock<mutex>& lock,
                chrono::duration<Rep, Period> rel_time,
                Predicate pred);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()}
is locked by the calling thread, and either
\begin{itemize}
\item
no other thread is waiting on this \tcode{condition_variable} object or

\item
\tcode{lock.mutex()} returns the same value for each of the \tcode{lock} arguments
supplied by all concurrently waiting (via \tcode{wait}, \tcode{wait_for}, or
\tcode{wait_until}) threads.
\end{itemize}

\pnum
\effects
Equivalent to:
\begin{codeblock}
return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));
\end{codeblock}

\pnum
\begin{note}
There is no blocking if \tcode{pred()} is initially \tcode{true}, even if the
timeout has already expired.
\end{note}

\pnum
\ensures
\tcode{lock.owns_lock()} is \tcode{true} and \tcode{lock.mutex()}
is locked by the calling thread.

\pnum
\begin{note}
The returned value indicates whether the predicate evaluates to \tcode{true}
regardless of whether the timeout was triggered.
\end{note}

\pnum
\throws
Timeout-related
exceptions\iref{thread.req.timing} or any exception thrown by \tcode{pred}.

\pnum
\remarks
If the function fails to meet the postcondition, \tcode{terminate()}
is invoked\iref{except.terminate}.
\begin{note}
This can happen if the re-locking of the mutex throws an exception.
\end{note}
\end{itemdescr}

\rSec2[thread.condition.condvarany]{Class \tcode{condition_variable_any}}

\rSec3[thread.condition.condvarany.general]{General}

\pnum
In \ref{thread.condition.condvarany},
template arguments for template parameters named \tcode{Lock}
shall meet the \oldconcept{Basic\-Lockable}
requirements\iref{thread.req.lockable.basic}.
\begin{note}
All of the standard
mutex types meet this requirement. If a type other than one of the
standard mutex types or a \tcode{unique_lock} wrapper for a standard mutex type
is used with \tcode{condition_variable_any}, any
necessary synchronization is assumed to be in place with respect to the predicate associated
with the \tcode{condition_variable_any} instance.
\end{note}

\indexlibraryglobal{condition_variable_any}%
\begin{codeblock}
namespace std {
  class condition_variable_any {
  public:
    condition_variable_any();
    ~condition_variable_any();

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

    void notify_one() noexcept;
    void notify_all() noexcept;

    // \ref{thread.condvarany.wait}, noninterruptible waits
    template<class Lock>
      void wait(Lock& lock);
    template<class Lock, class Predicate>
      void wait(Lock& lock, Predicate pred);

    template<class Lock, class Clock, class Duration>
      cv_status wait_until(Lock& lock, chrono::time_point<Clock, Duration> abs_time);
    template<class Lock, class Clock, class Duration, class Predicate>
      bool wait_until(Lock& lock, chrono::time_point<Clock, Duration abs_time,
                      Predicate pred);
    template<class Lock, class Rep, class Period>
      cv_status wait_for(Lock& lock, chrono::duration<Rep, Period> rel_time);
    template<class Lock, class Rep, class Period, class Predicate>
      bool wait_for(Lock& lock, chrono::duration<Rep, Period> rel_time, Predicate pred);

    // \ref{thread.condvarany.intwait}, interruptible waits
    template<class Lock, class Predicate>
      bool wait(Lock& lock, stop_token stoken, Predicate pred);
    template<class Lock, class Clock, class Duration, class Predicate>
      bool wait_until(Lock& lock, stop_token stoken,
                      chrono::time_point<Clock, Duration> abs_time, Predicate pred);
    template<class Lock, class Rep, class Period, class Predicate>
      bool wait_for(Lock& lock, stop_token stoken,
                    chrono::duration<Rep, Period> rel_time, Predicate pred);
  };
}
\end{codeblock}

\indexlibraryctor{condition_variable_any}%
\begin{itemdecl}
condition_variable_any();
\end{itemdecl}

\begin{itemdescr}
\pnum
\throws
\tcode{bad_alloc} or \tcode{system_error} when an exception is
required\iref{thread.req.exception}.

\pnum
\errors
\begin{itemize}
\item \tcode{resource_unavailable_try_again} --- if some non-memory resource
limitation prevents initialization.

\item \tcode{operation_not_permitted} --- if the thread does not have the
privilege to perform the operation.
\end{itemize}
\end{itemdescr}

\indexlibrarydtor{condition_variable_any}%
\begin{itemdecl}
~condition_variable_any();
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
There is no thread blocked on \tcode{*this}.
\begin{note}
That is, all
threads have been notified; they can subsequently block on the lock specified in the
wait.
This relaxes the usual rules, which would have required all wait calls to happen before
destruction. Only the notification to unblock the wait needs to happen before destruction.
Undefined behavior ensues if a thread waits on \tcode{*this} once the destructor has
been started, especially when the waiting threads are calling the wait functions in a loop or
using the overloads of \tcode{wait}, \tcode{wait_for}, or \tcode{wait_until} that take a predicate.
\end{note}
\end{itemdescr}

\indexlibrarymember{notify_one}{condition_variable_any}%
\begin{itemdecl}
void notify_one() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If any threads are blocked waiting for \tcode{*this}, unblocks one of those threads.
\end{itemdescr}

\indexlibrarymember{notify_all}{condition_variable_any}%
\begin{itemdecl}
void notify_all() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Unblocks all threads that are blocked waiting for \tcode{*this}.
\end{itemdescr}

\rSec3[thread.condvarany.wait]{Noninterruptible waits}

\indexlibrarymember{wait}{condition_variable_any}%
\begin{itemdecl}
template<class Lock>
  void wait(Lock& lock);
\end{itemdecl}

\begin{itemdescr}
\pnum
\indextext{block (execution)}%
\effects
\begin{itemize}
\item Atomically calls \tcode{lock.unlock()} and blocks on \tcode{*this}.
\item When unblocked, calls \tcode{lock.lock()} (possibly blocking on the lock) and returns.
\item The function will unblock when signaled by a call to \tcode{notify_one()},
a call to \tcode{notify_all()}, or spuriously.
\end{itemize}

\pnum
\ensures
\tcode{lock} is locked by the calling thread.

\pnum
\throws
Nothing.

\pnum
\remarks
If the function fails to meet the postcondition, \tcode{terminate()}
is invoked\iref{except.terminate}.
\begin{note}
This can happen if the re-locking of the mutex throws an exception.
\end{note}
\end{itemdescr}

\indexlibrarymember{wait}{condition_variable_any}%
\begin{itemdecl}
template<class Lock, class Predicate>
  void wait(Lock& lock, Predicate pred);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
while (!pred())
  wait(lock);
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{wait_until}{condition_variable_any}%
\begin{itemdecl}
template<class Lock, class Clock, class Duration>
  cv_status wait_until(Lock& lock, chrono::time_point<Clock, Duration> abs_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects

\begin{itemize}
\item
\indextext{block (execution)}%
Atomically calls \tcode{lock.unlock()} and blocks on \tcode{*this}.

\item
When unblocked, calls \tcode{lock.lock()} (possibly blocking on the lock) and returns.

\item
The function will unblock when signaled by a call to \tcode{notify_one()}, a call to \tcode{notify_all()},
expiration of the absolute timeout\iref{thread.req.timing} specified by \tcode{abs_time},
or spuriously.

\item
If the function exits via an exception, \tcode{lock.lock()} is called prior to exiting the function.
\end{itemize}

\pnum
\ensures
\tcode{lock} is locked by the calling thread.

\pnum
\returns
\tcode{cv_status::timeout} if
the absolute timeout\iref{thread.req.timing} specified by \tcode{abs_time} expired,
otherwise \tcode{cv_status::no_timeout}.

\pnum
\throws
Timeout-related
exceptions\iref{thread.req.timing}.

\pnum
\remarks
If the function fails to meet the postcondition, \tcode{terminate()}
is invoked\iref{except.terminate}.
\begin{note}
This can happen if the re-locking of the mutex throws an exception.
\end{note}
\end{itemdescr}

\indexlibrarymember{wait_for}{condition_variable_any}%
\begin{itemdecl}
template<class Lock, class Rep, class Period>
  cv_status wait_for(Lock& lock, chrono::duration<Rep, Period> rel_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return wait_until(lock, chrono::steady_clock::now() + rel_time);
\end{codeblock}

\pnum
\ensures
\tcode{lock} is locked by the calling thread.

\pnum
\returns
\tcode{cv_status::timeout} if
the relative timeout\iref{thread.req.timing} specified by \tcode{rel_time} expired,
otherwise \tcode{cv_status::no_timeout}.

\pnum
\throws
Timeout-related
exceptions\iref{thread.req.timing}.

\pnum
\remarks
If the function fails to meet the postcondition, \tcode{terminate}
is invoked\iref{except.terminate}.
\begin{note}
This can happen if the re-locking of the mutex throws an exception.
\end{note}
\end{itemdescr}

\indexlibrarymember{wait_until}{condition_variable_any}%
\begin{itemdecl}
template<class Lock, class Clock, class Duration, class Predicate>
  bool wait_until(Lock& lock, chrono::time_point<Clock, Duration> abs_time, Predicate pred);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
while (!pred())
  if (wait_until(lock, abs_time) == cv_status::timeout)
    return pred();
return true;
\end{codeblock}

\pnum
\begin{note}
There is no blocking if \tcode{pred()} is initially \tcode{true}, or
if the timeout has already expired.
\end{note}

\pnum
\begin{note}
The returned value indicates whether the predicate evaluates to \tcode{true}
regardless of whether the timeout was triggered.
\end{note}
\end{itemdescr}

\indexlibrarymember{wait_for}{condition_variable_any}%
\begin{itemdecl}
template<class Lock, class Rep, class Period, class Predicate>
  bool wait_for(Lock& lock, chrono::duration<Rep, Period> rel_time, Predicate pred);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return wait_until(lock, chrono::steady_clock::now() + rel_time, std::move(pred));
\end{codeblock}
\end{itemdescr}

\rSec3[thread.condvarany.intwait]{Interruptible waits}

\pnum
The following wait functions will be notified
when there is a stop request on the passed \tcode{stop_token}.
In that case the functions return immediately,
returning \tcode{false} if the predicate evaluates to \tcode{false}.

\begin{itemdecl}
template<class Lock, class Predicate>
  bool wait(Lock& lock, stop_token stoken, Predicate pred);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Registers for the duration of this call \tcode{*this}
to get notified on a stop request on \tcode{stoken}
during this call and then equivalent to:
\begin{codeblock}
while (!stoken.stop_requested()) {
  if (pred())
    return true;
  wait(lock);
}
return pred();
\end{codeblock}

\pnum
\begin{note}
The returned value indicates whether the predicate evaluated to
\tcode{true} regardless of whether there was a stop request.
\end{note}

\pnum
\ensures
\tcode{lock} is locked by the calling thread.

\pnum
\throws
Any exception thrown by \tcode{pred}.

\pnum
\remarks
If the function fails to meet the postcondition,
\tcode{terminate} is called\iref{except.terminate}.
\begin{note}
This can happen if the re-locking of the mutex throws an exception.
\end{note}
\end{itemdescr}

\begin{itemdecl}
template<class Lock, class Clock, class Duration, class Predicate>
  bool wait_until(Lock& lock, stop_token stoken,
                  chrono::time_point<Clock, Duration> abs_time, Predicate pred);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Registers for the duration of this call \tcode{*this}
to get notified on a stop request on \tcode{stoken}
during this call and then equivalent to:
\begin{codeblock}
while (!stoken.stop_requested()) {
  if (pred())
    return true;
  if (wait_until(lock, abs_time) == cv_status::timeout)
    return pred();
}
return pred();
\end{codeblock}

\pnum
\begin{note}
There is no blocking if \tcode{pred()} is initially \tcode{true},
\tcode{stoken.stop_requested()} was already \tcode{true}
or the timeout has already expired.
\end{note}

\pnum
\begin{note}
The returned value indicates whether the predicate evaluated to \tcode{true}
regardless of whether the timeout was triggered or a stop request was made.
\end{note}

\pnum
\ensures
\tcode{lock} is locked by the calling thread.

\pnum
\throws
Timeout-related exceptions\iref{thread.req.timing},
or any exception thrown by \tcode{pred}.

\pnum
\remarks
If the function fails to meet the postcondition,
\tcode{terminate} is called\iref{except.terminate}.
\begin{note}
This can happen if the re-locking of the mutex throws an exception.
\end{note}
\end{itemdescr}

\begin{itemdecl}
template<class Lock, class Rep, class Period, class Predicate>
  bool wait_for(Lock& lock, stop_token stoken,
                chrono::duration<Rep, Period> rel_time, Predicate pred);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return wait_until(lock, std::move(stoken), chrono::steady_clock::now() + rel_time,
                  std::move(pred));
\end{codeblock}
\end{itemdescr}

\rSec1[thread.sema]{Semaphore}

\rSec2[thread.sema.general]{General}

\pnum
Semaphores are lightweight synchronization primitives
used to constrain concurrent access to a shared resource.
They are widely used to implement other synchronization primitives and,
whenever both are applicable, can be more efficient than condition variables.

\pnum
A counting semaphore is a semaphore object
that models a non-negative resource count.
A binary semaphore is a semaphore object that has only two states.
A binary semaphore should be more efficient than
the default implementation of a counting semaphore with a unit resource count.

\rSec2[semaphore.syn]{Header \tcode{<semaphore>} synopsis}

\indexheader{semaphore}%
\begin{codeblock}
namespace std {
  // \ref{thread.sema.cnt}, class template \tcode{counting_semaphore}
  template<ptrdiff_t least_max_value = @\impdef@>
    class counting_semaphore;

  using @\libglobal{binary_semaphore}@ = counting_semaphore<1>;
}
\end{codeblock}

\rSec2[thread.sema.cnt]{Class template \tcode{counting_semaphore}}

\begin{codeblock}
namespace std {
  template<ptrdiff_t least_max_value = @\impdefx{default value for \tcode{least_max_value} template parameter of \tcode{counting_semaphore}}@>
  class counting_semaphore {
  public:
    static constexpr ptrdiff_t max() noexcept;

    constexpr explicit counting_semaphore(ptrdiff_t desired);
    ~counting_semaphore();

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

    void release(ptrdiff_t update = 1);
    void acquire();
    bool try_acquire() noexcept;
    template<class Rep, class Period>
      bool try_acquire_for(const chrono::duration<Rep, Period>& rel_time);
    template<class Clock, class Duration>
      bool try_acquire_until(const chrono::time_point<Clock, Duration>& abs_time);

  private:
    ptrdiff_t counter;          // \expos
  };
}
\end{codeblock}

\pnum
\indextext{block (execution)}%
Class template \tcode{counting_semaphore} maintains an internal counter
that is initialized when the semaphore is created.
The counter is decremented when a thread acquires the semaphore, and
is incremented when a thread releases the semaphore.
If a thread tries to acquire the semaphore when the counter is zero,
the thread will block
until another thread increments the counter by releasing the semaphore.

\pnum
\tcode{least_max_value} shall be non-negative; otherwise the program is ill-formed.

\pnum
Concurrent invocations of the member functions of \tcode{counting_semaphore},
other than its destructor, do not introduce data races.

\indexlibrarymember{max}{counting_semaphore}%
\begin{itemdecl}
static constexpr ptrdiff_t max() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The maximum value of \tcode{counter}.
This value is greater than or equal to \tcode{least_max_value}.
\end{itemdescr}

\indexlibraryctor{counting_semaphore}%
\begin{itemdecl}
constexpr explicit counting_semaphore(ptrdiff_t desired);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{desired >= 0} is \tcode{true}, and
\tcode{desired <= max()} is \tcode{true}.

\pnum
\effects
Initializes \tcode{counter} with \tcode{desired}.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibrarymember{release}{counting_semaphore}%
\begin{itemdecl}
void release(ptrdiff_t update = 1);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{update >= 0} is \tcode{true}, and
\tcode{update <= max() - counter} is \tcode{true}.

\pnum
\effects
Atomically execute \tcode{counter += update}.
Then, unblocks any threads
that are waiting for \tcode{counter} to be greater than zero.

\pnum
\sync
Strongly happens before invocations of \tcode{try_acquire}
that observe the result of the effects.

\pnum
\throws
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
Any of the error conditions
allowed for mutex types\iref{thread.mutex.requirements.mutex}.
\end{itemdescr}

\indexlibrarymember{try_acquire}{counting_semaphore}%
\begin{itemdecl}
bool try_acquire() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to atomically decrement \tcode{counter} if it is positive,
without blocking.
If \tcode{counter} is not decremented, there is no effect and
\tcode{try_acquire} immediately returns.
An implementation may fail to decrement \tcode{counter}
even if it is positive.
\begin{note}
This spurious failure is normally uncommon, but
allows interesting implementations
based on a simple compare and exchange\iref{atomics}.
\end{note}
An implementation should ensure that \tcode{try_acquire}
does not consistently return \tcode{false}
in the absence of contending semaphore operations.

\pnum
\returns
\tcode{true} if \tcode{counter} was decremented, otherwise \tcode{false}.
\end{itemdescr}

\indexlibrarymember{acquire}{counting_semaphore}%
\begin{itemdecl}
void acquire();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Repeatedly performs the following steps, in order:
\begin{itemize}
\item Evaluates \tcode{try_acquire()}. If the result is \tcode{true}, returns.
\item
\indextext{block (execution)}%
Blocks on \tcode{*this} until \tcode{counter} is greater than zero.
\end{itemize}

\pnum
\throws
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
Any of the error conditions
allowed for mutex types\iref{thread.mutex.requirements.mutex}.
\end{itemdescr}

\indexlibrarymember{try_acquire_for}{counting_semaphore}%
\indexlibrarymember{try_acquire_until}{counting_semaphore}%
\begin{itemdecl}
template<class Rep, class Period>
  bool try_acquire_for(const chrono::duration<Rep, Period>& rel_time);
template<class Clock, class Duration>
  bool try_acquire_until(const chrono::time_point<Clock, Duration>& abs_time);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Repeatedly performs the following steps, in order:
\begin{itemize}
\item
  Evaluates \tcode{try_acquire()}.
  If the result is \tcode{true}, returns \tcode{true}.
\item
  \indextext{block (execution)}%
  Blocks on \tcode{*this}
  until \tcode{counter} is greater than zero or until the timeout expires.
  If it is unblocked by the timeout expiring, returns \tcode{false}.
\end{itemize}
The timeout expires\iref{thread.req.timing}
when the current time is after \tcode{abs_time} (for \tcode{try_acquire_until})
or when at least \tcode{rel_time} has passed
from the start of the function (for \tcode{try_acquire_for}).

\pnum
\throws
Timeout-related exceptions\iref{thread.req.timing}, or \tcode{system_error}
when a non-timeout-related exception is required\iref{thread.req.exception}.

\pnum
\errors
Any of the error conditions
allowed for mutex types\iref{thread.mutex.requirements.mutex}.
\end{itemdescr}

\rSec1[thread.coord]{Coordination types}

\rSec2[thread.coord.general]{General}

\pnum
Subclause \ref{thread.coord} describes various concepts related to thread coordination, and
defines the coordination types \tcode{latch} and \tcode{barrier}.
These types facilitate concurrent computation performed by a number of threads.

\rSec2[thread.latch]{Latches}

\rSec3[thread.latch.general]{General}

\pnum
A latch is a thread coordination mechanism
that allows any number of threads to block
until an expected number of threads arrive at the latch
(via the \tcode{count_down} function).
The expected count is set when the latch is created.
An individual latch is a single-use object;
once the expected count has been reached, the latch cannot be reused.

\rSec3[latch.syn]{Header \tcode{<latch>} synopsis}

\indexheader{latch}%
\begin{codeblock}
namespace std {
  class latch;
}
\end{codeblock}

\rSec3[thread.latch.class]{Class \tcode{latch}}

\begin{codeblock}
namespace std {
  class latch {
  public:
    static constexpr ptrdiff_t max() noexcept;

    constexpr explicit latch(ptrdiff_t expected);
    ~latch();

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

    void count_down(ptrdiff_t update = 1);
    bool try_wait() const noexcept;
    void wait() const;
    void arrive_and_wait(ptrdiff_t update = 1);

  private:
    ptrdiff_t counter;  // \expos
  };
}
\end{codeblock}

\pnum
A \tcode{latch} maintains an internal counter
that is initialized when the latch is created.
Threads can block on the latch object,
waiting for counter to be decremented to zero.

\pnum
Concurrent invocations of the member functions of \tcode{latch},
other than its destructor, do not introduce data races.

\indexlibrarymember{max}{latch}%
\begin{itemdecl}
static constexpr ptrdiff_t max() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The maximum value of \tcode{counter} that the implementation supports.
\end{itemdescr}

\indexlibraryctor{latch}%
\begin{itemdecl}
constexpr explicit latch(ptrdiff_t expected);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{expected >= 0} is \tcode{true} and
\tcode{expected <= max()} is \tcode{true}.

\pnum
\effects
Initializes \tcode{counter} with \tcode{expected}.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibrarymember{count_down}{latch}%
\begin{itemdecl}
void count_down(ptrdiff_t update = 1);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{update >= 0} is \tcode{true}, and
\tcode{update <= counter} is \tcode{true}.

\pnum
\effects
Atomically decrements \tcode{counter} by \tcode{update}.
If \tcode{counter} is equal to zero,
unblocks all threads blocked on \tcode{*this}.

\pnum
\sync
Strongly happens before the returns from all calls that are unblocked.

\pnum
\throws
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
Any of the error conditions
allowed for mutex types\iref{thread.mutex.requirements.mutex}.
\end{itemdescr}

\indexlibrarymember{try_wait}{latch}%
\begin{itemdecl}
bool try_wait() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
With very low probability \tcode{false}. Otherwise \tcode{counter == 0}.
\end{itemdescr}

\indexlibrarymember{wait}{latch}%
\begin{itemdecl}
void wait() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\indextext{block (execution)}%
\effects
If \tcode{counter} equals zero, returns immediately.
Otherwise, blocks on \tcode{*this}
until a call to \tcode{count_down} that decrements \tcode{counter} to zero.

\pnum
\throws
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
Any of the error conditions
allowed for mutex types\iref{thread.mutex.requirements.mutex}.
\end{itemdescr}

\indexlibrarymember{arrive_and_wait}{latch}%
\begin{itemdecl}
void arrive_and_wait(ptrdiff_t update = 1);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
count_down(update);
wait();
\end{codeblock}
\end{itemdescr}

\rSec2[thread.barrier]{Barriers}

\rSec3[thread.barrier.general]{General}

\pnum
A barrier is a thread coordination mechanism
whose lifetime consists of a sequence of barrier phases,
where each phase allows at most an expected number of threads to block
until the expected number of threads arrive at the barrier.
\begin{note}
A barrier is useful for managing repeated tasks
that are handled by multiple threads.
\end{note}

\rSec3[barrier.syn]{Header \tcode{<barrier>} synopsis}

\indexheader{barrier}%
\begin{codeblock}
namespace std {
  template<class CompletionFunction = @\seebelow@>
    class barrier;
}
\end{codeblock}

\rSec3[thread.barrier.class]{Class template \tcode{barrier}}

\begin{codeblock}
namespace std {
  template<class CompletionFunction = @\seebelow@>
  class barrier {
  public:
    using arrival_token = @\seebelow@;

    static constexpr ptrdiff_t max() noexcept;

    constexpr explicit barrier(ptrdiff_t expected,
                               CompletionFunction f = CompletionFunction());
    ~barrier();

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

    arrival_token arrive(ptrdiff_t update = 1);
    void wait(arrival_token&& arrival) const;

    void arrive_and_wait();
    void arrive_and_drop();

  private:
    CompletionFunction completion;      // \expos
  };
}
\end{codeblock}

\pnum
Each \defn{barrier phase} consists of the following steps:
\begin{itemize}
\item
  The expected count is decremented
  by each call to \tcode{arrive} or \tcode{arrive_and_drop}.
\item
  Exactly once after the expected count reaches zero, a thread
  executes the completion step during its call
  to \tcode{arrive}, \tcode{arrive_and_drop}, or \tcode{wait},
  except that it is \impldef{barrier phrase completion without \tcode{wait}}
  whether the step executes if no thread calls \tcode{wait}.
\item
  When the completion step finishes,
  the expected count is reset
  to what was specified by the \tcode{expected} argument to the constructor,
  possibly adjusted by calls to \tcode{arrive_and_drop}, and
  the next phase starts.
\end{itemize}

\indextext{phase synchronization point|see{barrier, phase synchronization point}}%
\pnum
\indextext{block (execution)}%
Each phase defines a \defnx{phase synchronization point}{barrier!phase synchronization point}.
Threads that arrive at the barrier during the phase
can block on the phase synchronization point by calling \tcode{wait}, and
will remain blocked until the phase completion step is run.

\pnum
The \defn{phase completion step}
that is executed at the end of each phase has the following effects:
\begin{itemize}
\item Invokes the completion function, equivalent to \tcode{completion()}.
\item Unblocks all threads that are blocked on the phase synchronization point.
\end{itemize}
The end of the completion step strongly happens before
the returns from all calls that were unblocked by the completion step.
For specializations that do not have
the default value of the \tcode{CompletionFunction} template parameter,
the behavior is undefined if any of the barrier object's member functions
other than \tcode{wait} are called while the completion step is in progress.

\pnum
Concurrent invocations of the member functions of \tcode{barrier},
other than its destructor, do not introduce data races.
The member functions \tcode{arrive} and \tcode{arrive_and_drop}
execute atomically.

\pnum
\tcode{CompletionFunction} shall meet the
\oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}) and
\oldconcept{Destructible} (\tref{cpp17.destructible}) requirements.
\tcode{is_nothrow_invocable_v<CompletionFunction\&>} shall be \tcode{true}.

\pnum
The default value of the \tcode{CompletionFunction} template parameter is
an unspecified type, such that,
in addition to satisfying the requirements of \tcode{CompletionFunction},
it meets the \oldconcept{DefaultConstructible}
requirements (\tref{cpp17.defaultconstructible}) and
\tcode{completion()} has no effects.

\pnum
\tcode{barrier::arrival_token} is an unspecified type,
such that it meets the
\oldconcept{MoveConstructible} (\tref{cpp17.moveconstructible}),
\oldconcept{MoveAssignable} (\tref{cpp17.moveassignable}), and
\oldconcept{Destructible} (\tref{cpp17.destructible}) requirements.

\indexlibrarymember{max}{barrier}%
\begin{itemdecl}
static constexpr ptrdiff_t max() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The maximum expected count that the implementation supports.
\end{itemdescr}

\indexlibraryctor{barrier}
\begin{itemdecl}
constexpr explicit barrier(ptrdiff_t expected,
                           CompletionFunction f = CompletionFunction());
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{expected >= 0} is \tcode{true} and
\tcode{expected <= max()} is \tcode{true}.

\pnum
\effects
Sets both the initial expected count for each barrier phase and
the current expected count for the first phase to \tcode{expected}.
Initializes \tcode{completion} with \tcode{std::move(f)}.
Starts the first phase.
\begin{note}
If \tcode{expected} is 0 this object can only be destroyed.
\end{note}

\pnum
\throws
Any exception thrown by \tcode{CompletionFunction}'s move constructor.
\end{itemdescr}

\indexlibrarymember{arrive}{barrier}%
\begin{itemdecl}
arrival_token arrive(ptrdiff_t update = 1);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{update > 0} is \tcode{true}, and
\tcode{update} is less than or equal to
the expected count for the current barrier phase.

\pnum
\effects
Constructs an object of type \tcode{arrival_token}
that is associated with the phase synchronization point for the current phase.
Then, decrements the expected count by \tcode{update}.

\pnum
\sync
The call to \tcode{arrive} strongly happens before
the start of the phase completion step for the current phase.

\pnum
\returns
The constructed \tcode{arrival_token} object.

\pnum
\throws
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
Any of the error conditions
allowed for mutex types\iref{thread.mutex.requirements.mutex}.

\pnum
\begin{note}
This call can cause the completion step for the current phase to start.
\end{note}
\end{itemdescr}

\indexlibrarymember{wait}{barrier}%
\begin{itemdecl}
void wait(arrival_token&& arrival) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{arrival} is associated with
the phase synchronization point for the current phase or
the immediately preceding phase of the same barrier object.

\pnum
\indextext{block (execution)}%
\effects
Blocks at the synchronization point associated with \tcode{std::move(arrival)}
until the phase completion step of the synchronization point's phase is run.
\begin{note}
If \tcode{arrival} is associated with the synchronization point
for a previous phase, the call returns immediately.
\end{note}

\pnum
\throws
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
Any of the error conditions
allowed for mutex types\iref{thread.mutex.requirements.mutex}.
\end{itemdescr}

\indexlibrarymember{arrive_and_wait}{barrier}%
\begin{itemdecl}
void arrive_and_wait();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{wait(arrive())}.
\end{itemdescr}

\indexlibrarymember{arrive_and_drop}{barrier}%
\begin{itemdecl}
void arrive_and_drop();
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The expected count for the current barrier phase is greater than zero.

\pnum
\effects
Decrements the initial expected count for all subsequent phases by one.
Then decrements the expected count for the current phase by one.

\pnum
\sync
The call to \tcode{arrive_and_drop} strongly happens before
the start of the phase completion step for the current phase.

\pnum
\throws
\tcode{system_error} when an exception is required\iref{thread.req.exception}.

\pnum
\errors
Any of the error conditions
allowed for mutex types\iref{thread.mutex.requirements.mutex}.

\pnum
\begin{note}
This call can cause the completion step for the current phase to start.
\end{note}
\end{itemdescr}

\rSec1[futures]{Futures}

\rSec2[futures.overview]{Overview}

\pnum
\ref{futures} describes components that a \Cpp{} program can use to retrieve in one thread the
result (value or exception) from a function that has run in the same thread or another thread.
\begin{note}
These components are not restricted to multi-threaded programs but can be useful in
single-threaded programs as well.
\end{note}

\rSec2[future.syn]{Header \tcode{<future>} synopsis}

\indexheader{future}%
\begin{codeblock}
namespace std {
  enum class @\libglobal{future_errc}@ {
    @\libmember{broken_promise}{future_errc}@ = @\impdefx{value of \tcode{future_errc::broken_promise}}@,
    @\libmember{future_already_retrieved}{future_errc}@ = @\impdefx{value of \tcode{future_errc::future_already_retrieved}}@,
    @\libmember{promise_already_satisfied}{future_errc}@ = @\impdefx{value of \tcode{future_errc::promise_already_satisfied}}@,
    @\libmember{no_state}{future_errc}@ = @\impdefx{value of \tcode{future_errc::no_state}}@
  };

  enum class @\libglobal{launch}@ : @\unspec{}@ {
    @\libmember{async}{launch}@ = @\unspec{}@,
    @\libmember{deferred}{launch}@ = @\unspec{}@,
    @\impdefx{last enumerator of \tcode{launch}}@
  };

  enum class @\libglobal{future_status}@ {
    @\libmember{ready}{future_status}@,
    @\libmember{timeout}{future_status}@,
    @\libmember{deferred}{future_status}@
  };

  // \ref{futures.errors}, error handling
  template<> struct is_error_code_enum<future_errc> : public true_type { };
  error_code make_error_code(future_errc e) noexcept;
  error_condition make_error_condition(future_errc e) noexcept;

  const error_category& future_category() noexcept;

  // \ref{futures.future.error}, class \tcode{future_error}
  class future_error;

  // \ref{futures.promise}, class template \tcode{promise}
  template<class R> class promise;
  template<class R> class promise<R&>;
  template<> class promise<void>;

  template<class R>
    void swap(promise<R>& x, promise<R>& y) noexcept;

  // \ref{futures.unique.future}, class template \tcode{future}
  template<class R> class future;
  template<class R> class future<R&>;
  template<> class future<void>;

  // \ref{futures.shared.future}, class template \tcode{shared_future}
  template<class R> class shared_future;
  template<class R> class shared_future<R&>;
  template<> class shared_future<void>;

  // \ref{futures.task}, class template \tcode{packaged_task}
  template<class> class packaged_task;  // \notdef
  template<class R, class... ArgTypes>
    class packaged_task<R(ArgTypes...)>;

  template<class R, class... ArgTypes>
    void swap(packaged_task<R(ArgTypes...)>&, packaged_task<R(ArgTypes...)>&) noexcept;

  // \ref{futures.async}, function template \tcode{async}
  template<class F, class... Args>
    future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
      async(F&& f, Args&&... args);
  template<class F, class... Args>
    future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
      async(launch policy, F&& f, Args&&... args);
}
\end{codeblock}

\pnum
The \keyword{enum} type \tcode{launch} is a bitmask type\iref{bitmask.types} with
elements \tcode{launch::async} and \tcode{launch::deferred}.
\begin{note}
Implementations can provide bitmasks to specify restrictions on task
interaction by functions launched by \tcode{async()} applicable to a
corresponding subset of available launch policies. Implementations can extend
the behavior of the first overload of \tcode{async()} by adding their extensions
to the launch policy under the ``as if'' rule.
\end{note}

\pnum
The enum values of \tcode{future_errc} are distinct and not zero.

\rSec2[futures.errors]{Error handling}

\indexlibraryglobal{future_category}%
\begin{itemdecl}
const error_category& future_category() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A reference to an object of a type derived from class \tcode{error_category}.

\pnum
The object's \tcode{default_error_condition} and \tcode{equivalent} virtual functions shall
behave as specified for the class \tcode{error_category}. The object's \tcode{name}
virtual function returns a pointer to the string \tcode{"future"}.
\end{itemdescr}

\indexlibrarymember{make_error_code}{future_errc}%
\begin{itemdecl}
error_code make_error_code(future_errc e) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{error_code(static_cast<int>(e), future_category())}.
\end{itemdescr}

\indexlibrarymember{make_error_condition}{future_errc}%
\begin{itemdecl}
error_condition make_error_condition(future_errc e) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{error_condition(static_cast<int>(e), future_category())}.
\end{itemdescr}

\rSec2[futures.future.error]{Class \tcode{future_error}}

\indexlibraryglobal{future_error}%
\begin{codeblock}
namespace std {
  class future_error : public logic_error {
  public:
    explicit future_error(future_errc e);

    const error_code& code() const noexcept;
    const char*       what() const noexcept;

  private:
    error_code ec_;             // \expos
  };
}
\end{codeblock}

\indexlibraryctor{future_error}%
\begin{itemdecl}
explicit future_error(future_errc e);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{ec_} with \tcode{make_error_code(e)}.
\end{itemdescr}

\indexlibrarymember{code}{future_error}%
\begin{itemdecl}
const error_code& code() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ec_}.
\end{itemdescr}

\indexlibrarymember{what}{future_error}%
\begin{itemdecl}
const char* what() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An \ntbs{} incorporating \tcode{code().message()}.
\end{itemdescr}

\rSec2[futures.state]{Shared state}

\pnum
Many of the classes introduced in subclause~\ref{futures} use some state to communicate results. This
\indextext{shared state|see{future, shared state}}
\defnx{shared state}{future!shared state} consists of some state information and some (possibly not
yet evaluated) \term{result}, which can be a (possibly void) value or an exception.
\begin{note}
Futures, promises, and tasks defined in this Clause reference such shared state.
\end{note}

\pnum
\begin{note}
The result can be any kind of object including a function to compute that result,
as used by \tcode{async} when \tcode{policy} is \tcode{launch::deferred}.
\end{note}

\pnum
An \defn{asynchronous return object} is an object that reads results from a
shared state. A \defnadj{waiting}{function} of an asynchronous return object is one
that potentially blocks to wait for the shared state to be made
ready.
If a waiting function can return before the state is made ready because of a
timeout\iref{thread.req.lockable}, then it is a \term{timed waiting function}, otherwise
it is a \term{non-timed waiting function}.

\pnum
An \defn{asynchronous provider} is an object that provides a result to a shared
state.
The result of a shared state is set by
respective functions on the asynchronous provider.
\begin{example}
Promises and tasks are examples of asynchronous providers.
\end{example}
The means of setting the result of a shared state is specified
in the description of those classes and functions that create such a state object.

\pnum
When an asynchronous return object or an asynchronous provider is said to release its
shared state, it means:
\begin{itemize}
\item
if the return object or provider holds the last reference to its shared state,
the shared state is destroyed; and

\item
the return object or provider gives up its reference to its shared state; and

\item these actions will not block for the shared state to become ready, except that it
may block if all of the following are true: the shared state was created by a call to
\tcode{std::async}, the shared state is not yet ready, and this was the last reference
to the shared state.
\end{itemize}

\pnum
When an asynchronous provider is said to make its shared state ready, it means:
\begin{itemize}
\item
first, the provider marks its shared state as ready; and
\item
second, the provider unblocks any execution agents waiting for its shared
state to become ready.
\end{itemize}

\pnum
When an asynchronous provider is said to abandon its shared state, it means:
\begin{itemize}
\item
first, if that state is not ready, the provider
\begin{itemize}
\item
stores an exception object of type \tcode{future_error} with an error condition of
\tcode{broken_promise} within its shared state; and then
\item
makes its shared state ready;
\end{itemize}
\item
second, the provider releases its shared state.
\end{itemize}

\pnum
A shared state is \defn{ready} only if it holds a value or an exception ready for
retrieval.
Waiting for a shared state to become ready may invoke code to compute the result on
the waiting thread if so specified in the description of the class or function that creates
the state object.

\pnum
Calls to functions that successfully set the stored result of a shared
state synchronize
with\iref{intro.multithread} calls to functions
successfully detecting the ready state resulting from that setting.
The storage of the result
(whether normal or exceptional) into the shared state
synchronizes with\iref{intro.multithread}
the successful return from a call to a waiting function on the shared state.

\pnum
Some functions (e.g., \tcode{promise::set_value_at_thread_exit}) delay making
the shared state ready until the calling thread exits. The destruction of
each of that thread's objects with thread storage duration\iref{basic.stc.thread}
is sequenced before making that shared state ready.

\pnum
Access to the result of the same shared state may conflict\iref{intro.multithread}.
\begin{note}
This explicitly specifies that the result of the shared state is
visible in the objects that reference this state in the sense of data race
avoidance\iref{res.on.data.races}. For example, concurrent accesses through
references returned by \tcode{shared_future::get()}\iref{futures.shared.future}
must either use read-only operations or provide additional synchronization.
\end{note}

\rSec2[futures.promise]{Class template \tcode{promise}}

\indexlibraryglobal{promise}%
\begin{codeblock}
namespace std {
  template<class R>
  class promise {
  public:
    promise();
    template<class Allocator>
      promise(allocator_arg_t, const Allocator& a);
    promise(promise&& rhs) noexcept;
    promise(const promise&) = delete;
    ~promise();

    // assignment
    promise& operator=(promise&& rhs) noexcept;
    promise& operator=(const promise&) = delete;
    void swap(promise& other) noexcept;

    // retrieving the result
    future<R> get_future();

    // setting the result
    void set_value(@\seebelow@);
    void set_exception(exception_ptr p);

    // setting the result with deferred notification
    void set_value_at_thread_exit(@\seebelow@);
    void set_exception_at_thread_exit(exception_ptr p);
  };
}
\end{codeblock}

\pnum
For the primary template, \tcode{R} shall be an object type that
meets the \oldconcept{Destructible} requirements.

\pnum
The implementation provides the template \tcode{promise} and two specializations,
\tcode{promise<R\&>} and \tcode{promise<\brk{}void>}. These differ only in the argument type
of the member functions \tcode{set_value} and \tcode{set_value_at_thread_exit},
as set out in their descriptions, below.

\pnum
The \tcode{set_value}, \tcode{set_exception}, \tcode{set_value_at_thread_exit},
and \tcode{set_exception_at_thread_exit} member functions behave as though
they acquire a single mutex associated with the promise object while updating the
promise object.

\indexlibraryctor{promise}%
\begin{itemdecl}
promise();
template<class Allocator>
  promise(allocator_arg_t, const Allocator& a);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Creates a shared state. The second
constructor uses the allocator \tcode{a} to allocate memory for the shared
state.
\end{itemdescr}

\indexlibraryctor{promise}%
\begin{itemdecl}
promise(promise&& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Transfers ownership of the shared state
of \tcode{rhs} (if any) to the newly-constructed object.

\pnum
\ensures
\tcode{rhs} has no shared state.
\end{itemdescr}

\indexlibrarydtor{promise}%
\begin{itemdecl}
~promise();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Abandons any shared state\iref{futures.state}.
\end{itemdescr}

\indexlibrarymember{operator=}{promise}%
\begin{itemdecl}
promise& operator=(promise&& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Abandons any shared state\iref{futures.state} and then as if
\tcode{promise(std::move(rhs)).swap(*this)}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{swap}{promise}%
\begin{itemdecl}
void swap(promise& other) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Exchanges the shared state of \tcode{*this} and \tcode{other}.

\pnum
\ensures
\tcode{*this} has the shared state (if any) that \tcode{other} had
prior to the call to \tcode{swap}. \tcode{other} has the shared state (if any) that
\tcode{*this} had prior to the call to \tcode{swap}.
\end{itemdescr}

\indexlibrarymember{get_future}{promise}%
\begin{itemdecl}
future<R> get_future();
\end{itemdecl}

\begin{itemdescr}
\pnum
\sync
Calls to this function do not introduce
data races~\iref{intro.multithread} with calls to
\tcode{set_value},
\tcode{set_exception},
\tcode{set_value_at_thread_exit}, or
\tcode{set_exception_at_thread_exit}.
\begin{note}
Such calls need not synchronize with each other.
\end{note}

\pnum
\returns
A \tcode{future<R>} object with the same shared state as
\tcode{*this}.

\pnum
\throws
\tcode{future_error} if \tcode{*this} has no shared state or if
\tcode{get_future} has already been called on a \tcode{promise} with the same
shared state as \tcode{*this}.

\pnum
\errors

\begin{itemize}
\item \tcode{future_already_retrieved} if \tcode{get_future} has already been called on
a \tcode{promise} with the same shared state as \tcode{*this}.

\item \tcode{no_state} if \tcode{*this} has no shared state.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{set_value}{promise}%
\begin{itemdecl}
void promise::set_value(const R& r);
void promise::set_value(R&& r);
void promise<R&>::set_value(R& r);
void promise<void>::set_value();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Atomically stores the value \tcode{r} in the shared state and
makes that state ready\iref{futures.state}.

\pnum
\throws
\begin{itemize}
\item \tcode{future_error} if its shared state
already has a stored value or exception, or
\item for the first version, any exception thrown by the constructor selected to copy an object of \tcode{R}, or
\item for the second version, any exception thrown by the constructor selected to move an object of \tcode{R}.
\end{itemize}

\pnum
\errors
\begin{itemize}
\item \tcode{promise_already_satisfied} if its shared state
already has a stored value or exception.
\item \tcode{no_state} if \tcode{*this} has no shared state.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{set_exception}{promise}%
\begin{itemdecl}
void set_exception(exception_ptr p);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{p} is not null.

\pnum
\effects
Atomically stores the exception pointer \tcode{p} in the shared state
and makes that state ready\iref{futures.state}.

\pnum
\throws
\tcode{future_error} if its shared state
already has a stored value or exception.

\pnum
\errors

\begin{itemize}
\item \tcode{promise_already_satisfied} if its shared state
already has a stored value or exception.
\item \tcode{no_state} if \tcode{*this} has no shared state.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{set_value_at_thread_exit}{promise}%
\begin{itemdecl}
void promise::set_value_at_thread_exit(const R& r);
void promise::set_value_at_thread_exit(R&& r);
void promise<R&>::set_value_at_thread_exit(R& r);
void promise<void>::set_value_at_thread_exit();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Stores the value \tcode{r} in the shared state without making that
state ready immediately. Schedules that state to be made ready when the current
thread exits, after all objects with thread storage duration associated with the
current thread have been destroyed.

\pnum
\throws
\begin{itemize}
\item \tcode{future_error} if its shared state
already has a stored value or exception, or
\item for the first version, any exception thrown by the constructor selected to copy an object of \tcode{R}, or
\item for the second version, any exception thrown by the constructor selected to move an object of \tcode{R}.
\end{itemize}

\pnum
\errors
\begin{itemize}
\item \tcode{promise_already_satisfied} if its shared state
already has a stored value or exception.
\item \tcode{no_state} if \tcode{*this} has no shared state.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{set_exception_at_thread_exit}{promise}%
\begin{itemdecl}
void set_exception_at_thread_exit(exception_ptr p);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{p} is not null.

\pnum
\effects
Stores the exception pointer \tcode{p} in the shared state without
making that state ready immediately. Schedules that state to be made ready when
the current thread exits, after all objects with thread storage duration
associated with the current thread have been destroyed.

\pnum
\throws
\tcode{future_error} if an error condition occurs.

\pnum
\errors
\begin{itemize}
\item \tcode{promise_already_satisfied} if its shared state
already has a stored value or exception.
\item \tcode{no_state} if \tcode{*this} has no shared state.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{swap}{promise}%
\begin{itemdecl}
template<class R>
  void swap(promise<R>& x, promise<R>& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
As if by \tcode{x.swap(y)}.
\end{itemdescr}

\rSec2[futures.unique.future]{Class template \tcode{future}}

\pnum
The class template \tcode{future} defines a type for asynchronous return objects which
do not share their shared state with other asynchronous return objects.
A default-constructed \tcode{future} object has no
shared state. A \tcode{future} object with shared state can be created by
functions on asynchronous providers\iref{futures.state} or by the move constructor
and shares its shared state with
the original asynchronous provider. The result (value or exception) of
a \tcode{future} object
can be
set by
calling a respective function on an
object that shares the same
shared state.

\pnum
\begin{note}
Member functions of \tcode{future} do not synchronize with themselves or with
member functions of \tcode{shared_future}.
\end{note}

\pnum
The effect of calling any member function other than the destructor, the
move assignment operator, \tcode{share}, or \tcode{valid} on a \tcode{future} object for which
\tcode{valid() == false}
is undefined.
\begin{note}
It is valid to move from a future object for which \tcode{valid() == false}.
\end{note}

\recommended
Implementations should detect this case and throw an object of type
\tcode{future_error} with an error condition of \tcode{future_errc::no_state}.

\indexlibraryglobal{future}%
\begin{codeblock}
namespace std {
  template<class R>
  class future {
  public:
    future() noexcept;
    future(future&&) noexcept;
    future(const future&) = delete;
    ~future();
    future& operator=(const future&) = delete;
    future& operator=(future&&) noexcept;
    shared_future<R> share() noexcept;

    // retrieving the value
    @\seebelow@ get();

    // functions to check state
    bool valid() const noexcept;

    void wait() const;
    template<class Rep, class Period>
      future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
    template<class Clock, class Duration>
      future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
  };
}
\end{codeblock}

\pnum
For the primary template, \tcode{R} shall be an object type that
meets the \oldconcept{Destructible} requirements.

\pnum
The implementation provides the template \tcode{future} and two specializations,
\tcode{future<R\&>} and \tcode{future<\brk{}void>}. These differ only in the return type and return
value of the member function \tcode{get}, as set out in its description, below.

\indexlibraryctor{future}%
\begin{itemdecl}
future() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The object does not refer to a shared state.

\pnum
\ensures
\tcode{valid() == false}.
\end{itemdescr}

\indexlibraryctor{future}%
\begin{itemdecl}
future(future&& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Move constructs a \tcode{future} object that refers to the shared
state that
was originally referred to by \tcode{rhs} (if any).

\pnum
\ensures
\begin{itemize}
\item \tcode{valid()} returns the same value as \tcode{rhs.valid()} prior to the
constructor invocation.
\item \tcode{rhs.valid() == false}.
\end{itemize}
\end{itemdescr}

\indexlibraryctor{future}%
\begin{itemdecl}
~future();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\begin{itemize}
\item
Releases any shared state\iref{futures.state};
\item
destroys \tcode{*this}.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{operator=}{future}%
\begin{itemdecl}
future& operator=(future&& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{addressof(rhs) == this} is \tcode{true}, there are no effects.
Otherwise:
\begin{itemize}
\item
Releases any shared state\iref{futures.state}.
\item
move assigns the contents of \tcode{rhs} to \tcode{*this}.
\end{itemize}

\pnum
\ensures
\begin{itemize}
\item
\tcode{valid()} returns the same value as \tcode{rhs.valid()} prior to the
assignment.

\item
If \tcode{addressof(rhs) == this} is \tcode{false},
\tcode{rhs.valid() == false}.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{share}{future}%
\begin{itemdecl}
shared_future<R> share() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{valid() == false}.

\pnum
\returns
\tcode{shared_future<R>(std::move(*this))}.
\end{itemdescr}

\indexlibrarymember{get}{future}%
\begin{itemdecl}
R future::get();
R& future<R&>::get();
void future<void>::get();
\end{itemdecl}

\begin{itemdescr}
\pnum
\begin{note}
As described above, the template and its two required specializations differ only in
the return type and return value of the member function \tcode{get}.
\end{note}

\pnum
\effects
\begin{itemize}
\item \tcode{wait()}{s} until the shared state is ready, then retrieves the
value stored in the shared state;
\item releases any shared state\iref{futures.state}.
\end{itemize}

\pnum
\ensures
\tcode{valid() == false}.

\pnum
\returns
\begin{itemize}
\item
\tcode{future::get()} returns the value \tcode{v} stored in the object's shared state as
\tcode{std::move(v)}.

\item
\tcode{future<R\&>::get()} returns the reference stored as value in the object's shared state.

\item
\tcode{future<void>::get()} returns nothing.
\end{itemize}

\pnum
\throws
The stored exception, if an exception was stored in the shared state.
\end{itemdescr}

\indexlibrarymember{valid}{future}%
\begin{itemdecl}
bool valid() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} only if \tcode{*this} refers to a shared state.
\end{itemdescr}

\indexlibrarymember{wait}{future}%
\begin{itemdecl}
void wait() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\indextext{block (execution)}%
\effects
Blocks until the shared state is ready.
\end{itemdescr}

\indexlibrarymember{wait_for}{future}%
\begin{itemdecl}
template<class Rep, class Period>
  future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\indextext{block (execution)}%
\effects
None if the shared state contains a deferred function\iref{futures.async},
otherwise
blocks until the shared state is ready or until
the relative timeout\iref{thread.req.timing} specified by \tcode{rel_time} has expired.

\pnum
\returns

\begin{itemize}
\item \tcode{future_status::deferred} if the shared state contains a deferred
function.

\item \tcode{future_status::ready} if the shared state is ready.

\item \tcode{future_status::timeout} if the function is returning because the
relative timeout\iref{thread.req.timing}
specified by \tcode{rel_time} has expired.
\end{itemize}

\pnum
\throws
timeout-related exceptions\iref{thread.req.timing}.
\end{itemdescr}

\indexlibrarymember{wait_until}{future}%
\begin{itemdecl}
template<class Clock, class Duration>
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\indextext{block (execution)}%
\effects
None if the shared state contains a deferred function\iref{futures.async},
otherwise
blocks until the shared state is ready or until
the absolute timeout\iref{thread.req.timing} specified by \tcode{abs_time} has expired.

\pnum
\returns

\begin{itemize}
\item \tcode{future_status::deferred} if the shared state contains a deferred
function.

\item \tcode{future_status::ready} if the shared state is ready.

\item \tcode{future_status::timeout} if the function is returning because the
absolute timeout\iref{thread.req.timing}
specified by \tcode{abs_time} has expired.
\end{itemize}

\pnum
\throws
timeout-related exceptions\iref{thread.req.timing}.
\end{itemdescr}


\rSec2[futures.shared.future]{Class template \tcode{shared_future}}

\pnum
The class template \tcode{shared_future} defines a type for asynchronous return objects
which may share their shared state with other asynchronous return
objects. A default-constructed \tcode{shared_future}
object has no shared state. A \tcode{shared_future} object with
shared state can
be created
by conversion from a \tcode{future} object and shares its shared state with the
original asynchronous provider\iref{futures.state} of the shared state.
The result (value or exception) of a \tcode{shared_future} object
can be set by
calling a respective function on an
object that shares the same shared state.

\pnum
\begin{note}
Member functions of \tcode{shared_future} do not synchronize with themselves,
but they synchronize with the shared state.
\end{note}

\pnum
The effect of calling any member function other than the destructor,
the move assignment operator, the copy assignment operator, or
\tcode{valid()} on a \tcode{shared_future} object for which \tcode{valid() == false} is undefined.
\begin{note}
It is valid to copy or move from a \tcode{shared_future}
object for which \tcode{valid()} is \tcode{false}.
\end{note}

\recommended
Implementations should detect this case and throw an object of type
\tcode{future_error} with an error condition of \tcode{future_errc::no_state}.

\indexlibraryglobal{shared_future}%
\begin{codeblock}
namespace std {
  template<class R>
  class shared_future {
  public:
    shared_future() noexcept;
    shared_future(const shared_future& rhs) noexcept;
    shared_future(future<R>&&) noexcept;
    shared_future(shared_future&& rhs) noexcept;
    ~shared_future();
    shared_future& operator=(const shared_future& rhs) noexcept;
    shared_future& operator=(shared_future&& rhs) noexcept;

    // retrieving the value
    @\seebelow@ get() const;

    // functions to check state
    bool valid() const noexcept;

    void wait() const;
    template<class Rep, class Period>
      future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
    template<class Clock, class Duration>
      future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
  };
}
\end{codeblock}

\pnum
For the primary template, \tcode{R} shall be an object type that
meets the \oldconcept{Destructible} requirements.

\pnum
The implementation provides the template \tcode{shared_future} and two
specializations, \tcode{shared_future<R\&>} and \tcode{shared_future<void>}. These
differ only in the return type and return value of the member function \tcode{get}, as
set out in its description, below.

\indexlibraryctor{shared_future}%
\begin{itemdecl}
shared_future() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The object does not refer to a shared state.

\pnum
\ensures
\tcode{valid() == false}.
\end{itemdescr}

\indexlibraryctor{shared_future}%
\begin{itemdecl}
shared_future(const shared_future& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The object refers to the same
shared state as \tcode{rhs} (if any).

\pnum
\ensures
\tcode{valid()} returns the same value as \tcode{rhs.valid()}.
\end{itemdescr}

\indexlibraryctor{shared_future}%
\begin{itemdecl}
shared_future(future<R>&& rhs) noexcept;
shared_future(shared_future&& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Move constructs a \tcode{shared_future} object that refers to the
shared state that was originally referred to by \tcode{rhs} (if any).

\pnum
\ensures
\begin{itemize}
\item \tcode{valid()} returns the same value as \tcode{rhs.valid()} returned prior to
the constructor invocation.
\item \tcode{rhs.valid() == false}.
\end{itemize}
\end{itemdescr}

\indexlibrarydtor{shared_future}%
\begin{itemdecl}
~shared_future();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\begin{itemize}
\item
Releases any shared state\iref{futures.state};
\item
destroys \tcode{*this}.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{operator=}{shared_future}%
\begin{itemdecl}
shared_future& operator=(shared_future&& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{addressof(rhs) == this} is \tcode{true}, there are no effects.
Otherwise:
\begin{itemize}
\item
Releases any shared state\iref{futures.state};
\item
move assigns the contents of \tcode{rhs} to \tcode{*this}.
\end{itemize}

\pnum
\ensures
\begin{itemize}
\item
\tcode{valid()} returns the same value as \tcode{rhs.valid()} returned prior to
the assignment.

\item
If \tcode{addressof(rhs) == this} is \tcode{false},
\tcode{rhs.valid() == false}.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{operator=}{shared_future}%
\begin{itemdecl}
shared_future& operator=(const shared_future& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{addressof(rhs) == this} is \tcode{true}, there are no effects.
Otherwise:
\begin{itemize}
\item
Releases any shared state\iref{futures.state};
\item
assigns the contents of \tcode{rhs} to \tcode{*this}.
\begin{note}
As a result,
\tcode{*this} refers to the same shared state as \tcode{rhs}
(if any).
\end{note}
\end{itemize}

\pnum
\ensures
\tcode{valid() == rhs.valid()}.
\end{itemdescr}

\indexlibrarymember{get}{shared_future}%
\begin{itemdecl}
const R& shared_future::get() const;
R& shared_future<R&>::get() const;
void shared_future<void>::get() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\begin{note}
As described above, the template and its two required specializations differ only in
the return type and return value of the member function \tcode{get}.
\end{note}

\pnum
\begin{note}
Access to a value object stored in the shared state is
unsynchronized, so operations on \tcode{R} might
introduce a data race\iref{intro.multithread}.
\end{note}

\pnum
\effects
\tcode{wait()}{s} until the shared state is ready, then retrieves the
value stored in the shared state.

\pnum
\returns
\begin{itemize}
\item
\tcode{shared_future::get()} returns a const reference to the value stored in the object's
shared state.
\begin{note}
Access through that reference after the shared state has been
destroyed produces undefined behavior; this can be avoided by not storing the reference in any
storage with a greater lifetime than the \tcode{shared_future} object that returned the
reference.
\end{note}

\item
\tcode{shared_future<R\&>::get()} returns the reference stored as value in the object's
shared state.

\item
\tcode{shared_future<void>::get()} returns nothing.
\end{itemize}

\pnum
\throws
The stored exception, if an exception was stored in the shared state.
\end{itemdescr}

\indexlibrarymember{valid}{shared_future}%
\begin{itemdecl}
bool valid() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} only if \tcode{*this} refers to a shared state.
\end{itemdescr}

\indexlibrarymember{wait}{shared_future}%
\begin{itemdecl}
void wait() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\indextext{block (execution)}%
\effects
Blocks until the shared state is ready.
\end{itemdescr}

\indexlibrarymember{wait_for}{shared_future}%
\begin{itemdecl}
template<class Rep, class Period>
  future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\indextext{block (execution)}%
\effects
None if the shared state contains a deferred function\iref{futures.async},
otherwise
blocks until the shared state is ready or until
the relative timeout\iref{thread.req.timing} specified by
\tcode{rel_time} has expired.

\pnum
\returns

\begin{itemize}
\item \tcode{future_status::deferred} if the shared state contains a deferred
function.

\item \tcode{future_status::ready} if the shared state is ready.

\item \tcode{future_status::timeout} if the function is returning because the
relative timeout\iref{thread.req.timing}
specified by \tcode{rel_time} has expired.
\end{itemize}

\pnum
\throws
timeout-related exceptions\iref{thread.req.timing}.
\end{itemdescr}

\indexlibrarymember{wait_until}{shared_future}%
\begin{itemdecl}
template<class Clock, class Duration>
  future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\indextext{block (execution)}%
\effects
None if the shared state contains a deferred function\iref{futures.async},
otherwise
blocks until the shared state is ready or until the
absolute timeout\iref{thread.req.timing} specified by
\tcode{abs_time} has expired.

\pnum
\returns

\begin{itemize}
\item \tcode{future_status::deferred} if the shared state contains a deferred
function.

\item \tcode{future_status::ready} if the shared state is ready.

\item \tcode{future_status::timeout} if the function is returning because the
absolute timeout\iref{thread.req.timing}
specified by \tcode{abs_time} has expired.
\end{itemize}

\pnum
\throws
timeout-related exceptions\iref{thread.req.timing}.
\end{itemdescr}

\rSec2[futures.async]{Function template \tcode{async}}

\pnum
The function template \tcode{async} provides a mechanism to launch a function potentially
in a new thread and provides the result of the function in a \tcode{future} object with which
it shares a shared state.

\indexlibraryglobal{async}%
\begin{itemdecl}
template<class F, class... Args>
  future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
    async(F&& f, Args&&... args);
template<class F, class... Args>
  future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
    async(launch policy, F&& f, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
The following are all \tcode{true}:
\begin{itemize}
\item \tcode{is_constructible_v<decay_t<F>, F>},
\item \tcode{(is_constructible_v<decay_t<Args>, Args> \&\& ...)}, and
\item \tcode{is_invocable_v<decay_t<F>, decay_t<Args>...>}.
\end{itemize}

\pnum
\effects
The first function
behaves the same as a call to the second function with a \tcode{policy} argument of
\tcode{launch::async | launch::deferred}
and the same arguments for \tcode{F} and \tcode{Args}.
The second function creates a shared state that is associated with
the returned \tcode{future} object.
The further behavior
of the second function depends on the \tcode{policy} argument as follows (if
more than one of these conditions applies, the implementation may choose any of
the corresponding policies):

\begin{itemize}
\item
If \tcode{launch::async} is set in \tcode{policy}, calls
\tcode{invoke(auto(std::forward<F>(f)), auto(std::for\-ward<Args>(args))...)}\iref{func.invoke,thread.thread.constr}
as if in a new thread of execution represented by a \tcode{thread} object
with the values produced by \tcode{auto}
being materialized\iref{conv.rval} in the thread that called \tcode{async}.
Any return value
is stored as the result in the
shared state. Any exception propagated from
the execution of
\tcode{invoke(auto(std::forward<F>(f)), auto(std::forward<Args>(args))...)}
is stored as the exceptional result in the shared state.
The \tcode{thread} object is
stored in the shared state
and affects the behavior of any asynchronous return objects that
reference that state.

\item
If \tcode{launch::deferred} is set in \tcode{policy},
stores \tcode{auto(std::forward<F>(f))} and
\tcode{auto(std::for\-ward<Args>(args))...}
in the shared state. These copies of \tcode{f} and \tcode{args} constitute
a \defnadj{deferred}{function}. Invocation of the deferred function evaluates
\tcode{invoke(std::move(g), std::move(xyz))} where \tcode{g} is the stored value of
\tcode{auto(std::forward<F>(f))} and \tcode{xyz} is the stored copy of
\tcode{auto(std::forward<Args>(args))...}.
Any return value is stored
as the result in the shared state.
Any exception propagated
from the execution
of the deferred function
is stored as the exceptional result
in the shared state.
The shared state is not
made ready until the function has completed. The first call to a
non-timed waiting function\iref{futures.state}
on an asynchronous return object referring to
this shared state invokes the
deferred function in the thread that called the waiting function.
Once evaluation of \tcode{invoke(std::move(g), std::move(xyz))} begins, the function is no longer
considered deferred.

 \recommended
If this policy is specified together with other policies, such as when using a
\tcode{policy} value of \tcode{launch::async | launch::deferred}, implementations should defer
invocation or the selection of the policy when no more concurrency can be effectively
exploited.

\item
If no value is set in the launch policy, or a value is set that is neither specified
in this document nor by the implementation, the behavior is undefined.
\end{itemize}

\pnum
\sync
The invocation of \tcode{async} synchronizes with the invocation of \tcode{f}.
The completion of the function \tcode{f} is sequenced before
the shared state is made ready.
\begin{note}
These apply regardless of the provided \tcode{policy} argument, and
even if the corresponding \tcode{future} object is moved to another thread.
However, it is possible for \tcode{f} not to be called at all,
in which case its completion never happens.
\end{note}

If the implementation chooses the \tcode{launch::async} policy,
\begin{itemize}
\item
a call to a waiting function on an asynchronous return
object that shares the shared state created by this \tcode{async} call shall
block until the associated thread has completed, as if joined, or else time
out\iref{thread.thread.member};
\item
the associated thread completion
synchronizes with\iref{intro.multithread}
the return from
the first function
that successfully detects the ready status of the shared state or
with the return from the last
function that releases the shared state, whichever
happens first.
\end{itemize}

\pnum
\returns
An object of type
\tcode{future<invoke_result_t<decay_t<F>, decay_t<Args>...>>} that refers
to the shared state created by this call to \tcode{async}.
\begin{note}
If a future obtained from \tcode{async} is moved outside the local scope,
the future's destructor can block for the shared state to become ready.
\end{note}

\pnum
\throws
\tcode{system_error} if \tcode{policy == launch::async} and the
implementation is unable to start a new thread, or
\tcode{std::bad_alloc} if memory for the internal data structures
cannot be allocated.

\pnum
\errors
\begin{itemize}
\item \tcode{resource_unavailable_try_again} --- if
\tcode{policy == launch::async} and the system is unable to start a new thread.
\end{itemize}
\end{itemdescr}

\pnum
\begin{example}
\begin{codeblock}
int work1(int value);
int work2(int value);
int work(int value) {
  auto handle = std::async([=]{ return work2(value); });
  int tmp = work1(value);
  return tmp + handle.get();    // \#1
}
\end{codeblock}

\begin{note}
Line \#1 might not result in concurrency because
the \tcode{async} call uses the default policy, which might use
\tcode{launch::deferred}, in which case the lambda might not be invoked until the
\tcode{get()} call; in that case, \tcode{work1} and \tcode{work2} are called on the
same thread and there is no concurrency.
\end{note}
\end{example}

\rSec2[futures.task]{Class template \tcode{packaged_task}}

\rSec3[futures.task.general]{General}

\pnum
The class template \tcode{packaged_task} defines a type for wrapping a function or
callable object so that the return value of the function or callable object is stored in
a future when it is invoked.

\pnum
When the \tcode{packaged_task} object is invoked, its stored task is invoked and the
result (whether normal or exceptional) stored in the shared state. Any futures that
share the shared state will then be able to access the stored result.

\indexlibraryglobal{packaged_task}%
\begin{codeblock}
namespace std {
  template<class> class packaged_task;  // \notdef

  template<class R, class... ArgTypes>
  class packaged_task<R(ArgTypes...)> {
  public:
    // construction and destruction
    packaged_task() noexcept;
    template<class F>
      explicit packaged_task(F&& f);
    template<class F, class Allocator>
      explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
    ~packaged_task();

    // no copy
    packaged_task(const packaged_task&) = delete;
    packaged_task& operator=(const packaged_task&) = delete;

    // move support
    packaged_task(packaged_task&& rhs) noexcept;
    packaged_task& operator=(packaged_task&& rhs) noexcept;
    void swap(packaged_task& other) noexcept;

    bool valid() const noexcept;

    // result retrieval
    future<R> get_future();

    // execution
    void operator()(ArgTypes... );
    void make_ready_at_thread_exit(ArgTypes...);

    void reset();
  };

  template<class R, class... ArgTypes>
    packaged_task(R (*)(ArgTypes...)) -> packaged_task<R(ArgTypes...)>;

  template<class F> packaged_task(F) -> packaged_task<@\seebelow@>;
}
\end{codeblock}

\rSec3[futures.task.members]{Member functions}

\indexlibraryctor{packaged_task}%
\begin{itemdecl}
packaged_task() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
The object has no shared state and no stored task.
\end{itemdescr}

\indexlibraryctor{packaged_task}%
\begin{itemdecl}
template<class F>
  explicit packaged_task(F&& f);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to
\tcode{packaged_task(allocator_arg, allocator<int>(), std::forward<F>(f))}.
\end{itemdescr}

\indexlibraryctor{packaged_task}%
\begin{itemdecl}
template<class F, class Allocator>
  explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{remove_cvref_t<F>}
is not the same type as \tcode{packaged_task<R(ArgTypes...)>}.

\pnum
\mandates
\tcode{is_invocable_r_v<R, decay_t<F>\&, ArgTypes...>} is \tcode{true}.

\pnum
\expects
\tcode{Allocator} meets the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}.

\pnum
\effects
Let \tcode{A2} be
\tcode{allocator_traits<Allocator>::rebind_alloc<\unspec>}
and let \tcode{a2} be an object of type \tcode{A2} initialized with
\tcode{A2(a)}.
Constructs a new \tcode{packaged_task} object with
a stored task of type \tcode{decay_t<F>} and a shared state.
Initializes the object's stored task with \tcode{std::forward<F>(f)}.
Uses \tcode{a2} to allocate storage for the shared state and stores a copy
of \tcode{a2} in the shared state.

\pnum
\throws
Any exceptions thrown by the initialization of the stored task.
If storage for the shared state cannot be allocated, any exception thrown by
\tcode{A2::allocate}.
\end{itemdescr}

\indexlibraryctor{packaged_task}%
\begin{itemdecl}
template<class F> packaged_task(F) -> packaged_task<@\seebelow@>;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{\&F::operator()} is well-formed when
treated as an unevaluated operand\iref{term.unevaluated.operand} and either
\begin{itemize}
\item
\tcode{F::operator()} is a non-static member function and
\tcode{decltype(\brk{}\&F::operator())} is either of the form
\tcode{R(G::*)(A...)}~\cv{}~\tcode{\opt{\&}~\opt{noexcept}}
or of the form
\tcode{R(*)(G, A...)~\opt{noexcept}}
for a type \tcode{G}, or
\item
\tcode{F::operator()} is a static member function and
\tcode{decltype(\&F::operator())} is of the form
\tcode{R(*)(A...) \opt{noexcept}}.
\end{itemize}

\pnum
\remarks
The deduced type is \tcode{packaged_task<R(A...)>}.
\end{itemdescr}

\indexlibraryctor{packaged_task}%
\begin{itemdecl}
packaged_task(packaged_task&& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Transfers ownership of
\tcode{rhs}'s shared state to \tcode{*this}, leaving \tcode{rhs} with no
shared state. Moves the stored task from \tcode{rhs} to \tcode{*this}.

\pnum
\ensures
\tcode{rhs} has no shared state.
\end{itemdescr}

\indexlibrarymember{operator=}{packaged_task}%
\begin{itemdecl}
packaged_task& operator=(packaged_task&& rhs) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\begin{itemize}
\item
Releases any shared state\iref{futures.state};
\item
calls \tcode{packaged_task(std::move(rhs)).swap(*this)}.
\end{itemize}
\end{itemdescr}

\indexlibrarydtor{packaged_task}%
\begin{itemdecl}
~packaged_task();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Abandons any shared state\iref{futures.state}.
\end{itemdescr}

\indexlibrarymember{swap}{packaged_task}%
\begin{itemdecl}
void swap(packaged_task& other) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Exchanges the shared states and stored tasks of \tcode{*this} and \tcode{other}.

\pnum
\ensures
\tcode{*this} has the same shared state
and stored task (if any) as \tcode{other}
prior to the call to \tcode{swap}. \tcode{other} has the same shared state
and stored task (if any)
as \tcode{*this} prior to the call to \tcode{swap}.
\end{itemdescr}

\indexlibrarymember{valid}{packaged_task}%
\begin{itemdecl}
bool valid() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} only if \tcode{*this} has a shared state.
\end{itemdescr}

\indexlibrarymember{get_future}{packaged_task}%
\begin{itemdecl}
future<R> get_future();
\end{itemdecl}

\begin{itemdescr}
\pnum
\sync
Calls to this function do not introduce
data races~\iref{intro.multithread} with calls to
\tcode{operator()} or
\tcode{make_ready_at_thread_exit}.
\begin{note}
Such calls need not synchronize with each other.
\end{note}

\pnum
\returns
A \tcode{future} object that shares the same shared state as \tcode{*this}.

\pnum
\throws
A \tcode{future_error} object if an error occurs.

\pnum
\errors
\begin{itemize}
\item \tcode{future_already_retrieved} if \tcode{get_future} has already been called on
a \tcode{packaged_task} object with the same shared state as \tcode{*this}.
\item \tcode{no_state} if \tcode{*this} has no shared state.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{operator()}{packaged_task}%
\begin{itemdecl}
void operator()(ArgTypes... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
As if by \tcode{\placeholdernc{INVOKE}<R>(f, t$_1$, t$_2$, $\dotsc$, t$_N$)}\iref{func.require},
where \tcode{f} is the
stored task of \tcode{*this} and
\tcode{t$_1$, t$_2$, $\dotsc$, t$_N$} are the values in \tcode{args...}. If the task returns normally,
the return value is stored as the asynchronous result in the shared state of
\tcode{*this}, otherwise the exception thrown by the task is stored. The
shared state of \tcode{*this} is made ready, and any threads blocked in a
function waiting for
the shared state of \tcode{*this} to become ready are unblocked.

\pnum
\throws
A \tcode{future_error} exception object if there is no shared
state or the stored task has already been invoked.

\pnum
\errors
\begin{itemize}
\item \tcode{promise_already_satisfied} if
the stored task has already been invoked.
\item \tcode{no_state} if \tcode{*this} has no shared state.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{make_ready_at_thread_exit}{packaged_task}%
\begin{itemdecl}
void make_ready_at_thread_exit(ArgTypes... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
As if by \tcode{\placeholdernc{INVOKE}<R>(f, t$_1$, t$_2$, $\dotsc$, t$_N$)}\iref{func.require},
where \tcode{f} is the stored task and
\tcode{t$_1$, t$_2$, $\dotsc$, t$_N$} are the values in \tcode{args...}. If the task returns normally,
the return value is stored as the asynchronous result in the shared state of
\tcode{*this}, otherwise the exception thrown by the task is stored. In either
case, this is done without making that state ready\iref{futures.state} immediately. Schedules
the shared state to be made ready when the current thread exits,
after all objects with thread storage duration associated with the current thread
have been destroyed.

\pnum
\throws
\tcode{future_error} if an error condition occurs.

\pnum
\errors
\begin{itemize}
\item \tcode{promise_already_satisfied} if the
stored task has already been invoked.
\item \tcode{no_state} if \tcode{*this} has no shared state.
\end{itemize}
\end{itemdescr}

\indexlibrarymember{reset}{packaged_task}%
\begin{itemdecl}
void reset();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
if (!valid()) {
  throw future_error(future_errc::no_state);
}
*this = packaged_task(allocator_arg, a, std::move(f));
\end{codeblock}
where
\tcode{f} is the task stored in
\tcode{*this} and \tcode{a} is the allocator stored in the shared state.
\begin{note}
This constructs a new shared state for \tcode{*this}. The
old state is abandoned\iref{futures.state}.
\end{note}

\pnum
\throws
\begin{itemize}
\item Any exception thrown by the \tcode{packaged_task} constructor.
\item \tcode{future_error} with an error condition of \tcode{no_state} if \tcode{*this}
has no shared state.
\end{itemize}
\end{itemdescr}

\rSec3[futures.task.nonmembers]{Globals}

\indexlibrarymember{swap}{packaged_task}%
\begin{itemdecl}
template<class R, class... ArgTypes>
  void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
As if by \tcode{x.swap(y)}.
\end{itemdescr}

\rSec1[saferecl]{Safe reclamation}

\rSec2[saferecl.general]{General}

\pnum
Subclause \ref{saferecl} contains safe-reclamation techniques, which are most
frequently used to straightforwardly resolve access-deletion races.

\rSec2[saferecl.rcu]{Read-copy update (RCU)}

\rSec3[saferecl.rcu.general]{General}

\pnum
RCU is a synchronization mechanism
that can be used for linked data structures
that are frequently read, but seldom updated.
RCU does not provide mutual exclusion,
but instead allows the user to schedule specified actions
such as deletion at some later time.

\pnum
A class type \tcode{T} is \defn{rcu-protectable}
if it has exactly one base class of type \tcode{rcu_obj_base<T, D>}
for some \tcode{D}, and that base is public and non-virtual, and
it has no base classes of type \tcode{rcu_obj_base<X, Y>}
for any other combination \tcode{X}, \tcode{Y}.
An object is rcu-protectable if it is of rcu-protectable type.

\pnum
An invocation of \tcode{unlock} $U$ on an \tcode{rcu_domain dom}
corresponds to an invocation of \tcode{lock} $L$ on \tcode{dom}
if $L$ is sequenced before $U$ and either
\begin{itemize}
\item
no other invocation of \tcode{lock} on \tcode{dom}
is sequenced after $L$ and before $U$, or
\item
every invocation of \tcode{unlock} $U2$ on \tcode{dom}
such that $L$ is sequenced before $U2$ and $U2$ is sequenced before $U$
corresponds to an invocation of \tcode{lock} $L2$ on \tcode{dom}
such that $L$ is sequenced before $L2$ and $L2$ is sequenced before $U2$.
\end{itemize}
\begin{note}
This pairs nested locks and unlocks on a given domain in each thread.
\end{note}

\pnum
A \defn{region of RCU protection} on a domain \tcode{dom}
starts with a \tcode{lock} $L$ on \tcode{dom} and
ends with its corresponding \tcode{unlock} $U$.

\pnum
Given a region of RCU protection $R$ on a domain \tcode{dom} and
given an evaluation $E$ that scheduled another evaluation $F$ in \tcode{dom},
if $E$ does not strongly happen before the start of $R$,
the end of $R$ strongly happens before evaluating $F$.

\pnum
The evaluation of a scheduled evaluation is potentially concurrent with
any other scheduled evaluation.
Each scheduled evaluation is evaluated at most once.

\rSec3[rcu.syn]{Header \tcode{<rcu>} synopsis}

\indexheader{rcu}
\begin{codeblock}
namespace std {
  // \ref{saferecl.rcu.base}, class template \tcode{rcu_obj_base}
  template<class T, class D = default_delete<T>> class rcu_obj_base;

  // \ref{saferecl.rcu.domain}, class \tcode{rcu_domain}
  class rcu_domain;

  // \ref{saferecl.rcu.domain.func}, non-member functions
  rcu_domain& rcu_default_domain() noexcept;
  void rcu_synchronize(rcu_domain& dom = rcu_default_domain()) noexcept;
  void rcu_barrier(rcu_domain& dom = rcu_default_domain()) noexcept;
  template<class T, class D = default_delete<T>>
    void rcu_retire(T* p, D d = D(), rcu_domain& dom = rcu_default_domain());
}
\end{codeblock}

\rSec3[saferecl.rcu.base]{Class template \tcode{rcu_obj_base}}

\pnum
Objects of type \tcode{T} to be protected by RCU inherit from
a specialization \tcode{rcu_obj_base<T, D>} for some \tcode{D}.

\begin{codeblock}
namespace std {
  template<class T, class D = default_delete<T>>
  class rcu_obj_base {
  public:
    void retire(D d = D(), rcu_domain& dom = rcu_default_domain()) noexcept;
  protected:
    rcu_obj_base() = default;
    rcu_obj_base(const rcu_obj_base&) = default;
    rcu_obj_base(rcu_obj_base&&) = default;
    rcu_obj_base& operator=(const rcu_obj_base&) = default;
    rcu_obj_base& operator=(rcu_obj_base&&) = default;
    ~rcu_obj_base() = default;
  private:
    D @\exposid{deleter}@;            // \expos
  };
}
\end{codeblock}

\pnum
The behavior of a program that adds specializations for \tcode{rcu_obj_base}
is undefined.

\pnum
\tcode{T} may be an incomplete type.
It shall be complete before any member of the resulting specialization of
\tcode{rcu_obj_base} is referenced.

\pnum
\tcode{D} shall be a
function object type\iref{function.objects} for which,
given a value \tcode{d} of type \tcode{D} and
a value \tcode{ptr} of type \tcode{T*},
the expression \tcode{d(ptr)} is valid.

\pnum
\tcode{D} shall meet the requirements for
\oldconcept{DefaultConstructible} and \oldconcept{MoveAssignable}.

\pnum
If \tcode{D} is trivially copyable,
all specializations of \tcode{rcu_obj_base<T, D>} are trivially copyable.

\begin{itemdecl}
void retire(D d = D(), rcu_domain& dom = rcu_default_domain()) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
\tcode{T} is an rcu-protectable type.

\pnum
\expects
\tcode{*this} is
a base class subobject of an object \tcode{x} of type \tcode{T}.
The member function \tcode{rcu_obj_base<T, D>::retire}
was not invoked on \tcode{x} before.
The assignment to \exposid{deleter} does not exit via an exception.

\pnum
\effects
Evaluates \tcode{\exposid{deleter} = std::move(d)} and
schedules the evaluation of
the expression \tcode{\exposid{deleter}(\newline addressof(x))}
in the domain \tcode{dom};
the behavior is undefined if that evaluation exits via an exception.
May invoke scheduled evaluations in \tcode{dom}.

\begin{note}
If such evaluations acquire resources held across any invocation of
\tcode{retire} on \tcode{dom}, deadlock can occur.
\end{note}
\end{itemdescr}

\rSec3[saferecl.rcu.domain]{Class \tcode{rcu_domain}}

\rSec4[saferecl.rcu.domain.general]{General}

\begin{codeblock}
namespace std {
  class rcu_domain {
  public:
    rcu_domain(const rcu_domain&) = delete;
    rcu_domain& operator=(const rcu_domain&) = delete;

    void lock() noexcept;
    bool try_lock() noexcept;
    void unlock() noexcept;
  };
}
\end{codeblock}

\pnum
This class meets the requirements of
\oldconcept{Lockable}\iref{thread.req.lockable.req} and
provides regions of RCU protection.
\begin{example}
\begin{codeblock}
std::scoped_lock<rcu_domain> rlock(rcu_default_domain());
\end{codeblock}
\end{example}

\pnum
The functions \tcode{lock} and \tcode{unlock} establish
(possibly nested) regions of RCU protection.

\rSec4[saferecl.rcu.domain.members]{Member functions}

\indexlibrarymember{lock}{rcu_domain}%
\begin{itemdecl}
void lock() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Opens a region of RCU protection.

\pnum
\remarks
Calls to \tcode{lock}
do not introduce a data race\iref{intro.races} involving \tcode{*this}.
\end{itemdescr}

\indexlibrarymember{try_lock}{rcu_domain}%
\begin{itemdecl}
bool try_lock() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to \tcode{lock()}.

\pnum
\returns
\tcode{true}.
\end{itemdescr}

\indexlibrarymember{unlock}{rcu_domain}%
\begin{itemdecl}
void unlock() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
A call to \tcode{lock}
that opened an unclosed region of RCU protection
is sequenced before the call to \tcode{unlock}.

\pnum
\effects
Closes the unclosed region of RCU protection
that was most recently opened.
May invoke scheduled evaluations in \tcode{*this}.

\pnum
\begin{note}
If such evaluations acquire resources
held across any invocation of \tcode{unlock} on \tcode{*this},
deadlock can occur.
\end{note}

\pnum
\remarks
Calls to \tcode{unlock} do not introduce a data race involving \tcode{*this}.
\begin{note}
Evaluation of scheduled evaluations can still cause a data race.
\end{note}
\end{itemdescr}

\rSec4[saferecl.rcu.domain.func]{Non-member functions}

\indexlibraryglobal{rcu_default_domain}%
\begin{itemdecl}
rcu_domain& rcu_default_domain() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A reference to a static-duration object of type \tcode{rcu_domain}.
A reference to the same object is returned every time this function is called.
\end{itemdescr}

\indexlibraryglobal{rcu_synchronize}%
\begin{itemdecl}
void rcu_synchronize(rcu_domain& dom = rcu_default_domain()) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If the call to \tcode{rcu_synchronize} does not strongly happen before
the lock opening an RCU protection region \tcode{R} on \tcode{dom},
blocks until the \tcode{unlock} closing \tcode{R} happens.

\pnum
\sync
The \tcode{unlock} closing \tcode{R}
strongly happens before the return from \tcode{rcu_synchronize}.
\end{itemdescr}

\indexlibraryglobal{rcu_barrier}%
\begin{itemdecl}
void rcu_barrier(rcu_domain& dom = rcu_default_domain()) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
May evaluate any scheduled evaluations in \tcode{dom}.
For any evaluation that happens before the call to \tcode{rcu_barrier} and
that schedules an evaluation $E$ in \tcode{dom},
blocks until $E$ has been evaluated.

\pnum
\sync
The evaluation of any such $E$
strongly happens before the return from \tcode{rcu_barrier}.

\begin{note}
A call to \tcode{rcu_barrier} does not imply
a call to \tcode{rcu_synchronize} and vice versa.
\end{note}
\end{itemdescr}

\indexlibraryglobal{rcu_retire}%
\begin{itemdecl}
template<class T, class D = default_delete<T>>
  void rcu_retire(T* p, D d = D(), rcu_domain& dom = rcu_default_domain());
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
\tcode{is_move_constructible_v<D>} is \tcode{true} and
the expression \tcode{d(p)} is well-formed.

\pnum
\expects
\tcode{D} meets the \oldconcept{MoveConstructible} and
\oldconcept{Destructible} requirements.

\pnum
\effects
May allocate memory.
It is unspecified whether the memory allocation
is performed by invoking \tcode{\keyword{operator} \keyword{new}}.
Initializes an object \tcode{d1} of type \tcode{D} from \tcode{std::move(d)}.
Schedules the evaluation of \tcode{d1(p)} in the domain \tcode{dom};
the behavior is undefined if that evaluation exits via an exception.
May invoke scheduled evaluations in \tcode{dom}.
\begin{note}
If \tcode{rcu_retire} exits via an exception, no evaluation
is scheduled.
\end{note}

\pnum
\throws
\tcode{bad_alloc} or any exception thrown by the initialization of \tcode{d1}.

\pnum
\begin{note}
If scheduled evaluations acquire resources
held across any invocation of \tcode{rcu_retire} on \tcode{dom},
deadlock can occur.
\end{note}
\end{itemdescr}

\rSec2[saferecl.hp]{Hazard pointers}

\rSec3[saferecl.hp.general]{General}

\pnum
\indextext{hazard pointer}%
A hazard pointer is a single-writer multi-reader pointer
that can be owned by at most one thread at any time.
Only the owner of the hazard pointer can set its value,
while any number of threads may read its value.
The owner thread sets the value of a hazard pointer to point to an object
in order to indicate to concurrent threads---which
may delete such an object---that
the object is not yet safe to delete.

\pnum
A class type \tcode{T} is \defn{hazard-protectable}
if it has exactly one base class of type \tcode{hazard_pointer_obj_base<T, D>}
for some \tcode{D},
that base is public and non-virtual, and
it has no base classes of type \tcode{hazard_pointer_obj_base<T2, D2>}
for any other combination \tcode{T2}, \tcode{D2}.
An object is \defn{hazard-protectable} if it is of hazard-protectable type.

\pnum
The time span between creation and destruction of a hazard pointer $h$
is partitioned into a series of \defnadjx{protection}{epochs}{epoch};
in each protection epoch,
$h$ either is \defnx{associated with}{hazard pointer!associated}
a hazard-protectable object, or is \defnx{unassociated}{hazard pointer!unassociated}.
Upon creation, a hazard pointer is unassociated.
Changing the association (possibly to the same object)
initiates a new protection epoch and ends the preceding one.

\pnum
An object \tcode{x} of hazard-protectable type \tcode{T} is
\defn{retired} with a deleter of type \tcode{D}
when the member function \tcode{hazard_pointer_obj_base<T, D>::retire}
is invoked on \tcode{x}.
Any given object \tcode{x} shall be retired at most once.

\pnum
A retired object \tcode{x} is \defn{reclaimed}
by invoking its deleter with a pointer to \tcode{x};
the behavior is undefined if that invocation exits via an exception.

\pnum
A hazard-protectable object \tcode{x} is \defn{possibly-reclaimable}
with respect to an evaluation $A$ if
\begin{itemize}
\item
\tcode{x} is not reclaimed; and
\item
\tcode{x} is retired in an evaluation $R$ and
$A$ does not happen before $R$; and
\item
for all hazard pointers $h$ and for every protection epoch $E$ of $h$
during which $h$ is associated with \tcode{x}:
\begin{itemize}
\item
if the beginning of $E$ happens before $R$,
the end of $E$ strongly happens before $A$; and
\item
if $E$ began by an evaluation of \tcode{try_protect} with argument \tcode{src},
label its atomic load operation $L$.
If there exists an atomic modification $B$ on \tcode{src}
such that $L$ observes a modification that is modification-ordered before $B$, and
$B$ happens before \tcode{x} is retired,
the end of $E$ strongly happens before $A$.
\begin{note}
In typical use, a store to \tcode{src} sequenced before retiring \tcode{x}
will be such an atomic operation $B$.
\end{note}
\end{itemize}
\begin{note}
The latter two conditions convey the informal notion
that a protection epoch that began before retiring \tcode{x},
as implied either by the happens-before relation or
the coherence order of some source,
delays the reclamation of \tcode{x}.
\end{note}
\end{itemize}

\pnum
The number of possibly-reclaimable objects has an unspecified bound.
\begin{note}
The bound can be a function of the number of hazard pointers,
the number of threads that retire objects, and
the number of threads that use hazard pointers.
\end{note}
\begin{example}
The following example shows how hazard pointers allow updates to be carried out
in the presence of concurrent readers.
The object of type \tcode{hazard_pointer} in \tcode{print_name}
protects the object \tcode{*ptr} from being reclaimed by \tcode{ptr->retire}
until the end of the protection epoch.
\begin{codeblock}
struct Name : public hazard_pointer_obj_base<Name> { /* details */ };
atomic<Name*> name;
// called often and in parallel!
void print_name() {
  hazard_pointer h = make_hazard_pointer();
  Name* ptr = h.protect(name);          // Protection epoch starts
  // ... safe to access \tcode{*ptr}
}                                       // Protection epoch ends.

// called rarely, but possibly concurrently with \tcode{print_name}
void update_name(Name* new_name) {
  Name* ptr = name.exchange(new_name);
  ptr->retire();
}
\end{codeblock}
\end{example}

\rSec3[hazard.pointer.syn]{Header \tcode{<hazard_pointer>} synopsis}

\indexheader{hazard_pointer}%
\begin{codeblock}
namespace std {
  // \ref{saferecl.hp.base}, class template \tcode{hazard_pointer_obj_base}
  template<class T, class D = default_delete<T>> class hazard_pointer_obj_base;

  // \ref{saferecl.hp.holder}, class \tcode{hazard_pointer}
  class hazard_pointer;

  // \ref{saferecl.hp.holder.nonmem}, non-member functions
  hazard_pointer make_hazard_pointer();
  void swap(hazard_pointer&, hazard_pointer&) noexcept;
}
\end{codeblock}

\rSec3[saferecl.hp.base]{Class template \tcode{hazard_pointer_obj_base}}

\begin{codeblock}
namespace std {
  template<class T, class D = default_delete<T>>
  class hazard_pointer_obj_base {
  public:
    void retire(D d = D()) noexcept;
  protected:
    hazard_pointer_obj_base() = default;
    hazard_pointer_obj_base(const hazard_pointer_obj_base&) = default;
    hazard_pointer_obj_base(hazard_pointer_obj_base&&) = default;
    hazard_pointer_obj_base& operator=(const hazard_pointer_obj_base&) = default;
    hazard_pointer_obj_base& operator=(hazard_pointer_obj_base&&) = default;
    ~hazard_pointer_obj_base() = default;
  private:
    D @\exposid{deleter}@;      // \expos
  };
}
\end{codeblock}

\pnum
\tcode{D} shall be a function object type\iref{func.require}
for which, given a value \tcode{d} of type \tcode{D} and
a value \tcode{ptr} of type \tcode{T*},
the expression \tcode{d(ptr)} is valid.

\pnum
The behavior of a program
that adds specializations for \tcode{hazard_pointer_obj_base} is undefined.

\pnum
\tcode{D} shall meet the requirements for
\oldconcept{DefaultConstructible} and \oldconcept{MoveAssignable}.

\pnum
\tcode{T} may be an incomplete type.
It shall be complete before any member
of the resulting specialization of \tcode{hazard_pointer_obj_base}
is referenced.

\indexlibrarymember{retire}{hazard_pointer_obj_base}%
\begin{itemdecl}
void retire(D d = D()) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
\tcode{T} is a hazard-protectable type.

\pnum
\expects
\tcode{*this} is
a base class subobject of an object \tcode{x} of type \tcode{T}.
\tcode{x} is not retired.
Move-assigning \tcode{d} to \tcode{deleter} does not exit via an exception.

\pnum
\effects
Move-assigns \tcode{d} to \tcode{deleter},
thereby setting it as the deleter of \tcode{x},
then retires \tcode{x}.
May reclaim possibly-reclaimable objects.
\end{itemdescr}

\rSec3[saferecl.hp.holder]{Class \tcode{hazard_pointer}}

\rSec4[saferecl.hp.holder.general]{General}

\begin{codeblock}
namespace std {
  class hazard_pointer {
  public:
    hazard_pointer() noexcept;
    hazard_pointer(hazard_pointer&&) noexcept;
    hazard_pointer& operator=(hazard_pointer&&) noexcept;
    ~hazard_pointer();

    bool empty() const noexcept;
    template<class T> T* protect(const atomic<T*>& src) noexcept;
    template<class T> bool try_protect(T*& ptr, const atomic<T*>& src) noexcept;
    template<class T> void reset_protection(const T* ptr) noexcept;
    void reset_protection(nullptr_t = nullptr) noexcept;
    void swap(hazard_pointer&) noexcept;
  };
}
\end{codeblock}

\pnum
An object of type \tcode{hazard_pointer} is either empty or
\defnx{owns}{owning!hazard pointer} a hazard pointer.
Each hazard pointer is owned by
exactly one object of type \tcode{hazard_pointer}.
\begin{note}
An empty \tcode{hazard_pointer} object is different from
a \tcode{hazard_pointer} object
that owns an unassociated hazard pointer.
An empty \tcode{hazard_pointer} object does not own any hazard pointers.
\end{note}

\rSec4[saferecl.hp.holder.ctor]{Constructors, destructor, and assignment}

\indexlibraryctor{hazard_pointer}%
\begin{itemdecl}
hazard_pointer() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
\tcode{*this} is empty.
\end{itemdescr}

\indexlibraryctor{hazard_pointer}%
\begin{itemdecl}
hazard_pointer(hazard_pointer&& other) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\ensures
If \tcode{other} is empty, \tcode{*this} is empty.
Otherwise,
\tcode{*this} owns the hazard pointer originally owned by \tcode{other};
\tcode{other} is empty.
\end{itemdescr}

\indexlibrarydtor{hazard_pointer}%
\begin{itemdecl}
~hazard_pointer();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{*this} is not empty,
destroys the hazard pointer owned by \tcode{*this},
thereby ending its current protection epoch.
\end{itemdescr}

\indexlibrarymember{operator=}{hazard_pointer}%
\begin{itemdecl}
hazard_pointer& operator=(hazard_pointer&& other) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{this == \&other} is \tcode{true}, no effect.
Otherwise, if \tcode{*this} is not empty,
destroys the hazard pointer owned by \tcode{*this},
thereby ending its current protection epoch.

\pnum
\ensures
If \tcode{other} was empty, \tcode{*this} is empty.
Otherwise, \tcode{*this} owns the hazard pointer originally
owned by \tcode{other}.
If \tcode{this != \&other} is \tcode{true}, \tcode{other} is empty.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\rSec4[saferecl.hp.holder.mem]{Member functions}

\indexlibrarymember{empty}{hazard_pointer}%
\begin{itemdecl}
bool empty() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if and only if \tcode{*this} is empty.
\end{itemdescr}

\indexlibrarymember{protect}{hazard_pointer}%
\begin{itemdecl}
template<class T> T* protect(const atomic<T*>& src) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
T* ptr = src.load(memory_order::relaxed);
while (!try_protect(ptr, src)) {}
return ptr;
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{try_protect}{hazard_pointer}%
\begin{itemdecl}
template<class T> bool try_protect(T*& ptr, const atomic<T*>& src) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
\tcode{T} is a hazard-protectable type.

\pnum
\expects
\tcode{*this} is not empty.

\pnum
\effects
Performs the following steps in order:
\begin{itemize}
\item Initializes a variable \tcode{old} of type \tcode{T*} with the value of \tcode{ptr}.
\item Evaluates \tcode{reset_protection(old)}.
\item Assigns the value of \tcode{src.load(memory_order::acquire)} to \tcode{ptr}.
\item If \tcode{old == ptr} is \tcode{false},
evaluates \tcode{reset_protection()}.
\end{itemize}

\pnum
\returns
\tcode{old == ptr}.
\end{itemdescr}

\indexlibrarymember{reset_protection}{hazard_pointer}%
\begin{itemdecl}
template<class T> void reset_protection(const T* ptr) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\mandates
\tcode{T} is a hazard-protectable type.

\pnum
\expects
\tcode{*this} is not empty.

\pnum
\effects
If \tcode{ptr} is a null pointer value, invokes \tcode{reset_protection()}.
Otherwise,
associates the hazard pointer owned by \tcode{*this} with \tcode{*ptr},
thereby ending the current protection epoch.

\pnum
\complexity
Constant.
\end{itemdescr}

\indexlibrarymember{reset_protection}{hazard_pointer}%
\begin{itemdecl}
void reset_protection(nullptr_t = nullptr) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{*this} is not empty.

\pnum
\ensures
The hazard pointer owned by \tcode{*this} is unassociated.

\pnum
\complexity
Constant.
\end{itemdescr}

\indexlibrarymember{swap}{hazard_pointer}%
\begin{itemdecl}
void swap(hazard_pointer& other) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Swaps the hazard pointer ownership of this object with that of \tcode{other}.
\begin{note}
The owned hazard pointers, if any, remain unchanged during the swap and
continue to be associated with the respective objects
that they were protecting before the swap, if any.
No protection epochs are ended or initiated.
\end{note}

\pnum
\complexity
Constant.
\end{itemdescr}

\rSec4[saferecl.hp.holder.nonmem]{Non-member functions}

\indexlibraryglobal{make_hazard_pointer}%
\begin{itemdecl}
hazard_pointer make_hazard_pointer();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs a hazard pointer.

\pnum
\returns
A \tcode{hazard_pointer} object that owns the newly-constructed hazard pointer.

\pnum
\throws
May throw \tcode{bad_alloc}
if memory for the hazard pointer could not be allocated.
\end{itemdescr}

\indexlibrarymember{swap}{hazard_pointer}%
\begin{itemdecl}
void swap(hazard_pointer& a, hazard_pointer& b) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to \tcode{a.swap(b)}.
\end{itemdescr}
