<?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>P0019r00 : Atomic View</title>
<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" />
<meta name="date" content="2015-09-23" />
<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="p0019r00-atomic-view">
<h1 class="title">P0019r00 : Atomic View</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<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">Number:</th><td class="field-body">P0019</td>
</tr>
<tr><th class="docinfo-name">Version:</th>
<td>00</td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2015-09-23</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>
<tr class="field"><th class="docinfo-name">WG21:</th><td class="field-body">SG1 Concurrency</td>
</tr>
</tbody>
</table>
<div class="section" id="introduction">
<h1>1&nbsp;&nbsp;&nbsp;Introduction</h1>
<p>This paper proposes an extension to the atomic operations library [atomics]
for atomic operations applied to non-atomic objects.
The proposal is in five parts:
(1) the concept of an atomic view,
(2) application of this concept applied to single objects,
(3) application of this concept applied to members of a very large array,
(4) application of this concept applied to an object in a large
legacy code which cannot replace that object with a corresponding atomic&lt;T&gt; object,
and
(5) motivating use cases and illustrative examples.</p>
<blockquote>
<div class="line-block">
<div class="line">namespace std {</div>
<div class="line">namespace experimental {</div>
<div class="line-block">
<div class="line">template&lt; class T &gt; atomic_view ;</div>
<div class="line">template&lt; class T &gt; atomic_array_view ;</div>
<div class="line">template&lt; class T &gt; atomic_global_view ;</div>
</div>
<div class="line">}}</div>
</div>
</blockquote>
<div class="section" id="set-of-transitive-copies-and-its-originating-instance">
<h2>1.1&nbsp;&nbsp;&nbsp;Set of Transitive Copies and its Originating Instance</h2>
<dl class="docutils">
<dt><em>Definition</em>: <strong>Set of Transitive Copies</strong></dt>
<dd>An instance ‘b’ of type T is a <strong>transitive copy</strong> of an instance ‘a’
of the same type if-and-only-if ‘b’ is copy constructed from ‘a’,
assigned from ‘a’, copy constructed from a transitive copy of ‘a’,
or assigned from a transitive copy of ‘a’.
An instance is removed from its <em>set of transitive copies</em> when it is destroyed,
reset to an unassigned state, or assigned into a different <em>set of transitive copies</em>.</dd>
<dt><em>Definition</em>: <strong>Originating Instance</strong></dt>
<dd>A <em>set of transitive copies</em> has an <strong>originating instance</strong>
from which all other members are transitively copy constructed or assigned.</dd>
</dl>
<p>For example, instances of <strong>std::shared_ptr&lt;T&gt;</strong> that share ownership of a given object form a set of transitive copies.</p>
</div>
<div class="section" id="applicability-to-atomic-view">
<h2>1.2&nbsp;&nbsp;&nbsp;Applicability to Atomic View</h2>
<p>Operations provided through an <strong>atomic_view&lt;T&gt;</strong> instance
are guaranteed atomic [1.10, Multi-threaded executions and data races]
only with respect to operations performed through members of
the <em>set of transitive copies</em> of <strong>atomic_view&lt;T&gt;</strong> to which the instance belongs.</p>
<p>Operations provided through an <strong>atomic_array_view&lt;T&gt;</strong> instance
are guaranteed atomic [1.10, Multi-threaded executions and data races]
only with respect to operations performed through members of
the <em>set of transitive copies</em> of atomic_array_view&lt;T&gt; to which the instance belongs.</p>
</div>
</div>
<div class="section" id="atomic-view-concept">
<h1>2&nbsp;&nbsp;&nbsp;Atomic View Concept</h1>
<p>A class conforming to the atomic view concept
provides atomic operations for the viewed non-atomic object.
These operations replicate the operations on <strong>std::atomic&lt;T&gt;</strong> [29.5, Atomic types];
however, operations are const with respect to the atomic view object
in contrast to the non-const and volatile operations of a <strong>std::atomic&lt;T&gt;</strong> object.
An atomic view does not own (neither exclusively nor shared) the viewed non-atomic object.</p>
<p>The following <em>atomic-view-concept</em> specification is included to define requirements
for classes conforming to the <em>atomic-view-concept</em> and does not imply the existiance
of a template class of this name.</p>
<blockquote>
<div class="line-block">
<div class="line">template&lt; class T &gt;</div>
<div class="line">struct <em>atomic-view-concept</em> {</div>
<div class="line-block">
<div class="line">// Functionality matches corresponding member of atomic&lt;T&gt;</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">T operator=(T) const noexcept ;</div>
<div class="line"><br /></div>
<div class="line">// Functionality that may exist and deviate from corresponding member of atomic&lt;T&gt;, if any.</div>
<div class="line"><em>atomic-view-concept</em> ();</div>
<div class="line"><em>atomic-view-concept</em> ( const <em>atomic-view-concept</em> &amp; );</div>
<div class="line"><em>atomic-view-concept</em> ( <em>atomic-view-concept</em> &amp;&amp; );</div>
<div class="line"><em>atomic-view-concept</em> &amp; operator = ( const <em>atomic-view-concept</em> &amp; );</div>
<div class="line"><em>atomic-view-concept</em> &amp; operator = ( <em>atomic-view-concept</em> &amp;&amp; );</div>
<div class="line"><br /></div>
<div class="line">constexpr explicit bool operator() const noexcept;</div>
</div>
<div class="line">};</div>
</div>
</blockquote>
<p>Constructors and assignment operators of an <em>atomic-view-concept</em> may acquire resources
such as concurrent locks to support atomic operations on the non-atomic object, and
may track membership in a <strong>set of transitive copies</strong> for the purpose of
sharing those resources.</p>
<p><strong>constexpr explict bool operator() const noexept ;</strong></p>
<blockquote>
Returns if the <em>atomic-view-concept</em> object views an object.
A default constructed <em>atomic-view-concept</em> object returns false.</blockquote>
<p>A class conforming to the atomic view concept shall provide the
following operations when T is an integral type.
These operations replicate the operations on <em>std::atomic&lt;integral&gt;</em> [29.5, Atomic types];
however, operations are const with respect to the atomic view object
in contrast to the non-const and volatile operations of a <strong>std::atomic&lt;integral&gt;</strong> object.</p>
<blockquote>
<div class="line-block">
<div class="line">template&lt;&gt; struct <em>atomic-view-concept</em> &lt; <em>integral</em> &gt; {</div>
<div class="line"><br /></div>
<div class="line-block">
<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"><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>
<p>Note that for consistency the <em>atomic-view-concept</em><strong>&lt;</strong><em>integral</em><strong>&gt;</strong>
mathematical operator overloads retain the same mathematical inconsistency
with respect to the mathematical operators for the <em>integral</em> type,
as illustrated below.</p>
<pre class="code c++ literal-block">
<span class="keyword type">int</span> <span class="name function">i</span><span class="punctuation">(</span><span class="literal number integer">0</span><span class="punctuation">)</span>
<span class="operator">++</span><span class="punctuation">(</span> <span class="operator">++</span><span class="name">i</span> <span class="punctuation">);</span>        <span class="comment single">// ++i returns an lvalue
</span><span class="punctuation">(</span> <span class="name">i</span> <span class="operator">+=</span> <span class="literal number integer">1</span> <span class="punctuation">)</span> <span class="operator">+=</span> <span class="literal number integer">2</span> <span class="punctuation">;</span> <span class="comment single">// i+= returns an lvalue
</span>
<span class="name">std</span><span class="operator">::</span><span class="name">atomic</span><span class="operator">&lt;</span><span class="keyword type">int</span><span class="operator">&gt;</span> <span class="name">ai</span><span class="punctuation">(</span><span class="literal number integer">0</span><span class="punctuation">);</span>
<span class="operator">++</span><span class="punctuation">(</span> <span class="operator">++</span><span class="punctuation">(</span> <span class="name">ai</span> <span class="punctuation">)</span> <span class="punctuation">);</span>    <span class="comment single">// error: ++ai returns an rvalue
</span><span class="punctuation">(</span> <span class="name">ai</span> <span class="operator">+=</span> <span class="literal number integer">1</span> <span class="punctuation">)</span> <span class="operator">+=</span> <span class="literal number integer">2</span> <span class="punctuation">;</span> <span class="comment single">// error: ai+= returns an rvalue</span>
</pre>
<!--  -->
</div>
<div class="section" id="atomic-view-for-a-single-object">
<h1>3&nbsp;&nbsp;&nbsp;Atomic View for a Single Object</h1>
<p>An <strong>atomic_view&lt;T&gt;</strong> object is used to perform
atomic operations on the viewed non-atomic object.
The intent is for <strong>atomic_view&lt;T&gt;</strong> to provide the
best-performing implementation of <em>atomic-view-concept</em> operations for the type T.</p>
<blockquote>
<div class="line-block">
<div class="line">template&lt; class T &gt; struct atomic_view { // conforms to atomic view concept</div>
<div class="line"><br /></div>
<div class="line-block">
<div class="line">explicit atomic_view( T &amp; ); // Originating Constructor is NOT noexcept</div>
<div class="line"><br /></div>
<div class="line">atomic_view();</div>
<div class="line">atomic_view( atomic_view &amp;&amp; ) noexcept ;</div>
<div class="line">atomic_view( const atomic_view &amp; ) noexcept ;</div>
<div class="line">atomic_view &amp; operator = ( const atomic_view &amp; ) noexcept ;</div>
<div class="line">~atomic_view() noexcept ;</div>
</div>
<div class="line">};</div>
</div>
</blockquote>
<p>[Note: The intent is for atomic operations of
<em>atomic_view&lt;T&gt;</em> to directly update the referenced object.
The set of transitive copies of <em>atomic_view&lt;T&gt;</em>
may require a resource, such as a locking mechanism, to perform atomic operations.
The intent is to enable amortization of the time and space overhead of
obtaining and releasing such a resource.
– end note]</p>
<p><strong>atomic_view&lt;T&gt;::atomic_view( T &amp; obj );</strong></p>
<blockquote>
<p>Requires: The referenced obj must be properly aligned for its type T, otherwise behavior is undefined.</p>
<p>Effects: This originating constructor wraps the referenced object.
The constructed instance is the originating member of a
<strong>set of transitive copies</strong> of <strong>atomic_view&lt;T&gt;</strong>.
[Note: This constructor may obtain a resource as necessary to support atomic operations.
The originating constructor is allowed to throw an exception if such a resource could not be obtained.
– end note]</p>
</blockquote>
<p><strong>atomic_view&lt;T&gt;::atomic_view( const atomic_view &amp; rhs ) noexcept ;</strong></p>
<blockquote>
Effects: If rhs is a member of a set of transitive copies of atomic_view&lt;T&gt; the copy constructed instance is a member of that set.</blockquote>
<p><strong>atomic_view&lt;T&gt;::~atomic_view() noexcept ;</strong></p>
<blockquote>
Effects: If this instance is a member of a <em>set of transitive copies</em>
then this instance is removed from the set.
[Note: If the set will become empty then a resource shared by that set should be released. – end note]</blockquote>
<p><strong>atomic_view&lt;T&gt; &amp; atomic_view&lt;T&gt;::operator = ( const atomic_view &amp; rhs ) noexcept ;</strong></p>
<blockquote>
Effects: If this instance is a member of a <em>set of transitive copies</em>
then that instance is removed from the set.
[Note: If the set will become empty then a resource shared by that set should be released. – end note]
If rhs is a member of a set of transitive copies of <strong>atomic_view&lt;T&gt;</strong> the copy constructed instance is a member of that set.</blockquote>
</div>
<div class="section" id="atomic-view-for-a-very-large-array">
<h1>4&nbsp;&nbsp;&nbsp;Atomic View for a Very Large Array</h1>
<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 <strong>atomic_array_view&lt;T&gt;</strong> object is used to perform
atomic operations on the viewed non-atomic members of the array.
The intent is for <strong>atomic_array_view&lt;T&gt;</strong> to provide the
best-performing implementation of atomic-view-concept operations for the members of the array.</p>
<blockquote>
<div class="line-block">
<div class="line">template&lt; class T &gt; struct atomic_array_view {</div>
<div class="line"><br /></div>
<div class="line-block">
<div class="line">bool is_lock_free() const noexcept ;</div>
<div class="line"><br /></div>
<div class="line">// Returns true if the view wraps an array and member access is valid.</div>
<div class="line">explicit bool operator() const noexcept ;</div>
<div class="line"><br /></div>
<div class="line">atomic_array_view( T * , size_t ); // Originating Constructor is NOT noexcept</div>
<div class="line">atomic_array_view() noexcept ;</div>
<div class="line">atomic_array_view( atomic_array_view &amp;&amp; ) noexcept ;</div>
<div class="line">atomic_array_view( const atomic_array_view &amp; ) noexcept ;</div>
<div class="line">atomic_array_view &amp; operator = ( const atomic_array_view &amp; ) noexcept ;</div>
<div class="line">~atomic_array_view() noexcept ;</div>
<div class="line"><br /></div>
<div class="line">size_t size() const noexcept ;</div>
<div class="line"><br /></div>
<div class="line">typedef  implementation-defined-atomic-view-concept-type  reference ;</div>
<div class="line"><br /></div>
<div class="line">reference operator[]( size_t ) const noexcept ;</div>
</div>
<div class="line">};</div>
</div>
</blockquote>
<p>[Note: The intent is for atomic operations on members of
<strong>atomic_array_view&lt;T&gt;</strong> to directly update the referenced member.
The <em>set of transitive copies</em> of <strong>atomic_array_view&lt;T&gt;</strong> may require resources,
such as locking mechanisms, to perform atomic operations.
The intent is to enable amortization of the time and space overhead
of obtaining and releasing such resources. – end note]</p>
<p><strong>typedef</strong> <em>implementation-defined-atomic-view-concept-type</em> <strong>reference;</strong></p>
<blockquote>
The <strong>reference</strong> type conforms to <em>atomic-view-concept</em> for type T.</blockquote>
<p><strong>bool atomic_array_view&lt;T&gt;::is_lock_free() const noexcept ;</strong></p>
<blockquote>
Effects: Returns whether atomic operations on members are lock free.</blockquote>
<p><strong>atomic_array_view&lt;T&gt;::atomic_array_view( T * ptr , size_t N );</strong></p>
<blockquote>
<p>Requires: The array referenced by [ptr .. ptr+N-1] must be properly aligned for its type T, otherwise behavior is undefined.</p>
<p>Effects: This <em>originating constructor</em> wraps the referenced array [ptr .. ptr+N-1].
The constructed instance is the originating member of a <em>set of transitive copies</em>
of atomic_array_view&lt;T&gt;.
[Note: This constructor may obtain resources as necessary to support atomic operations.
The originating constructor is allowed to throw an exception if such resources could not be obtained. – end note]</p>
</blockquote>
<p><strong>atomic_array_view&lt;T&gt;::atomic_array_view( const atomic_array_view &amp; rhs ) noexcept ;</strong></p>
<blockquote>
Effects: If rhs is a member of a set of transitive copies of atomic_array_view&lt;T&gt; the copy constructed instance is a member of that set.</blockquote>
<p><strong>atomic_array_view&lt;T&gt;::~atomic_array_view() noexcept ;</strong></p>
<blockquote>
Effects: If this instance is a member of a set of transitive copies this instance is removed from the set. [Note: If the set will become empty then resources shared by that set should be released. – end note]</blockquote>
<p><strong>atomic_array_view&lt;T&gt; &amp; atomic_array_view&lt;T&gt;::operator = ( const atomic_array_view &amp; rhs ) noexcept ;</strong></p>
<blockquote>
Effects: If this instance is a member of a set of transitive copies that instance is removed from the set.
[Note: If the set will become empty then resources shared by that set should be released. – end note]
If rhs is a member of a set of transitive copies of atomic_array_view&lt;T&gt; the copy constructed instance is a member of that set.</blockquote>
<p><strong>atomic_array_view&lt;T&gt;::reference  atomic_array_view&lt;T&gt;::operator[]( size_t i ) const noexcept ;</strong></p>
<blockquote>
<p>Requires: The index i must be in the range [0 .. N-1], otherwise behavior is undefined.</p>
<p>Effects: Return an instance of <strong>reference</strong> type for the member object referenced by the input index i.
[Note: The intent is for efficient generation of the returned instance with respect to obtaining a resource,
such as a shared locking mechanism, that may be required to support atomic operations on the referenced member. – end note]</p>
</blockquote>
</div>
<div class="section" id="atomic-global-views-for-a-single-non-atomic-object">
<h1>5&nbsp;&nbsp;&nbsp;Atomic Global Views for a Single Non-atomic Object</h1>
<p>An <strong>atomic_global_view&lt;T&gt;</strong> object is used to perform
atomic operations on the globally accessible viewed non-atomic object.
The intent is for <strong>atomic_global_view&lt;T&gt;</strong> to provide the best-performing
implementation of <em>atomic-view-concept</em> operations for the type T.
All atomic operations on an instance of <strong>atomic_global_view&lt;T&gt;</strong>
are atomic with respect to any other instance that views the same
globally accessible object, as defined by equality of pointers to that object.</p>
<p>[Note: Introducing concurrency within legacy codes may require
replacing operations on existing non-atomic objects with atomic operations.
Such replacement may not be able to introduce a set of transitive copies of atomic_view&lt;T&gt;. – end note]</p>
<blockquote>
<div class="line-block">
<div class="line">template&lt; class T &gt; struct atomic_global_view { // conforms to atomic view concept</div>
<div class="line"><br /></div>
<div class="line-block">
<div class="line">atomic_global_view( T &amp; );  // Wrapping constructor is NOT noexcept</div>
<div class="line">atomic_global_view( const atomic_global_view &amp; ) noexcept ;</div>
<div class="line">atomic_global_view( atomic_global_view &amp;&amp; ) noexcept ;</div>
<div class="line">~atomic_global_view() noexcept ;</div>
<div class="line"><br /></div>
<div class="line">atomic_global_view() = delete ;</div>
<div class="line">atomic_global_view &amp; operator = ( const atomic_concurrent__view &amp; ) = delete ;</div>
</div>
<div class="line">};</div>
</div>
</blockquote>
<p>[Note: The intent is for atomic operations of <strong>atomic_global_view&lt;T&gt;</strong> to directly update the referenced object. – end note]</p>
<p><strong>atomic_global_view&lt;T&gt;::atomic_global_view( T &amp; obj );</strong></p>
<blockquote>
<p>Requires: The referenced obj must be properly aligned for its type T, otherwise behavior is undefined.</p>
<p>Effects: This wrapping constructor wraps the globally accessible referenced object.
Atomic operations on this instance are atomic with respect to atomic operations
on any <strong>atomic_global_view&lt;T&gt;</strong> instance that reference the same globally accessible object.
[Note: This constructor may obtain a resource as necessary to support atomic operations.
This constructor is allowed to throw an exception if such a resource could not be obtained. – end note]</p>
</blockquote>
<div class="line-block">
<div class="line"><strong>atomic_global_view&lt;T&gt;::atomic_global_view( const atomic_global_view &amp; ) noexcept ;</strong></div>
<div class="line"><strong>atomic_global_view&lt;T&gt; &amp; atomic_global_view&lt;T&gt;::operator = ( const atomic_global_view &amp; ) noexcept ;</strong></div>
</div>
<blockquote>
Effects: If rhs references a globally accessible object then this instance references the same object otherwise this instance does not reference a globally accessible object.</blockquote>
<p><strong>atomic_global_view&lt;T&gt;::~atomic_global_view() noexcept ;</strong></p>
<blockquote>
Effects: This instance does not reference a globally accessible object.</blockquote>
</div>
<div class="section" id="notes-and-examples">
<h1>6&nbsp;&nbsp;&nbsp;Notes and Examples</h1>
<div class="section" id="atomic-view">
<h2>6.1&nbsp;&nbsp;&nbsp;Atomic View</h2>
<p>All non-atomic accesses of the wrapped object that appear before
the wrapping constructor must happen before subsequent
atomic operations on the atomic_view.  For example:</p>
<pre class="code c++ literal-block">
<span class="keyword type">void</span> <span class="name function">foo</span><span class="punctuation">(</span> <span class="keyword type">int</span> <span class="operator">&amp;</span> <span class="name">i</span> <span class="punctuation">)</span> <span class="punctuation">{</span>
  <span class="name">i</span> <span class="operator">=</span> <span class="literal number integer">42</span> <span class="punctuation">;</span>
  <span class="name">atomic_view</span><span class="operator">&lt;</span><span class="keyword type">int</span><span class="operator">&gt;</span> <span class="name">ai</span><span class="punctuation">(</span><span class="name">i</span><span class="punctuation">);</span>
  <span class="comment single">// Operations on ‘i’ must happen before operations on ‘ai’
</span>  <span class="name">foreach</span><span class="punctuation">(</span> <span class="name">parallel_policy</span><span class="punctuation">,</span> <span class="literal number integer">0</span><span class="punctuation">,</span> <span class="name">N</span><span class="punctuation">,</span> <span class="punctuation">[</span><span class="operator">=</span><span class="punctuation">](){</span> <span class="operator">++</span><span class="name">ai</span> <span class="punctuation">;</span> <span class="punctuation">}</span> <span class="punctuation">);</span>
<span class="punctuation">}</span>
</pre>
<!--  -->
</div>
<div class="section" id="atomic-array-view">
<h2>6.2&nbsp;&nbsp;&nbsp;Atomic Array View</h2>
<p>Under the HPC use case the member access operator,
proxy type constructor, or proxy type destructor
will be frequently invoked; therefore,
an implementation should trade off decreased overhead
in these operations versus increased overhead in the wrapper constructor and final destructor.</p>
<p>Usage Scenario for <strong>atomic_array_view&lt;T&gt;</strong></p>
<ol class="loweralpha simple">
<li>A very large array of trivially copyable members is allocated.</li>
<li>A parallel algorithm initializes members through non-conflicting assignments.</li>
<li>The array is wrapped by an atomic_array_view&lt;T&gt;.</li>
<li>One or more parallel algorithms update members of the array through atomic view operations.</li>
<li>The atomic_array_view&lt;T&gt; is destructed.</li>
<li>Parallel algorithms access array members through non-conflicting reads, writes, or updates.</li>
</ol>
<p>Example:</p>
<pre class="code c++ literal-block">
<span class="comment single">// atomic array view wrapper constructor:
</span><span class="name">atomic_array_view</span><span class="operator">&lt;</span><span class="name">T</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="name">atomic_array_view</span><span class="operator">&lt;</span><span class="name">T</span><span class="operator">&gt;::</span><span class="name">reference</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>
<!--  -->
<p>Possible interface for <strong>atomic_array_view&lt;T&gt;::reference</strong></p>
<pre class="code c++ literal-block">
<span class="keyword">struct</span> <span class="name">implementation</span><span class="operator">-</span><span class="name">defined</span><span class="operator">-</span><span class="name">proxy</span><span class="operator">-</span><span class="name">type</span> <span class="punctuation">{</span>   <span class="comment single">// conforms to atomic view concept
</span>
  <span class="comment single">// Construction limited to move
</span>  <span class="name">implementation</span><span class="operator">-</span><span class="name">defined</span><span class="operator">-</span><span class="name">proxy</span><span class="operator">-</span><span class="name">type</span><span class="punctuation">(</span><span class="name">implementation</span><span class="operator">-</span><span class="name">defined</span><span class="operator">-</span><span class="name">proxy</span><span class="operator">-</span><span class="name">type</span> <span class="operator">&amp;&amp;</span> <span class="punctuation">)</span> <span class="operator">=</span> <span class="keyword">noexcept</span> <span class="punctuation">;</span>
  <span class="operator">~</span><span class="name">implementation</span><span class="operator">-</span><span class="name">defined</span><span class="operator">-</span><span class="name">proxy</span><span class="operator">-</span><span class="name">type</span><span class="punctuation">();</span>

  <span class="name">implementation</span><span class="operator">-</span><span class="name">defined</span><span class="operator">-</span><span class="name">proxy</span><span class="operator">-</span><span class="name">type</span><span class="punctuation">()</span> <span class="operator">=</span> <span class="keyword">delete</span> <span class="punctuation">;</span>
  <span class="name">implementation</span><span class="operator">-</span><span class="name">defined</span><span class="operator">-</span><span class="name">proxy</span><span class="operator">-</span><span class="name">type</span><span class="punctuation">(</span> <span class="keyword">const</span> <span class="name">implementation</span><span class="operator">-</span><span class="name">defined</span><span class="operator">-</span><span class="name">proxy</span><span class="operator">-</span><span class="name">type</span> <span class="operator">&amp;</span> <span class="punctuation">)</span> <span class="operator">=</span> <span class="keyword">delete</span> <span class="punctuation">;</span>
  <span class="name">implementation</span><span class="operator">-</span><span class="name">defined</span><span class="operator">-</span><span class="name">proxy</span><span class="operator">-</span><span class="name">type</span> <span class="operator">&amp;</span>
    <span class="keyword">operator</span> <span class="operator">=</span> <span class="punctuation">(</span> <span class="keyword">const</span> <span class="name">implementation</span><span class="operator">-</span><span class="name">defined</span><span class="operator">-</span><span class="name">proxy</span><span class="operator">-</span><span class="name">type</span> <span class="operator">&amp;</span> <span class="punctuation">)</span> <span class="operator">=</span> <span class="keyword">delete</span> <span class="punctuation">;</span>
<span class="punctuation">};</span>
</pre>
<!--  -->
<p>Originating constructor options for <strong>atomic_array_view&lt;T&gt;</strong></p>
<blockquote>
A originating constructor of the form (T*begin, T*end) could be valid.  However, the (T*ptr, size_t N) version is preferred to minimize potential confusion with construction from non-contiguous iterators.  Wrapping constructors for standard contiguous containers would also be valid.  However, such constructors could have potential confusion as to whether the atomic_array_view would or would not track resizing operations applied to the input container.</blockquote>
<p>Implementation note for <strong>atomic_array_view&lt;T&gt;</strong></p>
<blockquote>
All non-atomic accesses of array members that appear before the wrapping constructor must happen before subsequent atomic operations on the atomic_array_view members.  For example:</blockquote>
<pre class="code c++ literal-block">
<span class="keyword type">void</span> <span class="name function">foo</span><span class="punctuation">(</span> <span class="keyword type">int</span> <span class="operator">*</span> <span class="name">i</span> <span class="punctuation">,</span> <span class="keyword type">size_t</span> <span class="name">N</span> <span class="punctuation">)</span> <span class="punctuation">{</span>
  <span class="name">i</span><span class="punctuation">[</span><span class="literal number integer">0</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="literal number integer">42</span> <span class="punctuation">;</span>
  <span class="name">i</span><span class="punctuation">[</span><span class="name">N</span><span class="operator">-</span><span class="literal number integer">1</span><span class="punctuation">]</span> <span class="operator">=</span> <span class="literal number integer">42</span> <span class="punctuation">;</span>
  <span class="name">atomic_array_view</span><span class="operator">&lt;</span><span class="keyword type">int</span><span class="operator">&gt;</span> <span class="name">ai</span><span class="punctuation">(</span><span class="name">i</span><span class="punctuation">,</span><span class="name">N</span><span class="punctuation">);</span>
  <span class="comment single">// Operations on ‘i’ must happen before operations on ‘ai’
</span>  <span class="name">foreach</span><span class="punctuation">(</span> <span class="name">parallel_policy</span><span class="punctuation">,</span> <span class="literal number integer">0</span><span class="punctuation">,</span> <span class="name">M</span><span class="punctuation">,</span> <span class="punctuation">[</span><span class="operator">=</span><span class="punctuation">](</span> <span class="keyword type">int</span> <span class="name">j</span> <span class="punctuation">){</span> <span class="operator">++</span><span class="name">ai</span><span class="punctuation">[</span><span class="name">j</span><span class="operator">%</span><span class="name">N</span><span class="punctuation">]</span> <span class="punctuation">;</span> <span class="punctuation">}</span> <span class="punctuation">);</span>
<span class="punctuation">}</span>
</pre>
<!--  -->
</div>
<div class="section" id="atomic-global-view">
<h2>6.3&nbsp;&nbsp;&nbsp;Atomic Global View</h2>
<p>All non-atomic accesses of the wrapped object that appear before the wrapping constructor must happen before subsequent atomic operations on the atomic_view.  For example:</p>
<pre class="code c++ literal-block">
<span class="keyword type">void</span> <span class="name function">foo</span><span class="punctuation">(</span> <span class="keyword type">int</span> <span class="operator">&amp;</span> <span class="name">i</span> <span class="punctuation">)</span> <span class="punctuation">{</span>
  <span class="name">i</span> <span class="operator">=</span> <span class="literal number integer">42</span> <span class="punctuation">;</span>
  <span class="comment single">// Operations on ‘i’ must happen before operations on ‘ai’
</span>  <span class="name">foreach</span><span class="punctuation">(</span> <span class="name">parallel_policy</span><span class="punctuation">,</span> <span class="literal number integer">0</span><span class="punctuation">,</span> <span class="name">N</span><span class="punctuation">,</span> <span class="punctuation">[</span><span class="operator">=</span><span class="punctuation">](){</span> <span class="operator">++</span><span class="name">atomic_global_view</span><span class="operator">&lt;</span><span class="name">ai</span><span class="operator">&gt;</span><span class="punctuation">(</span><span class="name">i</span><span class="punctuation">)</span> <span class="punctuation">;</span> <span class="punctuation">}</span> <span class="punctuation">);</span>
<span class="punctuation">}</span>
</pre>
<!--  -->
<p>Example:</p>
<pre class="code c++ literal-block">
<span class="comment single">// atomic operation on an object:
</span><span class="name">atomic_global_view</span><span class="operator">&lt;</span><span class="name">T</span><span class="operator">&gt;</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="punctuation">(...);</span>

<span class="comment single">// When multiple atomic operations are performed the cost of
// constructing and destructing the atomic view can be amortized
// through a temporary atomic view object.
</span><span class="punctuation">{</span>
  <span class="name">atomic_global_view</span> <span class="name">ax</span><span class="punctuation">(</span><span class="name">x</span><span class="punctuation">);</span>
  <span class="name">ax</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">ax</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>
<span class="punctuation">}</span>
</pre>
<!--  -->
</div>
<div class="section" id="mathematically-consistent-integral-operator-overloads">
<h2>6.4&nbsp;&nbsp;&nbsp;Mathematically Consistent Integral Operator Overloads</h2>
<p>As previously noted the <strong>std::atomic&lt;</strong><em>integral</em><strong>&gt;</strong>
mathematical operator overloads are inconsistent with the mathematical
operators for <em>integral</em>.
The <em>atomic-view-concept</em><strong>&lt;</strong><em>integral</em><strong>&gt;</strong> retains these inconsistent
operator overloads.
Consistent mathematical operator semantics would be restored with the following
operator specifications.
However, such a change would break backward compatibility and is therefore
only noted and not a proposed change.</p>
<div class="line-block">
<div class="line">template&lt;&gt; struct atomic &lt; <em>integral</em> &gt; {</div>
<div class="line"><br /></div>
<div class="line-block">
<div class="line">volatile atomic &amp; operator++(int) volatile noexcept ;</div>
<div class="line">atomic &amp; operator++(int) noexcept ;</div>
<div class="line">volatile atomic &amp; operator--(int) volatile noexcept ;</div>
<div class="line">atomic &amp; operator--(int) noexcept ;</div>
<div class="line"><br /></div>
<div class="line">// fetch-and-increment, fetch-and-decrement operators:</div>
<div class="line"><em>integral</em> operator++() volatile noexcept ;</div>
<div class="line"><em>integral</em> operator++() noexcept ;</div>
<div class="line"><em>integral</em> operator--() volatile noexcept ;</div>
<div class="line"><em>integral</em> operator--() noexcept ;</div>
<div class="line"><br /></div>
<div class="line">volatile atomic &amp; operator+=( <em>integral</em> ) volatile noexcept;</div>
<div class="line">atomic &amp; operator+=( <em>integral</em> ) noexcept;</div>
<div class="line">volatile atomic &amp; operator-=( <em>integral</em> ) volatile noexcept;</div>
<div class="line">atomic &amp; operator-=( <em>integral</em> ) noexcept;</div>
<div class="line">volatile atomic &amp; operator&amp;=( <em>integral</em> ) volatile noexcept;</div>
<div class="line">atomic &amp; operator&amp;=( <em>integral</em> ) noexcept;</div>
<div class="line">volatile atomic &amp; operator|=( <em>integral</em> ) volatile noexcept;</div>
<div class="line">atomic &amp; operator|=( <em>integral</em> ) noexcept;</div>
<div class="line">volatile atomic &amp; operator^=( <em>integral</em> ) volatile noexcept;</div>
<div class="line">atomic &amp; operator^=( <em>integral</em> ) noexcept;</div>
</div>
<div class="line">};</div>
<div class="line"><br /></div>
<div class="line">template&lt;&gt; struct <em>atomic-view-concept</em> &lt; <em>integral</em> &gt; {</div>
<div class="line"><br /></div>
<div class="line-block">
<div class="line">const <em>atomic-view-concept</em> &amp; operator++(int) const noexcept;</div>
<div class="line">const <em>atomic-view-concept</em> &amp; operator--(int) const noexcept;</div>
<div class="line"><br /></div>
<div class="line"><em>integral</em> operator++() const noexcept;</div>
<div class="line"><em>integral</em> operator--() const noexcept;</div>
<div class="line"><br /></div>
<div class="line">const <em>atomic-view-concept</em> &amp; operator+=( <em>integral</em> ) const noexcept;</div>
<div class="line">const <em>atomic-view-concept</em> &amp; operator-=( <em>integral</em> ) const noexcept;</div>
<div class="line">const <em>atomic-view-concept</em> &amp; operator&amp;=( <em>integral</em> ) const noexcept;</div>
<div class="line">const <em>atomic-view-concept</em> &amp; operator|=( <em>integral</em> ) const noexcept;</div>
<div class="line">const <em>atomic-view-concept</em> &amp; operator^=( <em>integral</em> ) const noexcept;</div>
</div>
<div class="line">};</div>
</div>
</div>
</div>
</div>
</body>
</html>
