<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.12: http://docutils.sourceforge.net/" />
<title>P0019r5 : Atomic View</title>
<meta name="date" content="2017-03-06" />
<meta name="author" content="H. Carter Edwards" />
<meta name="author" content="Hans Boehm" />
<meta name="author" content="Olivier Giroux" />
<meta name="author" content="James Reus" />
<style type="text/css">

/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7614 2013-02-21 15:55:51Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.

See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/

/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
  border: 0 }

table.borderless td, table.borderless th {
  /* Override padding for "table.docutils td" with "! important".
     The right padding separates the table cells. */
  padding: 0 0.5em 0 0 ! important }

.first {
  /* Override more specific margin styles with "! important". */
  margin-top: 0 ! important }

.last, .with-subtitle {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dl.docutils dd {
  margin-bottom: 0.5em }

object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
  overflow: hidden;
}

/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
  font-weight: bold }
*/

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

/* Uncomment (and remove this text!) to get reduced vertical space in
   compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
  margin-bottom: 0.5em }

div.compound .compound-last, div.compound .compound-middle {
  margin-top: 0.5em }
*/

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em ;
  margin-right: 2em }

div.footer, div.header {
  clear: both;
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin: 0 0 0.5em 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  margin-top: 0.4em }

h1.title {
  text-align: center }

h2.subtitle {
  text-align: center }

hr.docutils {
  width: 75% }

img.align-left, .figure.align-left, object.align-left {
  clear: left ;
  float: left ;
  margin-right: 1em }

img.align-right, .figure.align-right, object.align-right {
  clear: right ;
  float: right ;
  margin-left: 1em }

img.align-center, .figure.align-center, object.align-center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.align-left {
  text-align: left }

.align-center {
  clear: both ;
  text-align: center }

.align-right {
  text-align: right }

/* reset inner alignment in figures */
div.align-right {
  text-align: inherit }

/* div.align-center * { */
/*   text-align: left } */

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font: inherit }

pre.literal-block, pre.doctest-block, pre.math, pre.code {
  margin-left: 2em ;
  margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

span.section-subtitle {
  /* font-size relative to parent (h1..h6 element) */
  font-size: 80% }

table.citation {
  border-left: solid 1px gray;
  margin-left: 1px }

table.docinfo {
  margin: 2em 4em }

table.docutils {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.footnote {
  border-left: solid 1px black;
  margin-left: 1px }

table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

table.docutils th.field-name, table.docinfo th.docinfo-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap ;
  padding-left: 0 }

/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
  border: 0px;
  border-top: 2px solid;
  border-bottom: 2px solid;
  border-collapse: collapse;
}
table.docutils.booktabs * {
  border: 0px;
}
table.docutils.booktabs th {
  border-bottom: thin solid;
  text-align: left;
}

