<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-16LE">

<style type="text/css">

body { color: #000000; background-color: #FFFFFF; }

del { text-decoration: line-through; color: #8B0040; background-color: #FF0000; }
ins { text-decoration: underline; color: #005100; background-color: #FFFF00; }

del.n4346 { text-decoration: line-through; color:blue;}
ins.n4346 { text-decoration: underline; color: blue;}

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }

p.function { }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; }

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5em; padding-right: 0.5em; ; }

blockquote.stdins { /*text-decoration: underline;*/
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto; }
th { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }
td { text-align: left; vertical-align: top;
  padding-left: 0.8em; border: none; }

</style>

<title>Multidimensional bounds, offset and array_view, revision 7</title>

</head>

<body>
<h1>Multidimensional bounds, offset and array_view, revision 7</h1>

<p>
ISO/IEC JTC1 SC22 WG21 N4512 - 2015-05-07
</p>

<p>
Reply-to:<br>
&#x141;ukasz Mendakiewicz &lt;lukaszme@microsoft.com&gt;<br>
Herb Sutter &lt;hsutter@microsoft.com&gt;
</p>


<h2><a name="Overview">Overview</a></h2>

<p>
Revision 7 (N4512) incorporates additional changes requested by LWG in
Lenexa meeting, marked as <del>deletions</del> and <ins>insertions</ins>. 
</p>

<p>
Revision 6 (N4494) incorporates the changes requested by LWG in Cologne meeting.
</p>
<p>
The following suggestions were implemented fully:
</p><ol>
<li>Rephrased coord.general avoid references to mathematical entites.</li>
<li>Renamed <code>index</code> to <code>offset</code>.</li>
<li>Changed <code>int Rank</code> template parameter to <code>size_t Rank</code> throughout the document.</li>
<li>Made <code>offset</code>, <code>bounds</code> and <code>bounds_iterator</code> binary operators (apart from <code>@=</code> forms) free functions.</li>
<li>Replaced term "component" with "element" when referring to the individual constituents of <code>offset</code> or <code>bounds</code>.</li>
<li>In coord.bounds.require replaced prose with an equivalent mathematical expression.</li>
<li>In coord.bounds.iterator and coord.bounds.iterator.require removed the requirement on <code>bounds_iterator</code> to represent a random access iterator, replacing with "as<del>-</del><ins> </ins>if" phrasing.</li>
<li>In the description of <code>bounds_iterator&amp; operator++()</code> replaced the code snippet with equivalent prose.</li>
<li>In views.general changed the font back to non-monospace.</li>
<li>Removed views.require, duplicating it as arrayview.require and stridedarrayview.require.</li>
<li>Removed redundant assignment operators on <code>array_view</code> and <code>strided_array_view</code>.</li>
<li>Employed "exposition only" data members is the descriptions of <code>array_view</code> and <code>strided_array_view</code> semantics.</li>
<li>Rephrased the first paragraph in arrayview.cons to avoid ambiguity in binding of the token "type".</li>
<li>In <code>constexpr array_view(Viewable&amp;&amp; vw)</code> rephrased the third bullet point.</li>
</ol>
<p>
The following suggestion was implemented partially:
</p><ol>
<li>Instead of the <code>array_view(ArrayType&amp; arr)</code> 
constructor being completely removed, it has been constrained to 1-D 
case as the Committee indicated that such case does not exhibit the 
undefined behavior. We believe that the request to remove it completely 
was a misstatment.</li>
</ol>
<p>
The following suggestion was not implemented:
</p><ol>
<li>The semantics of the proposed types were not extended to allow 
rank-0 cases. We feel that we lack sufficient practical experience in 
using such cases and we are afraid of some contention points when it 
comes to defining their detailed semantics. We observe that such an 
extension can be introduced in future without conflicting with the 
proposal in the current form.</li>
</ol>

