<?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>P0019r2 : Atomic View</title>
<meta name="date" content="2016-03-14" />
<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="p0019r2-atomic-view">
<h1 class="title">P0019r2 : 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">P0019r2</td>
</tr>
<tr><th class="docinfo-name">Date:</th>
<td>2016-03-14</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">SG1 Concurrency, Library Evoluton</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="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, and
(4) 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>
<div class="line">}}</div>
</div>
</blockquote>
<p>Note: Feedback from SG1 Library Evolution Working Group (LEWG) on P0009r0,
Polymorphic Multidimensional Array View, noted that the term <em>view</em>
has the connotation of read-only. In response the P0009r0 <em>array_view</em>
name has been revised to <strong>array_ref</strong> in P0009r1.
The proposed names <strong>atomic_view</strong> and <strong>atomic_array_view</strong> may have
the same feedback from LEWG, potentially resulting in a similar
naming revision.</p>
</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 a referenced non-atomic object.
These operations replicate the operations on
<strong>std::atomic&lt;T&gt;</strong> [29.5 Atomic Types and 29.6 Operations on 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 because an atomic view does not own
(neither exclusively nor shared) the referenced non-atomic object.</p>
<p>The following <em>atomic-view-concept</em> specification is
included to define requirements for types conforming
to the <em>atomic-view-concept</em> and does not imply the existance
of a template class of this name.
This specification is to appear in 29.5 Atomic Types.</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">// The following members satisfy the specifications in 29.6 Operations on atomic types,</div>
<div class="line">// with the difference that member functions are non-volatile and const.</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">// The following member corresponds to specification of P0152R0.</div>
<div class="line">static constexpr bool is_always_lock_free = <em>implementation defined</em> ;</div>
<div class="line"><br /></div>
<div class="line">// Alignment requirement for objects of type <em>T</em></div>
<div class="line">static constexpr size_t minimum_required_alignment = <em>implementation defined</em> ;</div>
<div class="line"><br /></div>
<div class="line">// The following member operator does not appear in atomic&lt;T&gt;</div>
<div class="line">// it is similar to the std::unique_ptr operator.</div>
<div class="line">explicit constexpr operator bool () const 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-block">
<div class="line">// The following members satisfy the specifications in 29.6 Operations on atomic types,</div>
<div class="line">// with the difference that member functions are non-volatile and const.</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"><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>
<p>Requires: Type <em>T</em> is trivially copyable.</p>
</blockquote>
<p>Lock-free <em>atomic-view-concept</em> conform to the address-free property as in 29.4p3.</p>
<p>Constructors and assignment operators of non-lock-free <em>atomic-view-concept</em>
may acquire shared resources such as concurrent locks to
support atomic operations on the non-atomic object.</p>
<p><strong>static constexpr size_t minimum_required_alignment</strong></p>
<blockquote>
Requires: An object referenced by an <em>atomic-view-concept</em> shall
be aligned to <strong>minimum_required_alignment</strong>.
[Note: For example, an architecture may be able to support lock-free
<em>atomic-view-concept</em> operations on <strong>std::complex&lt;double&gt;</strong> only
if aligned to 16 bytes. - end note]</blockquote>
<p><strong>explicit constexpr operator bool () const noexept ;</strong></p>
<blockquote>
Returns: true if the <em>atomic-view-concept</em> object wraps a non-null pointer.
A default constructed <em>atomic-view-concept</em> object returns false.</blockquote>
</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 <strong>T</strong>.
All atomic operations on an instance of <strong>atomic_view&lt;T&gt;</strong>
are atomic with respect to any other instance that views the same
object, as defined by equality of pointers to that object.</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 <em>std::atomic</em> object.</p>
<p>An object may be heavily used non-atomically in well-defined phases
of an application.  Forcing such objects to be exclusively <em>std::atomic</em>
would incur an unnecessary performance penalty.</p>
<p>This specification is to appear in a new section 29.# Atomic Views.</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; obj ); // wrapping constructor is NOT noexcept</div>
<div class="line"><br /></div>
<div class="line">constexpr atomic_view() noexcept ;</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 = ( atomic_view &amp;&amp; ) noexcept ;</div>
<div class="line">atomic_view &amp; operator = ( const atomic_view &amp; ) noexcept ;</div>
<div class="line">~atomic_view();</div>
</div>
<div class="line">};</div>
</div>
<p>Requires: Type <em>T</em> is trivially copyable.</p>
</blockquote>
<p>[Note: The intent is for <em>atomic-view-concept</em> operations
to directly update the referenced object.
The <em>wrapping constructor</em> may acquire a resource,
such as a lock from a collection of address-sharded locks,
to perform atomic operations.
Such <strong>atomic_view</strong> 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.
– end note]</p>
<p><strong>constexpr atomic_view&lt;T&gt;::atomic_view() noexcept;</strong></p>
<blockquote>
Effects: This instance does not reference an object and
therefore <strong>operator bool() == false</strong>.</blockquote>
<p><strong>atomic_view&lt;T&gt;::atomic_view( T &amp; obj );</strong></p>
<blockquote>
<p>Requires: The referenced non-atomic object <strong>obj</strong> shall be
aligned to <strong>minimum_required_alignment</strong>.
The lifetime (3.8) of an <strong>atomic_view&lt;T&gt;</strong> instance
shall not exceed the lifetime of the referenced non-atomic object.
Multiple instances of an <em>atomic_view</em> may be constructed
referencing the same object.
All accesses of an <strong>atomic_view</strong> referenced object shall
occur thru an <strong>atomic_view</strong> as long an <strong>atomic_view</strong> exists
that references that object.
If the <strong>atomic_view</strong> wrapped object is of a
class or aggregate type then members of that object
shall not be wrapped by an <strong>atomic_view</strong> object.
If he <strong>atomic_view</strong> wrapped object is a member of an array
that array shall not be wrapped by an <strong>atomic_array_view</strong>.</p>
<p>Effects: References the non-atomic object.
Atomic operations on this instance are atomic with respect
to atomic operations on any <strong>atomic_view</strong> instance that
references the same object.
May acquire shared resources such as a lock associated with
the referenced object.</p>
<p>Throws: If <em>atomic-view-concept</em> operations cannot be supported
for the referenced object.
[Note: For example, if the referenced object is not properly aligned
or has automatic storage duration within an accelerator
coprocessor (<em>e.g.</em>, a GPGPU) execution context. - end note]
If resource acquisition, such as a lock, is required and fails.</p>
</blockquote>
<div class="line-block">
<div class="line"><strong>atomic_view&lt;T&gt;::atomic_view( atomic_view &amp;&amp; rhs ) noexcept ;</strong></div>
<div class="line"><strong>atomic_view&lt;T&gt;::atomic_view( const atomic_view &amp; rhs ) noexcept ;</strong></div>
<div class="line"><strong>atomic_view&lt;T&gt; &amp; atomic_view&lt;T&gt;::operator = ( atomic_view &amp;&amp; rhs ) noexcept ;</strong></div>
<div class="line"><strong>atomic_view&lt;T&gt; &amp; atomic_view&lt;T&gt;::operator = ( const atomic_view &amp; rhs ) noexcept ;</strong></div>
</div>
<blockquote>
Effects: If <em>rhs</em> references an object
then this instance references the same object otherwise
this instance does not reference an object.</blockquote>
<p><strong>atomic_view&lt;T&gt;::~atomic_view() noexcept ;</strong></p>
<blockquote>
Effects: Releases shared resources that may have been acquired.</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 <em>atomic_array_view</em> object is used to perform
atomic operations on the viewed non-atomic members of the array.
The intent is for <em>atomic_array_view</em> to provide the
best-performing implementation of atomic-view-concept operations
for the members of the array.</p>
<p>Recall that any number of <em>atomic_view</em> entities may independently
<em>wrap construct</em> the same underlying object and all
<em>atomic-view-concept</em> operations performed thru any of those
<strong>atomic_view</strong> entities are atomic for the referenced object.
In contrast, only one <strong>atomic_array_view</strong> entity may <strong>wrap construct</strong>
an array and thus <em>atomic-view-concept</em> operations must be
performed thru that entity or <strong>atomic_array_view</strong> entities
transitively copy constructed, move constructed, copy assigned, or
move assigned from that originating <em>wrap constructed</em> <strong>atomic_array_view</strong>
entity.
This allows a non-lock-free <em>atomic_array_view</em> to acquire resources,
such as a set of locks, that are exclusively associated with the wrapped array.
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.
The intent is to enable reduction of the time and space overhead
associated with of managing such non-lock-free resources.</p>
<p>Note that an <strong>atomic_array_view</strong> is similar to <strong>string_view</strong>
(N4480 Section 7) in that it wraps or references a contiguous set of objects;
however, the reference is non-constant.</p>
<p>This specification is to appear in a new section 29.# Atomic Views.</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">// Alignment requirement for objects of type <em>T</em></div>
<div class="line">static constexprt size_t alignment = <em>implementation defined</em> ;</div>
<div class="line"><br /></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">// Returns true if the view wraps an array and member access is valid.</div>
<div class="line">explicit constexpr operator bool() const noexcept ;</div>
<div class="line"><br /></div>
<div class="line">atomic_array_view( T * , size_t ); // Wrapping constructor is NOT noexcept</div>
<div class="line">constexpr 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 = ( atomic_array_view &amp;&amp; ) noexcept ;</div>
<div class="line">atomic_array_view &amp; operator = ( const atomic_array_view &amp; ) noexcept ;</div>
<div class="line">~atomic_array_view();</div>
<div class="line"><br /></div>
<div class="line">size_t size() const noexcept ;</div>
<div class="line"><br /></div>
<div class="line">using reference = <em>implementation-defined-atomic-view-concept-type</em> ;</div>
<div class="line"><br /></div>
<div class="line">reference operator[]( size_t ) const noexcept ;</div>
</div>
<div class="line">};</div>
</div>
<p>Requires: Type <em>T</em> is trivially copyable.</p>
</blockquote>
<p><strong>using reference =</strong> <em>implementation-defined-atomic-view-concept-type</em> <strong>;</strong></p>
<blockquote>
Requires: The <strong>reference</strong> type conforms to <em>atomic-view-concept</em> for type T.
[Note: The <strong>reference</strong> type is <em>not</em> required to be <em>atomic_view&lt;T&gt;</em>. - end note]</blockquote>
<div class="line-block">
<div class="line"><strong>static constexpr bool is_always_lock_free =</strong> <em>implementation defined</em> <strong>;</strong></div>
<div class="line"><strong>bool atomic_array_view&lt;T&gt;::is_lock_free() const noexcept ;</strong></div>
</div>
<blockquote>
Returns: Whether atomic operations on members are (always) lock free.</blockquote>
<p><strong>constexpr atomic_array_view&lt;T&gt;::atomic_array_view() noexcept;</strong></p>
<blockquote>
Effects: The constructed <strong>atomic_array_view</strong> does not reference
an array and therefore <strong>size() == 0</strong>.</blockquote>
<p><strong>atomic_array_view&lt;T&gt;::atomic_array_view( T * ptr , size_t N );</strong></p>
<blockquote>
<p>Requires: If 0 &lt; N the array referenced by [ptr .. ptr+N) shall
be within a contiguously allocated set of objects (8.3.4p1) and
shall be aligned to <strong>minimum_required_alignment</strong>.
This <em>wrapping constructor</em> shall not be applied to any
subset of the array, including the entire array, as long
as an <strong>atomic_array_view</strong> entity exists wrapping that array.
An <strong>atomic_view</strong> shall not exist for any member
of the array as long as an <strong>atomic_array_view</strong> entity exists for that array.
All accesses of the array's members shall occur through an
<strong>atomic_array_view&lt;T&gt;::reference</strong> as long as an <strong>atomic_array_view</strong>
exists for that array.</p>
<p>Effects: If 0 &lt; N the <em>wrapping constructor</em> wraps the referenced
contiguously allocated array [ptr .. ptr+N);
otherwise the <strong>atomic_array_view</strong> does not reference an array.
Atomic operations on members of this instance are atomic with
respect to atomic operations on members any <strong>atomic_array_view</strong>
instance that references the same array.
May acquire shared resources such as a set of locks.</p>
<p>Throws: If <em>atomic-view-concept</em> operations cannot be supported
for members of the referenced array.
[Note: For example, if the referenced array is not properly aligned
or has automatic storage duration within an accelerator
coprocessor (<em>e.g.</em>, a GPGPU) execution context. - end note]
If resource acquisition, such as a set of locks, is required and fails.</p>
</blockquote>
<div class="line-block">
<div class="line"><strong>atomic_array_view&lt;T&gt;::atomic_array_view( atomic_array_view &amp;&amp; rhs ) noexcept ;</strong></div>
<div class="line"><strong>atomic_array_view&lt;T&gt;::atomic_array_view( const atomic_array_view &amp; rhs ) noexcept ;</strong></div>
<div class="line"><strong>atomic_array_view&lt;T&gt; &amp; atomic_array_view&lt;T&gt;::operator = ( atomic_array_view &amp;&amp; rhs ) noexcept ;</strong></div>
<div class="line"><strong>atomic_array_view&lt;T&gt; &amp; atomic_array_view&lt;T&gt;::operator = ( const atomic_array_view &amp; rhs ) noexcept ;</strong></div>
</div>
<p><strong>atomic_array_view&lt;T&gt;::~atomic_array_view() noexcept ;</strong></p>
<blockquote>
Effects: Releases shared resource that may have been acquired.</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: <strong>i &lt; size()</strong> and the lifetime of the returned <strong>reference</strong>
object, copied <strong>reference</strong> object, or moved <strong>reference</strong> object
shall not exceed the lifetime of the associated <strong>atomic_array_view</strong>.
[Note: Analogous to the lifetime of an iterator with respect to the
lifetime of the associated container. - end note]</p>
<p>Returns: An instance of <strong>reference</strong> type that references
the i-th member of the referenced array, where indexing is zero-based.
[Note: The intent is for efficient generation of the returned
<em>atomic-view-concept</em> object with respect to resources required
to support non-lock-free <em>atomic-view-concept</em> operations.
– end note]</p>
</blockquote>
</div>
<div class="section" id="notes-and-examples">
<h1>5&nbsp;&nbsp;&nbsp;Notes and Examples</h1>
<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>Wrapping constructor options for <strong>atomic_array_view&lt;T&gt;</strong></p>
<p>A wrapping 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
he atomic_array_view would or would not track resizing operations applied to the input container.</p>
</div>
</div>
</body>
</html>