h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  font-size: 100% }

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="p0019r5-atomic-view">
<h1 class="title">P0019r5 : Atomic View</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="field"><th class="docinfo-name">Project:</th><td class="field-body">ISO JTC1/SC22/WG21: Programming Language C++</td>
</tr>
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">P0019r5</td>
</tr>
<tr><th class="docinfo-name">Date:</th>
<td>2017-03-06</td></tr>
<tr class="field"><th class="docinfo-name">Reply-to:</th><td class="field-body"><a class="reference external" href="mailto:hcedwar&#64;sandia.gov">hcedwar&#64;sandia.gov</a></td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>H. Carter Edwards</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:hcedwar&#64;sandia.gov">hcedwar&#64;sandia.gov</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Hans Boehm</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:hboehm&#64;google.com">hboehm&#64;google.com</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>Olivier Giroux</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:ogiroux&#64;nvidia.com">ogiroux&#64;nvidia.com</a></td></tr>
<tr><th class="docinfo-name">Author:</th>
<td>James Reus</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first last reference external" href="mailto:reus1&#64;llnl.gov">reus1&#64;llnl.gov</a></td></tr>
<tr class="field"><th class="docinfo-name">Audience:</th><td class="field-body">Library Evolution</td>
</tr>
<tr class="field"><th class="docinfo-name">URL:</th><td class="field-body"><a class="reference external" href="https://github.com/kokkos/ISO-CPP-Papers/blob/master/P0019.rst">https://github.com/kokkos/ISO-CPP-Papers/blob/master/P0019.rst</a></td>
</tr>
</tbody>
</table>
<div class="section" id="revision-history">
<h1>Revision History</h1>
<div class="section" id="p0019r3">
<h2>P0019r3</h2>
<blockquote>
<ul class="simple">
<li>Align proposal with content of corresponding sections in N5131, 2016-07-15.</li>
<li>Remove the <em>one root wrapping constructor</em> requirement from <strong>atomic_array_view</strong>.</li>
<li>Other minor revisions responding to feedback from SG1 &#64; Oulu.</li>
</ul>
</blockquote>
</div>
<div class="section" id="p0019r4">
<h2>P0019r4</h2>
<blockquote>
<ul class="simple">
<li>wrapper constructor strengthen requires clause and omit throws clause</li>
<li>Note types must be trivially copyable, as required for all atomics</li>
<li>2016-11-09 Issaquah SG1 decision: move to LEWG targeting Concurrency TS V2</li>
</ul>
</blockquote>
</div>
<div class="section" id="d0019r5">
<h2>D0019r5</h2>
<blockquote>
<ul class="simple">
<li>2017-03-01 Kona LEWG review<ul>
<li>Merge in P0440 Floating Point Atomic View because LEWG
consensus to move P0020 Floating Point Atomic to C++20 IS</li>
<li>Rename from <strong>atomic_view</strong> and <strong>atomic_array_view</strong>
to <strong>atomic_ref&lt;T&gt;</strong> and <strong>atomic_ref&lt;T[]&gt;</strong>,
other name suggested <strong>atomic_wrapper</strong>.</li>
<li>Remove <strong>constexpr</strong> qualification from default constructor
because this qualification constrains implementations and
does not add apparent value.</li>
</ul>
</li>
<li>Remove default constructor, copy constructor, and assignment operator
for tighter alignment with <strong>atomic&lt;T&gt;</strong> and prevent empty references.</li>
<li>Revise syntax to align with P0558r1, Resolving atomic&lt;T&gt;
base class inconsistencies</li>
<li>Recommend feature next macro</li>
</ul>
</blockquote>
</div>
</div>
<div class="section" id="overview-motivation-discussion">
<h1>Overview / Motivation / Discussion</h1>
<p>This paper proposes an extension to the atomic operations library [atomics]
for atomic operations applied to non-atomic objects.
As required by [atomics.types.generic] 20.5p1 the wrapped type <strong>T</strong>
must be trivially copiable.
This paper includes <em>atomic floating point</em> capability defined in P0020r5.</p>
<div class="section" id="motivation-atomic-operations-on-a-single-non-atomic-object">
<h2>Motivation: Atomic Operations on a Single Non-atomic Object</h2>
<p>An <em>atomic reference</em> is used to perform
atomic operations on referenced non-atomic object.
The intent is for <em>atomic reference</em> to provide the best-performing
implementation of atomic operations for the non-atomic object type.
All atomic operations performed through an <em>atomic reference</em>
on a referenced non-atomic object
are atomic with respect to any other <em>atomic reference</em> that references
the same object, as defined by equality of pointers to that object.
The intent is for atomic operations
to directly update the referenced object.
The <em>atomic reference wrapping constructor</em> may acquire a resource,
such as a lock from a collection of address-sharded locks,
to perform atomic operations.
Such <em>atomic reference</em> objects are not lock-free and not address-free.
When such a resource is necessary subsequent
copy and move constructors and assignment operators
may reduce overhead by copying or moving the previously
acquired resource as opposed to re-acquiring that resource.</p>
<p>Introducing concurrency within legacy codes may require
replacing operations on existing non-atomic objects with atomic operations
such that the non-atomic object cannot be replaced with a <strong>atomic</strong> object.</p>
<p>An object may be heavily used non-atomically in well-defined phases
of an application.  Forcing such objects to be exclusively <strong>atomic</strong>
would incur an unnecessary performance penalty.</p>
</div>
<div class="section" id="motivation-atomic-operations-on-members-of-a-very-large-array">
<h2>Motivation: Atomic Operations on Members of a Very Large Array</h2>
<p>High performance computing (HPC) applications use very large arrays.
Computations with these arrays typically have distinct phases that
allocate and initialize members of the array,
update members of the array,
and read members of the array.
Parallel algorithms for initialization (e.g., zero fill)
have non-conflicting access when assigning member values.
Parallel algorithms for updates have conflicting access
to members which must be guarded by atomic operations.
Parallel algorithms with read-only access require best-performing
streaming read access, random read access, vectorization,
or other guaranteed non-conflicting HPC pattern.</p>
<p>An <em>atomic array reference</em> is used to perform
atomic operations on the non-atomic members of the referenced array.
The intent is for <em>atomic array reference</em> to provide the
best-performing implementation of atomic operations
for the members of the array.</p>
</div>
<div class="section" id="naming">
<h2>Naming</h2>
<p>The current <strong>Header &lt;atomic&gt; synopsis</strong> contains the following.</p>
<blockquote>
<div class="line-block">
<div class="line">namespace std {</div>
<div class="line-block">
<div class="line">template&lt; class T &gt; struct atomic;</div>
<div class="line">template&lt; class T &gt; struct atomic&lt;T*&gt;;</div>
</div>
<div class="line">}</div>
</div>
</blockquote>
<p>The proposal introduces the following type and partial specializations.</p>
<blockquote>
<div class="line-block">
<div class="line">namespace std {</div>
<div class="line">namespace experimental {</div>
<div class="line"><br /></div>
<div class="line-block">
<div class="line">template&lt; class T &gt; struct atomic_ref;</div>
<div class="line">template&lt; class T &gt; struct atomic_ref&lt;T*&gt;;</div>
<div class="line">template&lt; class T &gt; struct atomic_ref&lt;T[]&gt;;;</div>
<div class="line"><br /></div>
</div>
<div class="line">}}</div>
</div>
</blockquote>
<p>Other possible naming or partial specializations</p>
<blockquote>
<ul class="simple">
<li>atomic_wrapper&lt; T &gt;,
atomic_wrapper&lt; T * &gt;,
atomic_wrapper&lt; T[] &gt;</li>
<li>atomic&lt; T &amp; &gt;,
atomic&lt; T * &amp; &gt;,
atomic&lt; T[] &gt;</li>
</ul>
</blockquote>
</div>
<div class="section" id="wrappability-constraints">
<h2><em>Wrappability</em> Constraints</h2>
<p>The <em>wrapping constructor</em> of an atomic reference requires
that the object be <em>wrappable</em> for atomic operations;
for example that the object is properly aligned in memory
or resides in GPU register memory.
This revision of P0019 does not enumerate all potential
<em>wrappability</em> constraints or specify behavior of the
wrapping constructor when these constraints are violated.
It is quality-of-implementation to generate appropriate
error information.</p>
</div>
</div>
<div class="section" id="proposal">
<h1>Proposal</h1>
<div class="section" id="recommended-feature-text-macro">
<h2>Recommended feature text macro</h2>
<blockquote>
<div class="line-block">
<div class="line">__cpp_lib_atomic_ref</div>
</div>
</blockquote>
</div>
<div class="section" id="add-to-header-atomic-synopsis">
<h2><em>add to</em> Header &lt;atomic&gt; synopsis</h2>
<blockquote>
<div class="line-block">
<div class="line">namespace std {</div>
<div class="line">namespace experimental {</div>
<div class="line"><br /></div>
<div class="line-block">
<div class="line">template&lt; class T &gt; struct atomic_ref ;</div>
<div class="line">template&lt; class T &gt; struct atomic_ref&lt; T * &gt;;</div>
<div class="line">template&lt; class T &gt; struct atomic_ref&lt; T[] &gt;;</div>
<div class="line"><br /></div>
</div>
<div class="line">}}</div>
</div>
</blockquote>
</div>
<div class="section" id="add-section-to-class-template-atomic">
<h2><em>add section to</em> Class template atomic</h2>
<blockquote>
<div class="line-block">
<div class="line">template&lt; class T &gt; struct atomic_ref {</div>
<div class="line-block">
<div class="line">using value_type = T;</div>
<div class="line">static constexpr size_t required_alignment = <em>implementation-defined</em> ;</div>
<div class="line">static constexpr bool is_always_lock_free = <em>implementation-defined</em> ;</div>
<div class="line">bool is_lock_free() const noexcept;</div>
<div class="line">void store( T , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line">T load( memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line">operator T() const noexcept ;</div>
<div class="line">T exchange( T , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line">bool compare_exchange_weak( T&amp; , T , memory_order , memory_order ) const noexcept;</div>
<div class="line">bool compare_exchange_strong( T&amp; , T , memory_order , memory_order ) const noexcept;</div>
<div class="line">bool compare_exchange_weak( T&amp; , T , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line">bool compare_exchange_strong( T&amp;, T, memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line"><br /></div>
<div class="line">atomic_ref() = delete ;</div>
<div class="line">atomic_ref( const atomic_ref &amp; ) = delete ;</div>
<div class="line">atomic_ref &amp; operator = ( const atomic_ref &amp; ) = delete ;</div>
<div class="line"><br /></div>
<div class="line">explicit atomic_ref( T &amp; obj ); // <em>wrapping</em> constructor</div>
<div class="line"><br /></div>
<div class="line">T operator=(T) const noexcept ;</div>
</div>
<div class="line">};</div>
</div>
</blockquote>
<p><strong>static constexpr size_t required_alignment =</strong> <em>implementation-defined</em> <strong>;</strong></p>
<blockquote>
The required alignment of an object to be referenced by an atomic reference,
which is at least <tt class="docutils literal">alignof(T)</tt>.
[Note: An architecture may support lock-free atomic operations
on objects of type <em>T</em> only if those objects meet a required
alignment.  The intent is for <em>atomic_ref</em> to provide lock-free
atomic operations whenever possible.
For example, an architecture may be able to support lock-free
operations on <tt class="docutils literal"><span class="pre">std::complex&lt;double&gt;</span></tt> only if aligned to
<tt class="docutils literal">2*alignof(double)</tt> and not <tt class="docutils literal">alignof(double)</tt> . - end note]</blockquote>
<p><strong>atomic_ref( T &amp; obj );</strong></p>
<blockquote>
<p>This wrapping constructor constructs an atomic reference
that references the non-atomic object.
Atomic operations applied to object through a referencing
<em>atomic reference</em> are atomic with respect to atomic operations
applied through any other <em>atomic reference</em> that references that <em>object</em>.</p>
<p><em>Requires:</em> The referenced non-atomic object shall be
aligned to <tt class="docutils literal">required_alignment</tt>.
The lifetime (3.8) of <tt class="docutils literal">*this</tt>
shall not exceed the lifetime of the referenced non-atomic object.
While any <tt class="docutils literal">atomic_ref</tt> instance exists that references the object
all accesses of that object shall exclusively occur through those
<tt class="docutils literal">atomic_ref</tt> instances.
If the referenced <em>object</em> is of a class or aggregate type
then members of that object shall not be concurrently
wrapped by an <tt class="docutils literal">atomic_ref</tt> object.
The referenced object shall not be a member of an array that
is wrapped by an <tt class="docutils literal"><span class="pre">atomic_ref&lt;T[]&gt;</span></tt> .
[Note: Other implementation dependent conditions may exist. - end note]</p>
<p><em>Effects:</em> <tt class="docutils literal">*this</tt> references the non-atomic object*
[Note: The wrapping constructor may acquire a shared resource,
such as a lock associated with the referenced object,
to enable atomic operations applied to the referenced
non-atomic object. - end note]</p>
</blockquote>
</div>
<div class="section" id="add-to-specializations-for-integers">
<h2><em>add to</em> Specializations for integers</h2>
<blockquote>
<div class="line-block">
<div class="line">template&lt;&gt; struct atomic_ref&lt; <em>integral</em> &gt; {</div>
<div class="line-block">
<div class="line">using value_type = <em>integral</em> ;</div>
<div class="line">using difference_type = value_type;</div>
<div class="line">static constexpr size_t required_alignment = <em>implementation-defined</em> ;</div>
<div class="line">static constexpr bool is_always_lock_free = <em>implementation-defined</em> ;</div>
<div class="line">bool is_lock_free() const noexcept;</div>
<div class="line">void store( <em>integral</em> , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line"><em>integral</em> load( memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line">operator <em>integral</em> () const noexcept ;</div>
<div class="line"><em>integral</em> exchange( <em>integral</em> , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line">bool compare_exchange_weak( <em>integral</em> &amp; , <em>integral</em> , memory_order , memory_order ) const noexcept;</div>
<div class="line">bool compare_exchange_strong( <em>integral</em> &amp; , <em>integral</em>  , memory_order , memory_order ) const noexcept;</div>
<div class="line">bool compare_exchange_weak( <em>integral</em> &amp; , <em>integral</em>  , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line">bool compare_exchange_strong( <em>integral</em> &amp;, <em>integral</em> , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line"><br /></div>
<div class="line"><em>integral</em> fetch_add( <em>integral</em> , memory_order = memory_order_seq_cst) const noexcept;</div>
<div class="line"><em>integral</em> fetch_sub( <em>integral</em> , memory_order = memory_order_seq_cst) const noexcept;</div>
<div class="line"><em>integral</em> fetch_and( <em>integral</em> , memory_order = memory_order_seq_cst) const noexcept;</div>
<div class="line"><em>integral</em> fetch_or(  <em>integral</em> , memory_order = memory_order_seq_cst) const noexcept;</div>
<div class="line"><em>integral</em> fetch_xor( <em>integral</em> , memory_order = memory_order_seq_cst) const noexcept;</div>
<div class="line"><br /></div>
<div class="line">atomic_ref() = delete ;</div>
<div class="line">atomic_ref( const atomic_ref &amp; ) = delete ;</div>
<div class="line">atomic_ref &amp; operator = ( const atomic_ref &amp; ) = delete ;</div>
<div class="line"><br /></div>
<div class="line">explicit atomic_ref(  <em>integral</em>  &amp; obj ); // <em>wrapping</em> constructor</div>
<div class="line"><br /></div>
<div class="line"><em>integral</em> operator=( <em>integral</em> ) const noexcept ;</div>
<div class="line"><em>integral</em> operator++(int) const noexcept;</div>
<div class="line"><em>integral</em> operator--(int) const noexcept;</div>
<div class="line"><em>integral</em> operator++() const noexcept;</div>
<div class="line"><em>integral</em> operator--() const noexcept;</div>
<div class="line"><em>integral</em> operator+=( <em>integral</em> ) const noexcept;</div>
<div class="line"><em>integral</em> operator-=( <em>integral</em> ) const noexcept;</div>
<div class="line"><em>integral</em> operator&amp;=( <em>integral</em> ) const noexcept;</div>
<div class="line"><em>integral</em> operator|=( <em>integral</em> ) const noexcept;</div>
<div class="line"><em>integral</em> operator^=( <em>integral</em> ) const noexcept;</div>
</div>
<div class="line">};</div>
</div>
</blockquote>
</div>
<div class="section" id="add-to-specializations-for-floating-point">
<h2><em>add to</em> Specializations for floating-point</h2>
<blockquote>
<div class="line-block">
<div class="line">template&lt;&gt; struct atomic_ref&lt; <em>floating-point</em> &gt; {</div>
<div class="line-block">
<div class="line">using value_type = <em>floating-point</em> ;</div>
<div class="line">using difference_type = value_type;</div>
<div class="line">static constexpr size_t required_alignment = <em>implementation-defined</em> ;</div>
<div class="line">static constexpr bool is_always_lock_free = <em>implementation-defined</em> ;</div>
<div class="line">bool is_lock_free() const noexcept;</div>
<div class="line">void store( <em>floating-point</em> , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line"><em>floating-point</em> load( memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line">operator <em>floating-point</em> () const noexcept ;</div>
<div class="line"><em>floating-point</em> exchange( <em>floating-point</em> , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line">bool compare_exchange_weak( <em>floating-point</em> &amp; , <em>floating-point</em> , memory_order , memory_order ) const noexcept;</div>
<div class="line">bool compare_exchange_strong( <em>floating-point</em> &amp; , <em>floating-point</em>  , memory_order , memory_order ) const noexcept;</div>
<div class="line">bool compare_exchange_weak( <em>floating-point</em> &amp; , <em>floating-point</em>  , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line">bool compare_exchange_strong( <em>floating-point</em> &amp;, <em>floating-point</em> , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line"><br /></div>
<div class="line"><em>floating-point</em> fetch_add( <em>floating-point</em> , memory_order = memory_order_seq_cst) const noexcept;</div>
<div class="line"><em>floating-point</em> fetch_sub( <em>floating-point</em> , memory_order = memory_order_seq_cst) const noexcept;</div>
<div class="line"><br /></div>
<div class="line">atomic_ref() = delete ;</div>
<div class="line">atomic_ref( const atomic_ref &amp; ) = delete ;</div>
<div class="line">atomic_ref &amp; operator = ( const atomic_ref &amp; ) = delete ;</div>
<div class="line"><br /></div>
<div class="line">explicit atomic_ref( <em>floating-point</em> &amp; obj ) noexcept ;</div>
<div class="line"><br /></div>
<div class="line"><em>floating-point</em> operator=( <em>floating-point</em> ) noexcept ;</div>
<div class="line"><em>floating-point</em> operator+=( <em>floating-point</em> ) const noexcept ;</div>
<div class="line"><em>floating-point</em> operator-=( <em>floating-point</em> ) const noexcept ;</div>
</div>
<div class="line">};</div>
</div>
</blockquote>
</div>
<div class="section" id="add-to-partial-specializations-for-pointers">
<h2><em>add to</em> Partial specializations for pointers</h2>
<blockquote>
<div class="line-block">
<div class="line">template&lt;class T&gt; struct atomic_ref&lt; T * &gt; {</div>
<div class="line-block">
<div class="line">using value_type = T * ;</div>
<div class="line">using difference_type = ptrdiff_t;</div>
<div class="line">static constexpr size_t required_alignment = <em>implementation-defined</em> ;</div>
<div class="line">static constexpr bool is_always_lock_free = <em>implementation-defined</em> ;</div>
<div class="line">bool is_lock_free() const noexcept;</div>
<div class="line">void store( T * , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line">T * load( memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line">operator T * () const noexcept ;</div>
<div class="line">T * exchange( T * , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line">bool compare_exchange_weak( T * &amp; , T * , memory_order , memory_order ) const noexcept;</div>
<div class="line">bool compare_exchange_strong( T * &amp; , T *  , memory_order , memory_order ) const noexcept;</div>
<div class="line">bool compare_exchange_weak( T * &amp; , T *  , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line">bool compare_exchange_strong( T * &amp;, T * , memory_order = memory_order_seq_cst ) const noexcept;</div>
<div class="line"><br /></div>
<div class="line">T * fetch_add( difference_type , memory_order = memory_order_seq_cst) const noexcept;</div>
<div class="line">T * fetch_sub( difference_type , memory_order = memory_order_seq_cst) const noexcept;</div>
<div class="line"><br /></div>
<div class="line">~atomic_ref();</div>
<div class="line">atomic_ref() = delete ;</div>
<div class="line">atomic_ref( const atomic_ref &amp; ) = delete ;</div>
<div class="line">atomic_ref &amp; operator = ( const atomic_ref &amp; ) = delete ;</div>
<div class="line"><br /></div>
<div class="line">explicit atomic_ref( T * &amp; obj ); // <em>wrapping</em> constructor</div>
<div class="line"><br /></div>
<div class="line">T * operator=( T * ) const noexcept ;</div>
<div class="line">T * operator++(int) const noexcept;</div>
<div class="line">T * operator--(int) const noexcept;</div>
<div class="line">T * operator++() const noexcept;</div>
<div class="line">T * operator--() const noexcept;</div>
<div class="line">T * operator+=( difference_type ) const noexcept;</div>
<div class="line">T * operator-=( difference_type ) const noexcept;</div>
</div>
<div class="line">};</div>
</div>
</blockquote>
</div>
<div class="section" id="add-to-partial-specializations-for-elements-of-array-of-unknown-bound">
<h2><em>add to</em> Partial specializations for elements of array of unknown bound</h2>
<p>Performing compatibility verification within the atomic reference
wrapping constructor for many elements in an array can introduce
unecessary, redundant operations.
The <em>atomic array reference</em> partial specialization wraps the entire array
such that compatibility verification can be performed once and
amortized among all atomic references to members of that array.</p>
<blockquote>
<div class="line-block">
<div class="line">template&lt; class T &gt; struct atomic_ref&lt; T[] &gt; {</div>
<div class="line"><br /></div>
<div class="line-block">
<div class="line">static constexpr size_t required_alignment = <em>implementation defined</em> ;</div>
<div class="line">static constexpr bool is_always_lock_free = <em>implementation defined</em> ;</div>
<div class="line">bool is_lock_free() const noexcept ;</div>
<div class="line"><br /></div>
<div class="line">atomic_ref() = delete ;</div>
<div class="line">atomic_ref( const atomic_ref &amp; ) = delete ;</div>
<div class="line">atomic_ref &amp; operator = ( const atomic_ref &amp; ) = delete ;</div>
<div class="line"><br /></div>
<div class="line">atomic_array_ref( T * , size_t ); // wrapping constructor</div>
<div class="line"><br /></div>
<div class="line">size_t size() const noexcept ;</div>
<div class="line"><br /></div>
<div class="line">atomic_ref&lt;T&gt; operator[]( size_t ) const noexcept;</div>
</div>
<div class="line">};</div>
</div>
</blockquote>
<p><strong>atomic_ref( T * array , size_t length );</strong></p>
<blockquote>
<p>This wrapping constructor constructs an <tt class="docutils literal"><span class="pre">atomic_ref&lt;T[]&gt;</span></tt>
that references an array of non-atomic elements
spanning <tt class="docutils literal"><span class="pre">[array..array+length)</span></tt>.</p>
<p><em>Requires:</em> The referenced non-atomic array shall be
aligned to <tt class="docutils literal">required_alignment</tt>.
The lifetime (3.8) of <tt class="docutils literal">*this</tt>
shall not exceed the lifetime of the referenced non-atomic array.
All <tt class="docutils literal"><span class="pre">atomic_ref&lt;T[]&gt;</span></tt> instances that reference any element of
the array shall reference the same span of the array.
As long as any <tt class="docutils literal"><span class="pre">atomic_ref&lt;T[]&gt;</span></tt> instance exists that references
array all accesses to members of that array shall exclusively occur
through those <tt class="docutils literal"><span class="pre">atomic_ref&lt;T[]&gt;</span></tt> instances.
No element of array is concurrently wrap constructed by an
<tt class="docutils literal">atomic_ref&lt;T&gt;</tt>.
[Note: Other implementation dependent conditions may exist. - end note]</p>
<p><em>Effects:</em> <tt class="docutils literal">*this</tt> references the non-atomic array.
Atomic operations on members of array are atomic with respect
to atomic operations on members referenced through any other
<tt class="docutils literal"><span class="pre">atomic_ref&lt;T[]&gt;</span></tt> instance.
[Note: The <em>wrapping constructor</em> may acquire shared resources,
such as a locks associated with the referenced array,
to enable atomic operations applied to the referenced
non-atomic members of referenced array. - end note]</p>
</blockquote>
<p><strong>atomic_ref&lt;T&gt; operator[]( size_t i ) const noexcept ;</strong></p>
<blockquote>
<p><em>Requires:</em> <tt class="docutils literal">i &lt; size()</tt> and the lifetime of the returned
<tt class="docutils literal">atomic_ref&lt;T&gt;</tt> shall not exceed the lifetime of the
associated <tt class="docutils literal"><span class="pre">atomic_ref&lt;T[]&gt;</span></tt>.
[Note: Analogous to the lifetime of an iterator with respect to the
lifetime of the associated container. - end note]</p>
<p>Example usage:</p>
</blockquote>
<pre class="code c++ literal-block">
<span class="comment single">// atomic reference wrapper constructor:
</span><span class="name">atomic_ref</span><span class="operator">&lt;</span><span class="name">T</span><span class="punctuation">[]</span><span class="operator">&gt;</span> <span class="name">array</span><span class="punctuation">(</span> <span class="name">ptr</span> <span class="punctuation">,</span> <span class="name">N</span> <span class="punctuation">);</span>

<span class="comment single">// atomic operation on a member:
</span><span class="name">array</span><span class="punctuation">[</span><span class="name">i</span><span class="punctuation">].</span><span class="name">atomic</span><span class="operator">-</span><span class="name">operation</span><span class="punctuation">(...);</span>

<span class="comment single">// atomic operations through a temporary value
// within a concurrent function:
</span><span class="keyword">auto</span> <span class="name">x</span> <span class="operator">=</span> <span class="name">array</span><span class="punctuation">[</span><span class="name">i</span><span class="punctuation">];</span>
<span class="name">x</span><span class="punctuation">.</span><span class="name">atomic</span><span class="operator">-</span><span class="name">operation</span><span class="operator">-</span><span class="name">a</span><span class="punctuation">(...);</span>
<span class="name">x</span><span class="punctuation">.</span><span class="name">atomic</span><span class="operator">-</span><span class="name">operation</span><span class="operator">-</span><span class="name">b</span><span class="punctuation">(...);</span>
</pre>
<!--  -->
</div>
</div>
</div>
</body>
</html>