<p>
Revision 5 (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4346.html">N4346</a>) incorporates the changes requested by LWG in Urbana-Champaign meeting.
</p>

<p>
Revision 4 (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4177.html">N4177</a>) contains the following changes:
</p><ol>
<li>The order of some of the <code>array_view</code> and <code>strided_array_view</code> constructor parameters have been switched from {<i>size</i>, <i>location</i>} to {<i>location</i>, <i>size</i>} for consistency with the existing practice in STL (vide <code>copy_n</code>).</li>
<li>Alias templates for constant views have been introduced.</li>
</ol>

<p>
Revision 3 (<a href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4087.html">N4087</a>) incorporates the feedback received in Rapperswil from LEWG and some other minor fixes:
</p><ol>
<li>Fixed specification of <code>initializer_list</code> constructors in <code>index</code> and <code>bounds</code> — the size of the <code>initializer_list</code> cannot always be verified at the compile-time, so the check must be expressed as "Requires" instead of SFINAE.</li>
<ul>
<li>Note: LEWG suggested to try using constrained variadic constructor template instead of <code>initializer_list</code>
 constructor, as the former might reject the wrong number of arguments 
in the compile time. We have found that while we can almost fully 
emulate the behavior of e.g. <code>index&lt;2&gt;{1,2}</code> implemented as "<code>initializer_list</code>
 with constrained size", the solution comes with the cost of high 
complexity in specifying the intended behavior — basically duplicating 
the language rules in the library. It would probably also be fragile if 
any of the language rules change. Ultimately we have decided that the 
added diagnosability benefit is not worth the cost.</li>
</ul>
<li>Improved the wording for <code>operator-</code> and <code>operator-=</code> in <code>index</code> and <code>bounds</code> to avoid negating <code><var>rhs</var></code>.</li>
<li>Added <code>(const_)iterator</code> type aliases in <code>bounds</code>.</li>
<li>Slightly improved the wording in the <code>array_view(bounds_type bounds, pointer ptr)</code> specification.</li>
<li>Slightly improved the wording in the <code>bounds_iterator::operator++</code> specification.</li>
<li>Tightened the specification of views to prevent derived-to-base conversions.</li>
<li><code>Made array_view(Viewable&amp;&amp;)</code> and <code>array_view(ArrayType&amp;)</code> constructors not "explicit".</li>
<li>Fixed <code>array_view(bounds_type bounds, pointer ptr)</code> constructor not to be "noexcept".</li>
<li>Provided a definition for "uniformly strided".</li>
<li>Renamed "generalized views" to "views".</li>
<li>Changed <code>index</code> and <code>bounds</code> arithmetic operators from accepting any <code>ArithmeticType</code> to only <code>value_type</code>/<code>ptrdiff_t</code>.</li>
<li>Improved the overload resolution for <code>array_view</code> constructors so that all conversions between related <code>array_view</code>s can be <code>noexcept</code>.</li>
<li>Slightly improved consistency and mistakes between "this constructor" and "this function" wording.</li>
</ol>


<h2><a name="Acknowledgements">Acknowledgements</a></h2>

<p>
Thanks to Stephan T. Lavavej, Matthew Fioravante, Robert Kawulak and the
 members of LEWG for the suggested improvements. Thanks to the 
interlocutors at ISO C++ Standard - Future Proposals forum for the 
valuable feedback. Thanks to all correspondents expressing feedback in 
private emails.
</p>

<h2><a name="Wording">Wording changes</a></h2>

<p>
The proposed wording changes are relative to
the contents of <a href="http://www.open-std.org/jtc1/sc22/wg21/prot/14882fdis/n3936.pdf">N3936</a>.
</p>


<h3><a name="headers">17.6.1.2 Headers [headers]</a></h3>

<p>
Edit within paragraph 2 as follows.
</p>

<blockquote class="std">
<p>
The C++ standard library provides 55 <em>C++ library headers</em>, as shown in Table 14.
</p>
</blockquote>

<p>
Add the following items to table 14.
</p>

<blockquote class="std">
<p>
<code>&lt;array_view&gt;</code><br>
<code>&lt;coordinate&gt;</code>
</p>
</blockquote>


<h3><a name="utilities">Chapter 20 General utilities library [utilities]</a></h3>

<p>
Add a row to table 44 as follows.
</p>

<blockquote class="std">
<table>
<caption>Table 44: General utilities library summary</caption>
<tbody>
<tr><th>Subclause</th><th>Header(s)</th></tr>
<tr><td valign="top">20.2 Utility components</td>
<td><code>&lt;utility&gt;</code></td></tr>
<tr><td valign="top">20.3 Pairs</td>
<td><code>&lt;utility&gt;</code></td></tr>
<tr><td valign="top">20.4 Tuples</td>
<td><code>&lt;tuple&gt;</code></td></tr>
<tr><td valign="top">20.5 Compile-time integer sequences</td>
<td><code>&lt;utility&gt;</code></td></tr>
<tr><td valign="top">20.6 Multidimensional coordinates</td>
<td><code>&lt;coordinate&gt;</code></td></tr>
<tr><td valign="top">20.7 Fixed-size sequences of bits</td>
<td><code>&lt;bitset&gt;<br>
&lt;memory&gt;</code></td></tr>
<tr><td valign="top">20.8 Memory</td>
<td><code>&lt;cstdlib&gt;<br>
&lt;cstring&gt;</code></td></tr>
<tr><td valign="top">20.9 Smart pointers</td>
<td><code>&lt;memory&gt;</code></td></tr>
<tr><td valign="top">20.10 Function objects</td>
<td><code>&lt;functional&gt;</code></td></tr>
<tr><td valign="top">20.11 Type traits</td>
<td><code>&lt;type_traits&gt;</code></td></tr>
<tr><td valign="top">20.12 Compile-time rational arithmetic</td>
<td><code>&lt;ratio&gt;</code></td></tr>
<tr><td valign="top">20.13 Time utilities</td>
<td><code>&lt;chrono&gt;<br>
&lt;ctime&gt;</code></td></tr>
<tr><td valign="top">20.14 Scoped allocators</td>
<td><code>&lt;scoped_allocator&gt;</code></td></tr>
<tr><td valign="top">20.15 Type indexes</td>
<td><code>&lt;typeindex&gt;</code></td></tr>
</tbody>
</table>
</blockquote>


<h3><a name="coord">20.6 Multidimensional coordinates [coord]</a></h3>

<p>
Add a new section after the <code>intseq</code> section.
</p>


<h3><a name="coord.general">20.6.1 In general [coord.general]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">
<p>
This subclause describes the multidimensional coordinates library. It provides a class template <code>offset</code> which is an <var>N</var>-tuple of coordinates representing locations and offsets in <var>N</var>-dimensional data structures, a class template <code>bounds</code> which is an <var>N</var>-tuple representing extents of such data structures, and a class template <code>bounds_iterator</code> which allows iteration over <ins>a</ins> space defined by such extents. 
</p>
</blockquote>

<p>
Add a new synopsis:
</p>

<blockquote class="stdins">
<p>
<b>Header <code>&lt;<ins>experimental/</ins>coordinate&gt;</code> synopsis</b>
</p>

<pre><code>
#include &lt;initializer_list&gt;

namespace std {
  <ins>namespace experimental {
  inline namespace fundamentals_v2 {</ins>

    // [coord.offset], class template offset
    template &lt;size_t Rank&gt; class offset;

    // [coord.offset.eq], offset equality
    template &lt;size_t Rank&gt;
      constexpr bool operator==(const offset&lt;Rank&gt;&amp; <var>lhs</var>, const offset&lt;Rank&gt;&amp; <var>rhs</var>) noexcept;
    template &lt;size_t Rank&gt;
      constexpr bool operator!=(const offset&lt;Rank&gt;&amp; <var>lhs</var>, const offset&lt;Rank&gt;&amp; <var>rhs</var>) noexcept;

    // [coord.offset.arith], offset arithmetic
    template &lt;size_t Rank&gt;
      constexpr offset&lt;Rank&gt; operator+(const offset&lt;Rank&gt;&amp; <var>lhs</var>, const offset&lt;Rank&gt;&amp; <var>rhs</var>);
    template &lt;size_t Rank&gt;
      constexpr offset&lt;Rank&gt; operator-(const offset&lt;Rank&gt;&amp; <var>lhs</var>, const offset&lt;Rank&gt;&amp; <var>rhs</var>);
    template &lt;size_t Rank&gt;
      constexpr offset&lt;Rank&gt; operator*(const offset&lt;Rank&gt;&amp; <var>lhs</var>, ptrdiff_t <var>v</var>);
    template &lt;size_t Rank&gt;
      constexpr offset&lt;Rank&gt; operator*(ptrdiff_t <var>v</var>, const offset&lt;Rank&gt;&amp; <var>rhs</var>);
    template &lt;size_t Rank&gt;
      constexpr offset&lt;Rank&gt; operator/(const offset&lt;Rank&gt;&amp; <var>lhs</var>, ptrdiff_t <var>v</var>);

    // [coord.bounds], class template bounds
    template &lt;size_t Rank&gt; class bounds;

    // [coord.bounds.eq], bounds equality
    template &lt;size_t Rank&gt;
      constexpr bool operator==(const bounds&lt;Rank&gt;&amp; <var>lhs</var>, const bounds&lt;Rank&gt;&amp; <var>rhs</var>) noexcept;
    template &lt;size_t Rank&gt;
      constexpr bool operator!=(const bounds&lt;Rank&gt;&amp; <var>lhs</var>, const bounds&lt;Rank&gt;&amp; <var>rhs</var>) noexcept;

    // [coord.bounds.arith], bounds arithmetic
    template &lt;size_t Rank&gt;
      constexpr bounds&lt;Rank&gt; operator+(const bounds&lt;Rank&gt;&amp; <var>lhs</var>, const offset&lt;Rank&gt;&amp; <var>rhs</var>);
    template &lt;size_t Rank&gt;
      constexpr bounds&lt;Rank&gt; operator+(const offset&lt;Rank&gt;&amp; <var>lhs</var>, const bounds&lt;Rank&gt;&amp; <var>rhs</var>);
    template &lt;size_t Rank&gt;
      constexpr bounds&lt;Rank&gt; operator-(const bounds&lt;Rank&gt;&amp; <var>lhs</var>, const offset&lt;Rank&gt;&amp; <var>rhs</var>);
    template &lt;size_t Rank&gt;
      constexpr bounds&lt;Rank&gt; operator*(const bounds&lt;Rank&gt;&amp; <var>lhs</var>, ptrdiff_t <var>v</var>);
    template &lt;size_t Rank&gt;
      constexpr bounds&lt;Rank&gt; operator*(ptrdiff_t <var>v</var>, const bounds&lt;Rank&gt;&amp; <var>rhs</var>);
    template &lt;size_t Rank&gt;
      constexpr bounds&lt;Rank&gt; operator/(const bounds&lt;Rank&gt;&amp; <var>lhs</var>, ptrdiff_t <var>v</var>);

    // [coord.bounds.iterator], class template bounds_iterator
    template &lt;size_t Rank&gt; class bounds_iterator;

    template &lt;size_t Rank&gt;
      bool                  operator==(const bounds_iterator&lt;Rank&gt;&amp; <var>lhs</var>,
                                       const bounds_iterator&lt;Rank&gt;&amp; <var>rhs</var>);
    template &lt;size_t Rank&gt;
      bool                  operator!=(const bounds_iterator&lt;Rank&gt;&amp; <var>lhs</var>,
                                       const bounds_iterator&lt;Rank&gt;&amp; <var>rhs</var>);
    template &lt;size_t Rank&gt;
      bool                  operator&lt;(const bounds_iterator&lt;Rank&gt;&amp; <var>lhs</var>,
                                      const bounds_iterator&lt;Rank&gt;&amp; <var>rhs</var>);
    template &lt;size_t Rank&gt;
      bool                  operator&lt;=(const bounds_iterator&lt;Rank&gt;&amp; <var>lhs</var>,
                                       const bounds_iterator&lt;Rank&gt;&amp; <var>rhs</var>);
    template &lt;size_t Rank&gt;
      bool                  operator&gt;(const bounds_iterator&lt;Rank&gt;&amp; <var>lhs</var>,
                                      const bounds_iterator&lt;Rank&gt;&amp; <var>rhs</var>);
    template &lt;size_t Rank&gt;
      bool                  operator&gt;=(const bounds_iterator&lt;Rank&gt;&amp; <var>lhs</var>,
                                       const bounds_iterator&lt;Rank&gt;&amp; <var>rhs</var>);
    template &lt;size_t Rank&gt;
      bounds_iterator&lt;Rank&gt; operator+(typename bounds_iterator&lt;Rank&gt;::difference_type <var>n</var>,
                                      const bounds_iterator&lt;Rank&gt;&amp; <var>rhs</var>);
  <ins>
  } // inline namespace fundamentals_v2
  } // namespace experimental</ins>
} <ins>// namespace std</ins>
</code></pre>
</blockquote>


<h3><a name="coord.offset">20.6.2 Class template <code>offset</code> [coord.offset]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">
<pre><code>
namespace std {
  <ins>namespace experimental {
  inline namespace fundamentals_v2 {</ins>
    template &lt;size_t Rank&gt;
    class offset {
    public:
      // constants and types
      static constexpr size_t rank = Rank;
      using reference           = ptrdiff_t&amp;;
      using const_reference     = const ptrdiff_t&amp;;
      using size_type           = size_t;
      using value_type          = ptrdiff_t;

      // [coord.offset.cnstr], offset construction
      constexpr offset() noexcept;
      constexpr offset(value_type <var>v</var>) noexcept;           // only if Rank == 1
      constexpr offset(initializer_list&lt;value_type&gt; <var>il</var>);

      // [coord.offset.<del>cmpt</del><ins>elem</ins>], offset element access
      constexpr reference       operator[](size_type <var>n</var>);
      constexpr const_reference operator[](size_type <var>n</var>) const;

      // [coord.offset.arith], offset arithmetic
      
      constexpr offset&amp; operator+=(const offset&amp; <var>rhs</var>);
      constexpr offset&amp; operator-=(const offset&amp; <var>rhs</var>);

      constexpr offset&amp; operator++();    // only if Rank == 1
      constexpr offset  operator++(int); // only if Rank == 1
      constexpr offset&amp; operator--();    // only if Rank == 1
      constexpr offset  operator--(int); // only if Rank == 1

      constexpr offset  operator+() const noexcept;
      constexpr offset  operator-() const;

      
      constexpr offset&amp; operator*=(value_type <var>v</var>);
      constexpr offset&amp; operator/=(value_type <var>v</var>);
    };
  <ins>
  } // inline namespace fundamentals_v2
  } // namespace experimental</ins>
} <ins>// namespace std</ins>
</code></pre>
</blockquote>


<h3><a name="coord.offset.require">20.6.2.1 General requirements [coord.offset.require]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
If <code>Rank</code> is less than 1 the program is ill-formed.
</p>

</blockquote>


<h3><a name="coord.offset.cnstr">20.6.2.2 Construction [coord.offset.cnstr]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
<code>constexpr offset() noexcept;</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
Zero-initializes each element.
</p>
</blockquote>

<p>
<code>constexpr offset(value_type <var>v</var>) noexcept;</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
Initializes the 0<sup>th</sup> element of <code>*this</code> with <code><var>v</var></code>.
</p>
<p>
<i>Remarks:</i>
This constructor shall not participate in overload resolution unless <code>Rank</code> is 1.
</p>
</blockquote>

<p>
<code>constexpr offset(initializer_list&lt;value_type&gt; <var>il</var>);</code>
</p>

<blockquote>
<p>
<i>Requires:</i>
<code><var>il</var>.size() == Rank</code>.
</p>
<p>
<i>Effects:</i>
For all <var>i</var> in the range <code>[0, Rank)</code>, initializes the <var>i<sup>th</sup></var> element of <code>*this</code> with <code>*(<var>il</var>.begin() + <var>i</var>)</code>.
</p>
</blockquote>

</blockquote>


<h3><a name="coord.offset.eq">20.6.2.3 Equality [coord.offset.eq]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr bool operator==(const offset&lt;Rank&gt;&amp; <var>lhs</var>, const offset&lt;Rank&gt;&amp; <var>rhs</var>) noexcept;</code></pre>
<p></p>

<blockquote>
<p>
<i>Returns:</i>
<code>true</code> if <code><var>lhs</var>[<var>i</var>] == <var>rhs</var>[<var>i</var>]</code> for all <code><var>i</var></code> in the range <code>[0, Rank)</code>, otherwise <code>false</code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr bool operator!=(const offset&lt;Rank&gt;&amp; <var>lhs</var>, const offset&lt;Rank&gt;&amp; <var>rhs</var>) noexcept;</code></pre>
<p></p>

<blockquote>
<p>
<i>Returns:</i>
<code>!(<var>lhs</var> == <var>rhs</var>)</code>.
</p>
</blockquote>

</blockquote>


<h3><a name="coord.offset.<del>cmpt</del><ins>elem</ins>">20.6.2.4 Element access [coord.offset.<del>cmpt</del><ins>elem</ins>]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
<code>constexpr reference operator[](size_type <var>n</var>);</code><br>
<code>constexpr const_reference operator[](size_type <var>n</var>) const;</code>
</p>

<blockquote>
<p>
<i>Requires:</i>
<code><var>n</var> &lt; Rank</code>.
</p>
<p>
<i>Returns:</i>
A reference to the <code><var>n</var></code><sup>th</sup> element of <code>*this</code>.
</p>
</blockquote>

</blockquote>


<h3><a name="coord.offset.arith">20.6.2.5 Arithmetic [coord.offset.arith]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>

</p>

<blockquote>
<p>

</p>
</blockquote>

<p>

</p>

<blockquote>
<p>

</p>
</blockquote>

<p>
<code>constexpr offset&amp; operator+=(const offset&amp; <var>rhs</var>);</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
For all <var>i</var> in the range <code>[0, Rank)</code>, adds the <var>i<sup>th</sup></var> element of <code><var>rhs</var></code> to the <var>i<sup>th</sup></var> element of <code>*this</code> and stores the sum in the <var>i<sup>th</sup></var> element of <code>*this</code>.
</p>
<p>
<i>Returns:</i>
<code>*this</code>.
</p>
</blockquote>

<p>
<code>constexpr offset&amp; operator-=(const offset&amp; <var>rhs</var>);</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
For all <var>i</var> in the range <code>[0, Rank)</code>, subtracts the <var>i<sup>th</sup></var> element of <code><var>rhs</var></code> from the <var>i<sup>th</sup></var> element of <code>*this</code> and stores the difference in the <var>i<sup>th</sup></var> element of <code>*this</code>.
</p>
<p>
<i>Returns:</i>
<code>*this</code>.
</p>
</blockquote>

<p>
<code>constexpr offset&amp; operator++();</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
<code>++(*this)[0]</code>.
</p>
<p>
<i>Returns:</i>
<code>*this</code>.
</p>
<p>
<i>Remarks:</i>
This function shall not participate in overload resolution unless <code>Rank == 1</code>.
</p>
</blockquote>

<p>
<code>constexpr offset operator++(int);</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
<code>offset<del>&lt;Rank&gt;</del>{(*this)[0]++}</code>.
</p>
<p>
<i>Remarks:</i>
This function shall not participate in overload resolution unless <code>Rank == 1</code>.
</p>
</blockquote>

<p>
<code>constexpr offset&amp; operator--();</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
<code>--(*this)[0]</code>.
</p>
<p>
<i>Returns:</i>
<code>*this</code>.
</p>
<p>
<i>Remarks:</i>
This function shall not participate in overload resolution unless <code>Rank == 1</code>.
</p>
</blockquote>

<p>
<code>constexpr offset operator--(int);</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
<code>offset<del>&lt;Rank&gt;</del>{(*this)[0]--}</code>.
</p>
<p>
<i>Remarks:</i>
This function shall not participate in overload resolution unless <code>Rank == 1</code>.
</p>
</blockquote>

<p>
<code>constexpr offset operator+() const noexcept;</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
<code>*this</code>.
</p>
</blockquote>

<p>
<code>constexpr offset operator-() const;</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
A copy of <code>*this</code> with each element negated.
</p>
</blockquote>

<p>
</p>

<blockquote>
<p>

</p>
</blockquote>

<p>

</p>

<blockquote>
<p>

</p>
</blockquote>

<p>
<code>constexpr offset&amp; operator*=(value_type <var>v</var>);</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
For all <var>i</var> in the range <code>[0, Rank)</code>, multiplies the <var>i<sup>th</sup></var> element of <code>*this</code> by <code><var>v</var></code> and stores the product in the <var>i<sup>th</sup></var> element of <code>*this</code>.
</p>
<p>
<i>Returns:</i>
<code>*this</code>.
</p>
</blockquote>

<p>
<code>constexpr offset&amp; operator/=(value_type <var>v</var>);</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
For all <var>i</var> in the range <code>[0, Rank)</code>, divides the <var>i<sup>th</sup></var> element of <code>*this</code> by <code><var>v</var></code> and stores the quotient in the <var>i<sup>th</sup></var> element of <code>*this</code>.
</p>
<p>
<i>Returns:</i>
<code>*this</code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr offset&lt;Rank&gt; operator+(const offset&lt;Rank&gt;&amp; <var>lhs</var>, const offset&lt;Rank&gt;&amp; <var>rhs</var>);</code></pre>
<p></p>

<blockquote>
<p>
<i>Returns:</i>
<code>offset&lt;Rank&gt;{<var>lhs</var>} += <var>rhs</var></code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr offset&lt;Rank&gt; operator-(const offset&lt;Rank&gt;&amp; <var>lhs</var>, const offset&lt;Rank&gt;&amp; <var>rhs</var>);</code></pre>
<p></p>

<blockquote>
<p>
<i>Returns:</i>
<code>offset&lt;Rank&gt;{<var>lhs</var>} -= <var>rhs</var></code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr offset&lt;Rank&gt; operator*(const offset&lt;Rank&gt;&amp; <var>lhs</var>, ptrdiff_t <var>v</var>);</code></pre>
<p></p>

<blockquote>
<p>
<i>Returns:</i>
<code>offset&lt;Rank&gt;{<var>lhs</var>} *= <var>v</var></code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr offset&lt;Rank&gt; operator*(ptrdiff_t <var>v</var>, const offset&lt;Rank&gt;&amp; <var>rhs</var>);</code></pre>
<p></p>

<blockquote>
<p>
<i>Returns:</i>
<code>offset&lt;Rank&gt;{<var>rhs</var>} *= <var>v</var></code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr offset&lt;Rank&gt; operator/(const offset&lt;Rank&gt;&amp; <var>lhs</var>, ptrdiff_t <var>v</var>);</code></pre>
<p></p>

<blockquote>
<p>
<i>Returns:</i>
<code>offset&lt;Rank&gt;{<var>lhs</var>} /= <var>v</var></code>.
</p>
</blockquote>

</blockquote>


<h3><a name="coord.bounds">20.6.3 Class template <code>bounds</code> [coord.bounds]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">
<pre><code>
namespace std {
  <ins>namespace experimental {
  inline namespace fundamentals_v2 {</ins>

    template &lt;size_t Rank&gt;
    class bounds {
    public:
      // constants and types
      static constexpr size_t rank = Rank;
      using reference           = ptrdiff_t&amp;;
      using const_reference     = const ptrdiff_t&amp;;
      using iterator            = bounds_iterator&lt;Rank&gt;;
      using const_iterator      = bounds_iterator&lt;Rank&gt;;
      using size_type           = size_t;
      using value_type          = ptrdiff_t;

      // [coord.bounds.cnstr], bounds construction
      constexpr bounds() noexcept;
      constexpr bounds(value_type <var>v</var>);                    // only if Rank == 1
      constexpr bounds(initializer_list&lt;value_type&gt; <var>il</var>);

      

      // [coord.bounds.obs], bounds observers
      constexpr size_type size() const noexcept;
      constexpr bool      contains(const offset&lt;Rank&gt;&amp; <var>idx</var>) const noexcept;

      // [coord.bounds.iter], bounds iterators
      const_iterator begin() const noexcept;
      const_iterator end() const noexcept;

      // [coord.bounds.<del>cmpt</del><ins>elem</ins>], bounds element access
      constexpr reference       operator[](size_type <var>n</var>);
      constexpr const_reference operator[](size_type <var>n</var>) const;

      // [coord.bounds.arith], bounds arithmetic
      
      constexpr bounds&amp; operator+=(const offset&lt;Rank&gt;&amp; <var>rhs</var>);
      constexpr bounds&amp; operator-=(const offset&lt;Rank&gt;&amp; <var>rhs</var>);

      
      constexpr bounds&amp; operator*=(value_type <var>v</var>);
      constexpr bounds&amp; operator/=(value_type <var>v</var>);
    };
  <ins>
  } // inline namespace fundamentals_v2
  } // namespace experimental</ins>
} <ins>// namespace std</ins>
</code></pre>
</blockquote>


<h3><a name="coord.bounds.require">20.6.3.1 General requirements [coord.bounds.require]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
If <code>Rank</code> is less than 1 the program is ill-formed.
</p>

<p>
Construction of and every mutating operation on an object <code><var>b</var></code> of type <code>bounds</code> shall leave the object in a state that satisfies the following constraints:
</p><ol>
<li><code><var>b</var>[<var>i</var>] &gt;= 0</code> for all <code><var>i</var></code> in the range <code>[0, Rank)</code>.</li>
<li>
<code><var>b</var>[0]</code> × <code><var>b</var>[1]</code> × ... × <code><var>b</var>[Rank - 1] &lt;=</code> <code>numeric_limits&lt;ptrdiff_t&gt;::max()</code>.</li>
</ol>
<p>
Otherwise, the behavior is undefined.
</p>

</blockquote>


<h3><a name="coord.bounds.cnstr">20.6.3.2 Construction [coord.bounds.cnstr]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
<code>constexpr bounds() noexcept;</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
Zero-initializes each element.
</p>
</blockquote>

<p>
<code>constexpr bounds(value_type <var>v</var>);</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
Initializes the 0<sup>th</sup> element of <code>*this</code> with <code><var>v</var></code>.
</p>
<p>
<i>Remarks:</i>
This constructor shall not participate in overload resolution unless <code>Rank</code> is 1.
</p>
</blockquote>

<p>
<code>constexpr bounds(initializer_list&lt;value_type&gt; <var>il</var>);</code>
</p>

<blockquote>
<p>
<i>Requires:</i>
<code><var>il</var>.size() == Rank</code>.
</p>
<p>
<i>Effects:</i>
For all <var>i</var> in the range <code>[0, Rank)</code>, initializes the <var>i<sup>th</sup></var> element of <code>*this</code> with <code>*(<var>il</var>.begin() + <var>i</var>)</code>.
</p>
</blockquote>

</blockquote>


<h3><a name="coord.bounds.eq">20.6.3.3 Equality [coord.bounds.eq]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr bool operator==(const bounds&lt;Rank&gt;&amp; <var>lhs</var>, const bounds&lt;Rank&gt;&amp; <var>rhs</var>) noexcept;</code></pre>
<p></p>

<blockquote>
<p>
<i>Returns:</i>
<code>true</code> if <code><var>lhs</var>[<var>i</var>] == <var>rhs</var>[<var>i</var>]</code> for all <code><var>i</var></code> in the range <code>[0, Rank)</code>, otherwise <code>false</code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr bool operator!=(const bounds&lt;Rank&gt;&amp; <var>lhs</var>, const bounds&lt;Rank&gt;&amp; <var>rhs</var>) noexcept;</code></pre>
<p></p>

<blockquote>
<p>
<i>Returns:</i>
<code>!(<var>lhs</var> == <var>rhs</var>)</code>.
</p>
</blockquote>

</blockquote>


<h3><a name="coord.bounds.obs">20.6.3.4 Observers [coord.bounds.obs]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
<code>constexpr size_type size() const noexcept;</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
The product of all elements of <code>*this</code>.
</p>
</blockquote>

<p>
<code>constexpr bool contains(const offset&lt;Rank&gt;&amp; <var>idx</var>) const noexcept;</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
<code>true</code> if <code>0 &lt;= <var>idx</var>[<var>i</var>]</code> and <code><var>idx</var>[<var>i</var>] &lt; (*this)[<var>i</var>]</code> for all <code><var>i</var></code> in the range <code>[0, Rank)</code>, otherwise <code>false</code>.
</p>
</blockquote>

</blockquote>


<h3><a name="coord.bounds.iter">20.6.3.5 Iterators [coord.bounds.iter]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
<code><del>bounds_iterator&lt;Rank&gt;</del><ins>const_iterator</ins> begin() const noexcept;</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
A <code>bounds_iterator</code> referring to the first element of the space defined by <code>*this</code> such that <code>*begin() == offset&lt;Rank&gt;{}</code> if <code>size() != 0</code>,<ins>otherwise</ins> <code>begin() == end()</code> otherwise.
</p>
</blockquote>

<p>
<code><del>bounds_iterator&lt;Rank&gt;</del><ins>const_iterator</ins> end() const noexcept;</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
A <code>bounds_iterator</code> which is the past-the-end iterator for the space defined by <code>*this</code>.
</p>
</blockquote>

</blockquote>


<h3><a name="coord.bounds.<del>cmpt</del><ins>elem</ins>">20.6.3.6 Element access [coord.bounds.<del>cmpt</del><ins>elem</ins>]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
<code>constexpr reference operator[](size_type <var>n</var>);</code><br>
<code>constexpr const_reference operator[](size_type <var>n</var>) const;</code>
</p>

<blockquote>
<p>
<i>Requires:</i>
<code><var>n</var> &lt; Rank</code>.
</p>
<p>
<i>Returns:</i>
A reference to the <code><var>n</var></code><sup>th</sup> element of <code>*this</code>.
</p>
</blockquote>

</blockquote>


<h3><a name="coord.bounds.arith">20.6.3.7 Arithmetic [coord.bounds.arith]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>

</p>

<blockquote>
<p>

</p>
</blockquote>

<p>

</p>

<blockquote>
<p>

</p>
</blockquote>

<p>
<code>constexpr bounds&amp; operator+=(const offset&lt;Rank&gt;&amp; <var>rhs</var>);</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
For all <var>i</var> in the range <code>[0, Rank)</code>, adds the <var>i<sup>th</sup></var> element of <code><var>rhs</var></code> to the <var>i<sup>th</sup></var> element of <code>*this</code> and stores the sum in the <var>i<sup>th</sup></var> element of <code>*this</code>.
</p>
<p>
<i>Returns:</i>
<code>*this</code>.
</p>
</blockquote>

<p>
<code>constexpr bounds&amp; operator-=(const offset&lt;Rank&gt;&amp; <var>rhs</var>);</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
For all <var>i</var> in the range <code>[0, Rank)</code>, subtracts the <var>i<sup>th</sup></var> element of <code><var>rhs</var></code> from the <var>i<sup>th</sup></var> element of <code>*this</code> and stores the difference in the <var>i<sup>th</sup></var> element of <code>*this</code>.
</p>
<p>
<i>Returns:</i>
<code>*this</code>.
</p>
</blockquote>

<p>

</p>

<blockquote>
<p>

</p>
</blockquote>

<p>

</p>

<blockquote>
<p>

</p>
</blockquote>

<p>
<code>constexpr bounds&amp; operator*=(value_type <var>v</var>);</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
For all <var>i</var> in the range <code>[0, Rank)</code>, multiplies the <var>i<sup>th</sup></var> element of <code>*this</code> by <code><var>v</var></code> and stores the product in the <var>i<sup>th</sup></var> element of <code>*this</code>.
</p>
<p>
<i>Returns:</i>
<code>*this</code>.
</p>
</blockquote>

<p>
<code>constexpr bounds&amp; operator/=(value_type <var>v</var>);</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
For all <var>i</var> in the range <code>[0, Rank)</code>, divides the <var>i<sup>th</sup></var> element of <code>*this</code> by <code><var>v</var></code> and stores the quotient in the <var>i<sup>th</sup></var> element of <code>*this</code>.
</p>
<p>
<i>Returns:</i>
<code>*this</code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr bounds&lt;Rank&gt; operator+(const bounds&lt;Rank&gt;&amp; <var>lhs</var>, const offset&lt;Rank&gt;&amp; <var>rhs</var>);</code></pre>
<p></p>

<blockquote>
<p>
<i>Returns:</i>
<code>bounds&lt;Rank&gt;{<var>lhs</var>} += <var>rhs</var></code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr bounds&lt;Rank&gt; operator+(const offset&lt;Rank&gt;&amp; <var>lhs</var>, const bounds&lt;Rank&gt;&amp; <var>rhs</var>);</code></pre>

<blockquote>
<p>
<i>Returns:</i>
<code>bounds&lt;Rank&gt;{<var>rhs</var>} += <var>lhs</var></code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr bounds&lt;Rank&gt; operator-(const bounds&lt;Rank&gt;&amp; <var>lhs</var>, const offset&lt;Rank&gt;&amp; <var>rhs</var>);</code></pre>
<p></p>

<blockquote>
<p>
<i>Returns:</i>
<code>bounds&lt;Rank&gt;{<var>lhs</var>} -= <var>rhs</var></code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr bounds&lt;Rank&gt; operator*(const bounds&lt;Rank&gt;&amp; <var>lhs</var>, ptrdiff_t <var>v</var>);</code></pre>
<p></p>

<blockquote>
<p>
<i>Returns:</i>
<code>bounds&lt;Rank&gt;{<var>lhs</var>} *= <var>v</var></code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr bounds&lt;Rank&gt; operator*(ptrdiff_t <var>v</var>, const bounds&lt;Rank&gt;&amp; <var>rhs</var>);</code></pre>

<blockquote>
<p>
<i>Returns:</i>
<code>bounds&lt;Rank&gt;{<var>rhs</var>} *= <var>v</var></code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;size_t Rank&gt;
  constexpr bounds&lt;Rank&gt; operator/(const bounds&lt;Rank&gt;&amp; <var>lhs</var>, ptrdiff_t <var>v</var>);</code></pre>
<p></p>

<blockquote>
<p>
<i>Returns:</i>
<code>bounds&lt;Rank&gt;{<var>lhs</var>} /= <var>v</var></code>.
</p>
</blockquote>

</blockquote>


<h3><a name="coord.bounds.iterator">20.6.4 Class template <code>bounds_iterator</code> [coord.bounds.iterator]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">
<p>
<del>Semantincs</del><ins>Semantics</ins> of <ins>the</ins> <code>bounds_iterator</code> shall follow the semantics of a random access iterator ([random.access.iterators]) unless otherwise specified below.
</p>

<pre><code>
namespace std {
  <ins>namespace experimental {
  inline namespace fundamentals_v2 {</ins>

    template &lt;size_t Rank&gt;
    class bounds_iterator
    {
    public:
      using iterator_category = <em>unspecified</em>;
      using value_type        = offset&lt;Rank&gt;;
      using difference_type   = ptrdiff_t;
      using pointer           = <em>unspecified</em>;   // See [coord.bounds.iterator.require]
      using reference         = const offset&lt;Rank&gt;;

      

      bounds_iterator&amp; operator++();
      bounds_iterator  operator++(int);
      bounds_iterator&amp; operator--();
      bounds_iterator  operator--(int);

      bounds_iterator  operator+(difference_type <var>n</var>) const;
      bounds_iterator&amp; operator+=(difference_type <var>n</var>);
      bounds_iterator  operator-(difference_type <var>n</var>) const;
      bounds_iterator&amp; operator-=(difference_type <var>n</var>);

      difference_type  operator-(const bounds_iterator&amp; <var>rhs</var>) const;

      reference operator*() const;
      pointer   operator-&gt;() const;
      reference operator[](difference_type <var>n</var>) const;

    private:
      bounds&lt;Rank&gt; bnd_;  // <em>exposition only</em>
      offset&lt;Rank&gt;  idx_;  // <em>exposition only</em>
    };
  <ins>
  } // inline namespace fundamentals_v2
  } // namespace experimental</ins>
} <ins>// namespace std</ins>
</code></pre>
</blockquote>


<h3><a name="coord.bounds.iterator.require">20.6.4.1 General requirements [coord.bounds.iterator.require]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
If <code>Rank</code> is less than 1 the program is ill-formed.
</p>

<p>
<code>pointer</code> shall be an unspecified type such that for a <code>bounds_iterator <var>it</var></code> the expression <code><var>it</var>-&gt;E</code> is equivalent to <code>(*<var>it</var>).E</code> and that for an object <code><var>p</var></code> of type <code>pointer</code> the expression <code><var>p</var>-&gt;E</code> yields the same result irrespective of whether the state of the <code>bounds_iterator</code> object has changed or its lifetime has ended.
</p>

<p>
<i>[Note:</i>
All functions in the library that take a pair of iterators to denote a range shall treat <code>bounds_iterator</code>
 iterators as<del>-</del> if they were random access iterators, even though the 
pointer type is not a true pointer and the reference type is not a true 
reference.
—<i>end note</i>]
</p>

</blockquote>

<h3><a name="coord.bounds.iterator.func">20.6.4.2 Functions [coord.bounds.iterator.func]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">
<p>
<code>bool operator==(const bounds_iterator&amp; <var>rhs</var>) const;</code>
</p>

<blockquote>
<p>
<i>Requires:</i>
<code>*this</code> and <code><var>rhs</var></code> are iterators over the same <code>bounds</code> object.
</p>
<p>
<i>Returns:</i>
<code>idx_ == <var>rhs</var>.idx_</code>.
</p>
</blockquote>

<p>
<code>bounds_iterator&amp; operator++();</code>
</p>

<blockquote>
<p>
<i>Requires:</i>
<code>*this</code> is not the past-the-end iterator.
</p>
<p>
<i>Effects:</i>

</p><blockquote><pre><code></code></pre></blockquote>
<p>
Increments <code><var>idx_</var>[Rank - 1]</code>. If <code><var>idx_</var>[Rank - 1]</code> is equal to <code><var>bnd_</var>[Rank - 1]</code>, 
sets <code><var>idx_</var>[Rank - 1]</code> to zero and repeats the process with <code>Rank - 2</code>, and so on, until <code><var>idx_</var>[0]</code> is equal to <code><var>bnd_</var>[0]</code>, at which point<del>s</del> sets <code>idx_</code> to an unspecified past-the-end value.
</p>
<p>
<i>[Example:</i>
Given <code>bounds_iterator&lt;2&gt;</code> with <code><var>bnd_</var> == {3, 2}</code> and <code><var>idx_</var> == {0, 0}</code>, subsequent calls to <code>operator++</code> will result in <code><var>idx_</var></code> being equal to: <code>{0, 1}</code>, <code>{1, 0}</code>, <code>{1, 1}</code>, <code>{2, 0}</code>, <code>{2, 1}</code>, <em>unspecified past-the-end value</em>.
—<i>end example</i>]
</p>

<p>
<i>Returns:</i>
<code>*this</code>.
</p>
<p>

</p>
</blockquote>

<p>
<code>bounds_iterator&amp; operator--();</code>
</p>

<blockquote>
<p>
<i>Requires:</i>
There exists a <code>bounds_iterator<del>&lt;Rank&gt;</del> <var>it</var></code> such that <code>*this == ++<var>it</var></code>.
</p>
<p>
<i>Effects:</i>
<code>*this = <var>it</var></code>.
</p>
<p>
<i>Returns:</i>
<code>*this</code>.
</p>
</blockquote>

<p>
<code>reference operator*() const;</code>
</p>

<blockquote>
<p>
<i><ins>Requires:</ins></i>
<ins><code>*this</code> is not the past-the-end iterator.</ins>
</p>
<p>
<i>Returns:</i>
<code>idx_</code>.
</p>
</blockquote>

</blockquote>

<h3><a name="containers">Chapter 23 Containers library [containers]</a></h3>

<p>
Edit within paragraph 2 as follows.
</p>

<blockquote class="std">
<p>
The following subclauses describe container requirements, components for sequence containers and associative containers, and views, as summarized in Table 95.
</p>
</blockquote>

<p>
Add a row to table 95 as follows.
</p>

<blockquote class="std">
<table>
<caption>Table 95: Containers library summary</caption>
<tbody>
<tr><th>Subclause</th><th>Header(s)</th></tr>
<tr><td valign="top">23.2 Requirements</td>
<td></td></tr>
<tr><td valign="top">23.3 Sequence containers</td>
<td><code>&lt;array&gt;<br>
&lt;deque&gt;<br>
&lt;forward_list&gt;<br>
&lt;list&gt;<br>
&lt;vector&gt;</code></td></tr>
<tr><td valign="top">23.4 Associative containers</td>
<td><code>&lt;map&gt;<br>
&lt;set&gt;</code></td></tr>
<tr><td valign="top">23.5 Unordered associative containers</td>
<td><code>&lt;unordered_map&gt;<br>
&lt;unordered_set&gt;</code></td></tr>
<tr><td valign="top">23.6 Container adaptors</td>
<td><code>&lt;queue&gt;<br>
&lt;stack&gt;</code></td></tr>
<tr><td valign="top">23.7 Views</td>
<td><code>&lt;array_view&gt;</code></td></tr>
</tbody>
</table>
</blockquote>

<h3><a name="views">23.7 Views [views]</a></h3>

<p>
Add a new section after the <code>container.adaptors</code> section.
</p>

<h3><a name="views.general">23.7.1 In general [views.general]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">
<p>
The header <code>&lt;<ins>experimental/</ins>array_view&gt;</code> defines the <em>views</em> <code>array_view</code> and <code>strided_array_view</code>.
</p>
<p>
The objects in any valid range [<var>ptr</var>, <var>ptr</var> + <var>size</var>) are <em>uniformly strided</em> for a specific <var>N</var>-dimensional logical representation <var>V</var> parameterized by an <var>N</var>-dimensional vector <var>stride</var> if for every element in <var>V</var> the mapping between the location in <var>V</var> expressed as an <var>N</var>-dimensional vector <var>idx</var> and the address of the corresponding object in [<var>ptr</var>, <var>ptr</var> + <var>size</var>) can be computed as: <var>ptr</var> + <var>idx</var> · <var>stride</var>.
</p>
<p>
An <code>array_view</code> is a potentially multidimensional view on a 
sequence of uniformly strided objects of a uniform type, contiguous in 
the least significant dimension.
</p>
<p>
A <code>strided_array_view</code> is a potentially multidimensional view on a sequence of uniformly strided objects of a uniform type.
</p>
</blockquote>

<p>
Add a new synopsis:
</p>

<blockquote class="stdins">
<p>
<b>Header <code>&lt;<ins>experimental/</ins>array_view&gt;</code> synopsis</b>
</p>

<pre><code>
namespace std {
  <ins>namespace experimental {
  inline namespace fundamentals_v2 {</ins>

    // [arrayview], class template array_view
    template &lt;class T, size_t Rank = 1&gt; class array_view;

    // [stridedarrayview], class template strided_array_view
    template &lt;class T, size_t Rank = 1&gt; class strided_array_view;
  <ins>
  } // inline namespace fundamentals_v2
  } // namespace experimental</ins>
} <ins>// namespace std</ins>
</code></pre>
</blockquote>

<h3><a name="arrayview">23.7.2 Class template <code>array_view</code> [arrayview]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">
<pre><code>
namespace std {
  <ins>namespace experimental {
  inline namespace fundamentals_v2 {</ins>

    template &lt;class T, size_t Rank = 1&gt;
    class array_view {
    public:
      // constants and types
      static constexpr size_t rank = Rank;
      using offset_type          = offset&lt;Rank&gt;;
      using bounds_type         = bounds&lt;Rank&gt;;
      using size_type           = size_t;
      using value_type          = T;
      using pointer             = T*;
      using reference           = T&amp;;

      // [arrayview.cons], array_view constructors, copy, and assignment
      constexpr array_view() noexcept;

      template &lt;class Viewable&gt;
        constexpr array_view(Viewable&amp;&amp; <var>vw</var>);                              // only if Rank == 1
      template &lt;class U, size_t AnyRank&gt;
        constexpr array_view(const array_view&lt;U, AnyRank&gt;&amp; <var>rhs</var>) noexcept; // only if Rank == 1
      template &lt;size_t Extent&gt;
        constexpr array_view(value_type (&amp;<var>arr</var>)[Extent]) noexcept;  // only if Rank == 1

      template &lt;class U&gt;
        constexpr array_view(const array_view&lt;U, Rank&gt;&amp; <var>rhs</var>) noexcept;

      template &lt;class Viewable&gt;
        constexpr array_view(Viewable&amp;&amp; <var>vw</var>, bounds_type <var>bounds</var>);
      constexpr array_view(pointer <var>ptr</var>, bounds_type <var>bounds</var>);

      // [arrayview.obs], array_view observers
      constexpr bounds_type bounds() const noexcept;
      constexpr size_type   size() const noexcept;
      constexpr offset_type  stride() const noexcept;
      constexpr pointer     data() const noexcept;

      // [arrayview.elem], array_view element access
      constexpr reference operator[](const offset_type&amp; <var>idx</var>) const;

      // [arrayview.subview], array_view slicing and sectioning
      constexpr array_view&lt;T, Rank - 1&gt;
        operator[](ptrdiff_t <var>slice</var>) const;      // only if Rank &gt; 1
      constexpr strided_array_view&lt;T, Rank&gt;
        section(const offset_type&amp; <var>origin</var>, const bounds_type&amp; <var>section_bnd</var>) const;
      constexpr strided_array_view&lt;T, Rank&gt;
        section(const offset_type&amp; <var>origin</var>) const;

    private:
      pointer     data_;    // <em>exposition only</em>
      bounds_type bounds_;  // <em>exposition only</em>
    };
  <ins>
  } // inline namespace fundamentals_v2
  } // namespace experimental</ins>
} <ins>// namespace std</ins>
</code></pre>
</blockquote>


<h3><a name="arrayview.require">23.7.2.1 <code>array_view</code> requirements [arrayview.require]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">
<p>
<code>T</code> shall be an <ins>non-array</ins> object type. <i>[Note:</i> The type can be cv-qualified, resulting in semantics similar to the semantics of a pointer to cv-qualified type. —<i>end note</i>]
</p>
<p>
If <code>Rank</code> is less than 1 the program is ill-formed.
</p>
<p>
Any operation that invalidates a pointer in the range
 on which a view was created invalidates pointers and references 
returned from the view's functions.
</p>
<p>
Define <code><i>VIEW_ACCESS</i>(data, idx, stride, rank)</code> as <code>*(data + <var>offset</var>)</code> where [<i>Editorial note:</i> The following expression should be formatted as LaTeX code —<i>end note</i>] <code>offset = \sum_{i=0}^{rank - 1} idx_i \times stride_i</code>, <var>idx<sub>i</sub></var> = <code><var>idx</var>[</code><var>i</var><code>]</code>, and <var>stride<sub>i</sub></var> = <code>stride[</code><var>i</var><code>]</code>.
</p>
</blockquote>


<h3><a name="arrayview.cons">23.7.2.2 <code>array_view</code> constructors, copy, and assignment [arrayview.cons]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
For the purpose of this subclause, <em><code>Viewable</code> on 
<code>U</code></em> is a type satisfying the requirements set out in Table 104. 
In these definitions, 
let <code>v</code> denote an expression<del> which type</del>
<ins>, type of which</ins> is <code>Viewable</code> on <code>U</code>.
</p>

<table>
<caption>Table 104: <code>Viewable</code> on <code>U</code> requirements</caption>
<tbody>
<tr><th>Expression</th><th>Return type</th><th>Operational semantics</th></tr>
<tr><td><code>v.size()</code></td>
<td>Convertible to <code>ptrdiff_t</code></td>
<td></td></tr>
<tr><td><code>v.data()</code></td>
<td><del>Type </del><code>T*</code> such that <code>T*</code> is implicitly convertible to <code>U*</code>, and <code>is_same_v&lt;remove_cv_t&lt;T&gt;, remove_cv_t&lt;U&gt;&gt;</code> is <code>true</code>.</td>
<td><code>static_cast&lt;U*&gt;(v.data())</code> points to a contiguous sequence of at least <code>v.size()</code> objects of (possibly cv-qualified) type <code>remove_cv_t&lt;U&gt;</code>.</td></tr>
</tbody>
</table>

<p>
<i>[Example:</i> The type <code>vector&lt;int&gt;</code> ([vector]) meets the requirements of all of the following: <code>Viewable</code> on <code>int</code>, <code>Viewable</code> on <code>const int</code>, <code>Viewable</code> on <code>volatile int</code>, and <code>Viewable</code> on <code>const volatile int</code>. —<i>end example</i>]
</p>

<p>
<code>constexpr array_view() noexcept;</code>
</p>

<blockquote>
<p>
<i>Postconditions:</i>
<code>data_ == nullptr</code> and <code>bounds_.size() == 0</code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;class Viewable&gt;
  constexpr array_view(Viewable&amp;&amp; <var>vw</var>);</code></pre>

<blockquote>
<p>
<i>Requires:</i>
<code><var>vw</var></code> shall satisfy the requirements of <code>Viewable</code> on <code>value_type</code>.
</p>
<p>
<i>Postconditions:</i>
<code>data_ == <var>vw</var>.data()</code> and <code>bounds_.size() == <var>vw</var>.size()</code>.
</p>
<p>
<i>Remarks:</i>
This constructor shall not participate in overload resolution unless:
</p><ul>
<li><code>Rank</code> is 1,</li>
<li><code>Viewable</code> satisfies the syntactic requirements set in Table 104 for <code>Viewable</code> on <code>value_type</code>, and</li>
<li><code>decay_t&lt;Viewable&gt;</code> is not a specialization of <code>array_view</code>.</li>
</ul>
<i> [Note:</i>
This provision ensures that either the following or the implicit copy constructor — both of which are <code>noexcept</code> — will be selected by overload resolution instead. 
—<i>end note</i>]
<p></p>
</blockquote>

<p>
</p><pre><code>template &lt;class U, size_t AnyRank&gt;
  constexpr array_view(const array_view&lt;U, AnyRank&gt;&amp; <var>rhs</var>) noexcept;</code></pre>

<blockquote>
<p>
<i>Postconditions:</i>
<code>data_ == <var>rhs</var>.data()</code> and <code>bounds_.size() == <var>rhs</var>.size()</code>.
</p>
<p>
<i>Remarks:</i>
This constructor shall not participate in overload resolution unless:
</p><ul>
<li><code>Rank</code> is 1,</li>
<li><code>is_convertible_v&lt;add_pointer_t&lt;U&gt;, pointer&gt;</code> is <code>true</code>, and</li>
<li><code>is_same_v&lt;remove_cv_t&lt;U&gt;, remove_cv_t&lt;value_type&gt;&gt;</code> is <code>true</code>.</li>
</ul>
<p></p>
</blockquote>

<p>
</p><pre><code>template &lt;size_t Extent&gt;
  constexpr array_view(value_type (&amp;<var>arr</var>)[Extent]) noexcept;</code></pre>

<blockquote>
<p>
<i>Postconditions:</i>
<code>data_ == <var>arr</var></code> and <code>bounds_.size() == Extent</code>.
</p>
<p>
<i>Remarks:</i>
This constructor shall not participate in overload resolution unless <code>Rank</code> is 1.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;class U&gt;
  constexpr array_view(const array_view&lt;U, Rank&gt;&amp; <var>rhs</var>) noexcept;</code></pre>

<blockquote>
<p>
<i>Postconditions:</i>
<code>data_ == <var>rhs</var>.data()</code> and <code>bounds_ == <var>rhs</var>.bounds()</code>.
</p>
<p>
<i>Remarks:</i>
This constructor shall not participate in overload resolution unless <code>is_convertible_v&lt;add_pointer_t&lt;U&gt;, pointer&gt;</code> is <code>true</code> and <code>is_same_v&lt;remove_cv_t&lt;U&gt;, remove_cv_t&lt;value_type&gt;&gt;</code> is <code>true</code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;class Viewable&gt;
  constexpr array_view(Viewable&amp;&amp; <var>vw</var>, bounds_type <var>bounds</var>);</code></pre>

<blockquote>
<p>
<i>Requires:</i>
<code><var>bounds</var>.size() &lt;= <var>vw</var>.size()</code>.
</p>
<p>
<i>Postconditions:</i>
<code>data_ == <var>vw</var>.data()</code> and <code>bounds_ == <var>bounds</var></code>.
</p>
<p>
<i>Remarks:</i>
This constructor shall not participate in overload resolution unless <code>Viewable</code> satisfies the syntactic requirements set in Table 104 for <code>Viewable</code> on <code>value_type</code>.
</p>
<p>
<i>[Note:</i>
This constructor may be used to create an <code>array_view</code> with a different rank and/or bounds than the original <code>array_view</code>, i.e. reshape the view.
—<i>end note</i>]
</p>
</blockquote>

<p>
</p><pre><code>constexpr array_view(pointer <var>ptr</var>, bounds_type <var>bounds</var>);</code></pre>

<blockquote>
<p>
<i>Requires:</i>
<code>[<var>ptr</var>, <var>ptr</var> + <var>bounds</var>.size())</code> is a valid range.
</p>
<p>
<i>Postconditions:</i>
<code>data_ == <var>ptr</var></code> and <code>bounds_ == <var>bounds</var></code>.
</p>
</blockquote>

<p>
</p><pre><code></code></pre>

<blockquote>

</p>
</blockquote>

</blockquote>


<h3><a name="arrayview.obs">23.7.2.3 <code>array_view</code> observers [arrayview.obs]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
<code>constexpr bounds_type bounds() const noexcept;</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
<code>bounds_</code>.
</p>
</blockquote>

<p>
<code>constexpr size_type size() const noexcept;</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
<code>bounds().size()</code>.
</p>
</blockquote>

<p>
<code>constexpr offset_type stride() const noexcept;</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
A value <code><var>s</var></code> such that:
</p><ul>
<li><code><var>s</var>[<var>i</var>] == <var>s</var>[<var>i</var> + 1] * bounds()[<var>i</var> + 1]</code>, when <code>0 &lt;= <var>i</var></code> and <code><var>i</var> &lt; Rank - 1</code>.</li>
<li><code><var>s</var>[<var>i</var>] == 1</code>, when <code><var>i</var> == Rank - 1</code>.</li>
</ul>
</blockquote>

<p>
<code>constexpr pointer data() const noexcept;</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
<code>data_</code>.
</p>
</blockquote>

</blockquote>


<h3><a name="arrayview.elem">23.7.2.4 <code>array_view</code> element access [arrayview.elem]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
<code>constexpr reference operator[](const offset_type&amp; <var>idx</var>) const;</code>
</p>

<blockquote>
<p>
<i>Requires:</i>
<code>bounds().contains(<var>idx</var>) == true</code>.
</p>
<p>
<i>Returns:</i>
<code><i>VIEW_ACCESS</i>(data(), <var>idx</var>, stride(), Rank)</code>.
</p>
</blockquote>

</blockquote>


<h3><a name="arrayview.subview">23.7.2.5 <code>array_view</code> slicing and sectioning [arrayview.subview]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
</p><pre><code>constexpr array_view&lt;T, Rank - 1&gt;
  operator[](ptrdiff_t <var>slice</var>) const;</code></pre>

<blockquote>
<p>
<i>Requires:</i>
<code>0 &lt;= <var>slice</var></code> and <code><var>slice</var> &lt; bounds()[0]</code>.
</p>
<p>
<i>Returns:</i>
A view <code><var>vw</var></code> such that <code><var>vw</var>.data_</code> is <code>(*this)[{<var>slice</var>, 0, 0, ..., 0}]</code>, and <code><var>vw</var>.bounds_</code> is <code>{bounds()[1], bounds()[2], ..., bounds()[Rank - 1]}</code>.
</p>
<p>
<i>Remarks:</i>
This function shall not participate in overload resolution unless <code>Rank &gt; 1</code>.
</p>
</blockquote>

<p>
</p><pre><code>constexpr strided_array_view&lt;T, Rank&gt;
  section(const offset_type&amp; <var>origin</var>, const bounds_type&amp; <var>section_bnd</var>) const;</code></pre>

<blockquote>
<p>
<i>Requires:</i>
<code>bounds().contains(<var>origin</var> + <var>idx</var>) == true</code> for any <code>offset_type <var>idx</var></code> such that <code><var>section_bnd</var>.contains(<var>idx</var>) == true</code>.
</p>
<p>
<i>Returns:</i>
A strided view <code><var>vw</var></code> such that <code><var>vw</var>.data_</code> is <code>(*this)[<var>origin</var>]</code>, <code><var>vw</var>.stride_</code> is <code>stride()</code>, and <code><var>vw</var>.bounds_</code> is <code><var>section_bnd</var></code>.
</p>
</blockquote>

<p>
</p><pre><code>constexpr strided_array_view&lt;T, Rank&gt;
  section(const offset_type&amp; <var>origin</var>) const;</code></pre>

<blockquote>
<p>
<i>Requires:</i>
<code>bounds().contains(<var>origin</var> + <var>idx</var>) == true</code> for any <code>offset_type <var>idx</var></code> such that <code>(bounds() - <var>origin</var>).contains(<var>idx</var>) == true</code>.
</p>
<p>
<i>Returns:</i>
A strided view <code><var>vw</var></code> such that <code><var>vw</var>.data_</code> is <code>(*this)[<var>origin</var>]</code>, <code><var>vw</var>.stride_</code> is <code>stride()</code>, and <code><var>vw</var>.bounds_</code> is <code>bounds() - <var>origin</var></code>.
</p>
</blockquote>

</blockquote>


<h3><a name="stridedarrayview">23.7.3 Class template <code>strided_array_view</code> [stridedarrayview]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">
<pre><code>
namespace std {
  <ins>namespace experimental {
  inline namespace fundamentals_v2 {</ins>

    template &lt;class T, size_t Rank = 1&gt;
    class strided_array_view {
    public:
      // constants and types
      static constexpr size_t rank = Rank;
      using offset_type          = offset&lt;Rank&gt;;
      using bounds_type         = bounds&lt;Rank&gt;;
      using size_type           = size_t;
      using value_type          = T;
      using pointer             = T*;
      using reference           = T&amp;;

      // [stridedarrayview.cons], strided_array_view constructors, copy, and assignment
      constexpr strided_array_view() noexcept;

      template &lt;class U&gt;
        constexpr strided_array_view(const array_view&lt;U, Rank&gt;&amp; <var>rhs</var>) noexcept;
      template &lt;class U&gt;
        constexpr strided_array_view(const strided_array_view&lt;U, Rank&gt;&amp; <var>rhs</var>) noexcept;

      constexpr strided_array_view(pointer <var>ptr</var>, bounds_type <var>bounds</var>, offset_type <var>stride</var>);

      // [stridedarrayview.obs], strided_array_view observers
      constexpr bounds_type bounds() const noexcept;
      constexpr size_type   size() const noexcept;
      constexpr offset_type  stride() const noexcept;

      // [stridedarrayview.elem], strided_array_view element access
      constexpr reference operator[](const offset_type&amp; <var>idx</var>) const;

      // [stridedarrayview.subview], strided_array_view slicing and sectioning
      constexpr strided_array_view&lt;T, Rank - 1&gt;
        operator[](ptrdiff_t <var>slice</var>) const;      // only if Rank &gt; 1
      constexpr strided_array_view&lt;T, Rank&gt;
        section(const offset_type&amp; <var>origin</var>, const bounds_type&amp; <var>section_bnd</var>) const;
      constexpr strided_array_view&lt;T, Rank&gt;
        section(const offset_type&amp; <var>origin</var>) const;

    private:
      pointer     data_;    // <em>exposition only</em>
      bounds_type bounds_;  // <em>exposition only</em>
      offset_type stride_;  // <em>exposition only</em>
    };
  <ins>
  } // inline namespace fundamentals_v2
  } // namespace experimental</ins>
} <ins>// namespace std</ins>
</code></pre>
</blockquote>


<h3><a name="stridedarrayview.require">23.7.3.1 <code>strided_array_view</code> requirements [stridedarrayview.require]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">
<p>
<code>T</code> shall be an <ins>non-array</ins> object type. <i>[Note:</i> The type can be cv-qualified, resulting in semantics similar to the semantics of a pointer to cv-qualified type. —<i>end note</i>]
</p>
<p>
If <code>Rank</code> is less than 1 the program is ill-formed.
</p>
<p>
Any operation that invalidates a pointer in the range
 on which a view was created invalidates pointers and references 
returned from the view's functions.
</p>
<p>
Define <code><i>VIEW_ACCESS</i>(data, idx, stride, rank)</code> as <code>*(data + <var>offset</var>)</code> where [<i>Editorial note:</i> The following expression should be formatted as LaTeX code —<i>end note</i>] <code>offset = \sum_{i=0}^{rank - 1} idx_i \times stride_i</code>, <var>idx<sub>i</sub></var> = <code><var>idx</var>[</code><var>i</var><code>]</code>, and <var>stride<sub>i</sub></var> = <code>stride[</code><var>i</var><code>]</code>.
</p>
</blockquote>


<h3><a name="stridedarrayview.cons">23.7.3.2 <code>strided_array_view</code> constructors, copy, and assignment [stridedarrayview.cons]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
<code>constexpr strided_array_view() noexcept;</code>
</p>

<blockquote>
<p>
<i>Postconditions:</i>
<code>data_ == nullptr</code>, <code>bounds_.size() == 0</code>, and <code>stride_ == offset_type{}</code>.
</p>
</blockquote>

<p>
</p><pre><code>template &lt;class U&gt;
  constexpr strided_array_view(const array_view&lt;U, Rank&gt;&amp; <var>rhs</var>) noexcept;
template &lt;class U&gt;
  constexpr strided_array_view(const strided_array_view&lt;U, Rank&gt;&amp; <var>rhs</var>) noexcept;</code></pre>

<blockquote>
<p>
<i>Postconditions:</i>
For both constructors, <code>bounds_ == <var>rhs</var>.bounds()</code> and <code>stride_ == <var>rhs</var>.stride()</code>. For the first constructor, <code>data_ == <var>rhs</var>.data()</code>. For the second constructor, <code>data_ == <var>rhs</var>.data_</code>.
</p>
<p>
<i>Remarks:</i>
These constructors shall not participate in overload resolution unless <code>is_convertible_v&lt;add_pointer_t&lt;U&gt;, pointer&gt;</code> is <code>true</code> and <code>is_same_v&lt;remove_cv_t&lt;U&gt;, remove_cv_t&lt;value_type&gt;&gt;</code> is <code>true</code>.
</p>
</blockquote>

<p>
</p><pre><code>constexpr strided_array_view(pointer <var>ptr</var>, bounds_type <var>bounds</var>, offset_type <var>stride</var>);</code></pre>

<blockquote>
<p>
<i>Requires:</i>
For any <code>offset_type <var>idx</var></code> such that <code><var>bounds</var>.contains(<var>idx</var>)</code>:
</p><ul>
<li>The expression <code><var>idx</var>[<var>i</var>] * <var>stride</var>[<var>i</var>]</code> shall be well formed and shall have well defined behavior [<i>Note:</i> It follows that the result does not overflow type <code>ptrdiff_t</code>. —<i>end note</i>] for all <var>i</var> in the range <code>[0, Rank)</code>.</li>
<li>The expression <code><i>VIEW_ACCESS</i>(<var>ptr</var>, <var>idx</var>, <var>stride</var>, Rank)</code> shall be well formed and shall have well defined behavior.</li>
</ul>
<p>
<i>Postconditions:</i>
<code>data_ == <var>ptr</var></code>, <code>bounds_ == <var>bounds</var></code>, and <code>stride_ == <var>stride</var></code>.
</p>
</blockquote>

<p>
</p><pre><code></code></pre>

<blockquote>
<p>

</p>
</blockquote>

</blockquote>


<h3><a name="stridedarrayview.obs">23.7.3.3 <code>strided_array_view</code> observers [stridedarrayview.obs]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
<code>constexpr bounds_type bounds() const noexcept;</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
<code>bounds_</code>.
</p>
</blockquote>

<p>
<code>constexpr size_type size() const noexcept;</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
<code>bounds().size()</code>.
</p>
</blockquote>

<p>
<code>constexpr offset_type stride() const noexcept;</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
<code>stride_</code>.
</p>
</blockquote>

</blockquote>


<h3><a name="stridedarrayview.elem">23.7.3.4 <code>strided_array_view</code> element access [stridedarrayview.elem]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
<code>constexpr reference operator[](const offset_type&amp; <var>idx</var>) const;</code>
</p>

<blockquote>
<p>
<i>Requires:</i>
<code>bounds().contains(<var>idx</var>) == true</code>.
</p>
<p>
<i>Returns:</i>
<code><i>VIEW_ACCESS</i>(data_, <var>idx</var>, stride(), Rank)</code>.
</p>
</blockquote>

</blockquote>


<h3><a name="stridedarrayview.subview">23.7.3.5 <code>strided_array_view</code> slicing and sectioning [stridedarrayview.subview]</a></h3>

<p>
Add a new section:
</p>

<blockquote class="stdins">

<p>
</p><pre><code>constexpr strided_array_view&lt;T, Rank - 1&gt;
  operator[](ptrdiff_t <var>slice</var>) const;</code></pre>

<blockquote>
<p>
<i>Requires:</i>
<code>0 &lt;= <var>slice</var></code> and <code><var>slice</var> &lt; bounds()[0]</code>.
</p>
<p>
<i>Returns:</i>
A strided view <code><var>vw</var></code> such that <code><var>vw</var>.data_</code> is <code>(*this)[{<var>slice</var>, 0, 0, ..., 0}]</code>, <code><var>vw</var>.bounds_</code> is <code>{bounds()[1], bounds()[2], ..., bounds()[Rank - 1]}</code>, and <code><var>vw</var>.stride_</code> is <code>{stride()[1], stride()[2], ..., stride()[Rank - 1]}</code>.
</p>
<p>
<i>Remarks:</i>
This function shall not participate in overload resolution unless <code>Rank &gt; 1</code>.
</p>
</blockquote>

<p>
</p><pre><code>constexpr strided_array_view&lt;T, Rank&gt;
  section(const offset_type&amp; <var>origin</var>, const bounds_type&amp; <var>section_bnd</var>) const;</code></pre>

<blockquote>
<p>
<i>Requires:</i>
<code>bounds().contains(<var>origin</var> + <var>idx</var>) == true</code> for any <code>offset_type <var>idx</var></code> such that <code><var>section_bnd</var>.contains(<var>idx</var>) == true</code>.
</p>
<p>
<i>Returns:</i>
A strided view <code><var>vw</var></code> such that <code><var>vw</var>.data_</code> is <code>(*this)[<var>origin</var>]</code>, <code><var>vw</var>.stride_</code> is <code>stride()</code>, and <code><var>vw</var>.bounds_</code> is <code><var>section_bnd</var></code>.
</p>
</blockquote>

<p>
</p><pre><code>constexpr strided_array_view&lt;T, Rank&gt;
  section(const offset_type&amp; <var>origin</var>) const;</code></pre>

<blockquote>
<p>
<i>Requires:</i>
<code>bounds().contains(<var>origin</var> + <var>idx</var>) == true</code> for any <code>offset_type <var>idx</var></code> such that <code>(bounds() - <var>origin</var>).contains(<var>idx</var>) == true</code>.
</p>
<p>
<i>Returns:</i>
A strided view <code><var>vw</var></code> such that <code><var>vw</var>.data_</code> is <code>(*this)[<var>origin</var>]</code>, <code><var>vw</var>.stride_</code> is <code>stride()</code>, and <code><var>vw</var>.bounds_</code> is <code>bounds() - <var>origin</var></code>.
</p>
</blockquote>

</blockquote>


<h3><a name="iterator.range">24.7 range access [iterator.range]</a></h3>

<p>
Edit within paragraph 1 as follows.
</p>

<blockquote class="std">
<p>
In addition to being available via inclusion of the <code>&lt;iterator&gt;</code> header, the function templates in 24.7 are
available when any of the following headers are included: <code>&lt;array&gt;</code>, <code>&lt;coordinate&gt;</code>, <code>&lt;deque&gt;</code>, <code>&lt;forward_list&gt;</code>, <code>&lt;list&gt;</code>, <code>&lt;map&gt;</code>, <code>&lt;regex&gt;</code>, <code>&lt;set&gt;</code>, <code>&lt;string&gt;</code>, <code>&lt;unordered_map&gt;</code>, <code>&lt;unordered_set&gt;</code>, and <code>&lt;vector&gt;</code>.
</p>
</blockquote>

</body></html>