<!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=US-ASCII">

<style type="text/css">

body { color: #000000; background-color: #FFFFFF; }
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }

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.5empadding-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>Working Draft, Technical Specification &mdash; Array Extensions</title>
</head>

<body>
<h1>Working Draft, Technical Specification &mdash; Array Extensions</h1>

<p>
ISO/IEC JTC1 SC22 WG21 N3820 - 2013-10-10
</p>

<p>
Editor: Lawrence Crowl, Lawrence@Crowl.org
</p>


<h2>Contents</h2>

<p>
<a href="#Foreword">Foreword</a><br>
<a href="#Introduction">Introduction</a><br>
<a href="#Scope">Scope</a><br>
<a href="#Conformance">Conformance</a><br>
<a href="#Normative">Normative references</a><br>
<a href="#Terms">Terms and definitions</a><br>
<a href="#Requirements">Requirements</a><br>
<a href="#Wording">Wording changes</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#basic.types">3.9 Types [basic.types]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#basic.compound">3.9.2 Compound Types [basic.compound]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#conv.array">4.2 Array-to-pointer conversion [conv.array]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#expr.prim.lambda">5.1.2 Lambda expressions [expr.prim.lambda]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#expr.typeid">5.2.8 Type identification [expr.typeid]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#expr.unary.op">5.3.1 Unary operators [expr.unary.op]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#expr.sizeof">5.3.3 Sizeof [expr.sizeof]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.typedef">7.1.3 The <code>typedef</code> specifier [dcl.typedef]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.type.simple">7.1.6.2 Simple type specifiers [dcl.type.simple]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.decl">8 Declarators [dcl.decl]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.ptr">8.3.1 Pointers [dcl.ptr]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.ref">8.3.2 References [dcl.ref]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.array">8.3.4 Arrays [dcl.array]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.fct">8.3.5 Functions [dcl.fct]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.init.aggr">8.5.1 Aggregates [dcl.init.aggr]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dcl.init.string">8.5.2 Character arrays [dcl.init.string]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#class.mem">9.2 Class members [class.mem]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#temp.param">14.1 Template parameters [temp.param]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#temp.param">15.1 Throwing an exception [except.throw]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#bad.array.length">18.6.2.new Class <code>bad_array_length</code> [bad.array.length]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#containers">Chapter 23 Containers library [containers]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#sequence.reqmts">23.2.3 Sequence containers [sequence.reqmts]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#sequences">23.3.1 In general [sequences.general]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dynarray">23.3.4 Class template <code>dynarray</code> [dynarray]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dynarray.overview">23.3.4.1 Class template <code>dynarray</code> overview [dynarray.overview]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dynarray.cons">23.3.4.2 <code>dynarray</code> constructor and destructor [dynarray.cons]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dynarray.data">23.3.4.3 <code>dynarray::data</code> [dynarray.data]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dynarray.mutate">23.3.4.4 Mutating operations [dynarray.mutate]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dynarray.zero">23.3.4.5 Zero sized dynarrays [dynarray.zero]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#dynarray.traits">23.3.4.6 Traits [dynarray.traits]</a><br>
<a href="#Revision">Revision History</a><br>
</p>


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

<p>
<em>
ISO requires a foreword,
with most content supplied by the Central Secretariat of ISO.
It will be added by the editor before the final document is sent to ISO.
</em>
</p>


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

<p>
<em>
ISO specifies
"The introduction is an optional preliminary element used, if required,
to give specific information or commentary
about the technical content of the document,
and about the reasons prompting its preparation.
It shall not contain requirements."
</em>
</p>

<p>
This Technical Specification
specifies requirements for implementations
of various extensions for arrays to the C++ language and library.
Included are:
</p>

<dl>

<dt>arrays of runtime bound</dt>
<dd>
<p>
The core language is extended to permit run-time computation
of the bound of an array with automatic storage duration.
</p>
</dd>

<dt>class <code>dynarray</code></dt>
<dd>
<p>
The library is extended with a class that
specifies an array size only on construction.
</p>
</dd>

</dl>


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

<p>
This Technical Specification
is applicable to information technology systems
that implement the C++ language and standard library.
This Technical Specification
is applicable only to vendors who wish to provide the interface it describes.
</p>


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

<p>
<em>No content (yet).</em>
</p>


<h2><a name="Normative">Normative references</a></h2>

<p>
The following referenced documents
are indispensable for the application of this document.
For dated references, only the edition cited applies.
For undated references,
the latest edition of the referenced document (including any amendments)
applies.
<em>ISO required wording.</em>
</p>

<ul>

<li>ISO/IEC 14882, Programming Language C++</li>

</ul>
     
<p>
[<i>Note:</i>
The programming language and library described in ISO/IEC 14882
is herein called <dfn>the C++ Standard</dfn>.
&mdash;<i>end note</i>]
</p>

<p>
Unless otherwise specified,
the whole of the C++ Standard's Library introduction [lib.library]
is included into this Technical Specification by reference.
</p>


<h2><a name="Terms">Terms and definitions</a></h2>

<p>
All terms and definitions in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf">
N3797</a>.
apply unless otherwise stated.
</p>


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

<p>
All requirements in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf">
N3797</a>.
apply unless otherwise stated.
</p>


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

<p>
The proposed wording changes are relative to
the expected contents of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf">
N3797</a>.
</p>


<h3><a name="basic.types">3.9 Types [basic.types]</a></h3>

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

<blockquote class="std">
<p>
A type is a <em>literal type</em> if it is:
</p>
<ul>
<li>...</li>
<li>an array of literal type <ins>other than an array of runtime bound</ins>; or
<li>...</li>
</ul>
</blockquote>


<h3><a name="basic.compound">3.9.2 Compound Types [basic.compound]</a></h3>

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

<blockquote class="std">
<p>
These methods of constructing types can be applied recursively;
restrictions are mentioned in
8.3.1 dcl.ptr, 8.3.4 dcl.array, 8.3.5 dcl.fct, and 8.3.2 dcl.ref.
<ins>Constructing a type such that
the number of bytes in its object representation
exceeds the maximum value representable
in the type <code>std::size_t</code> (18.2 support.types)
is ill-formed.</ins>
</p>
</blockquote>


<h3><a name="conv.array">4.2 Array-to-pointer conversion [conv.array]</a></h3>

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

<blockquote class="std">
<p>
An <del>lvalue or rvalue</del> <ins>expression</ins> of type
"array of N T"<ins>, "array of runtime bound of T",</ins>
or "array of unknown bound of T"
can be converted to a prvalue of type "pointer to T".
The result is a pointer to the first element of the array.
</p>
</blockquote>


<h3><a name="expr.prim.lambda">5.1.2 Lambda expressions [expr.prim.lambda]</a></h3>

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

<blockquote class="std">
<p>
...
[<i>Note:</i>...]
<ins>An array of runtime bound (8.3.4 dcl.array)
shall not be captured by copy.</ins>
</p>
</blockquote>

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

<blockquote class="std">
<p>
An entity is <dfn>captured by reference</dfn>
if it is implicitly or explicitly captured but not captured by copy.
It is unspecified whether additional unnamed non-static data members
are declared in the closure type for entities captured by reference.
<ins>
[<i>Note:</i>
Capturing by reference an array of runtime bound
also implicitly captures the value of the bound
to support the range-based for statement (6.5.4 stmt.ranged).
&mdash;<i>end note</i>]
</ins>
</p>
</blockquote>


<h3><a name="expr.typeid">5.2.8 Type identification [expr.typeid]</a></h3>

<p>
Insert a new paragraph before paragraph 2
(starting "When <code>typeid</code> is applied ...").
</p>

<blockquote class="stdins">
<p>
The <code>typeid</code> operator
shall not be applied to an array of runtime bound.
</p>
</blockquote>


<h3><a name="expr.unary.op">5.3.1 Unary operators [expr.unary.op]</a></h3>

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

<blockquote class="std">
<p>
The result of the unary &amp; operator is a pointer to its operand.
The operand shall be an lvalue
<ins>of type other than "array of runtime bound"</ins>
or a <var>qualified-id</var>.
...
</p>
</blockquote>


<h3><a name="expr.sizeof">5.3.3 Sizeof [expr.sizeof]</a></h3>

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

<blockquote class="std">
<p>
...
The <code>sizeof</code> operator shall not be applied
to an expression that has function or incomplete type,
to an enumeration type whose underlying type
is not fixed before all its enumerators have been declared,
<ins>to an array of runtime bound,</ins>
to the parenthesized name of such types,
or to an lvalue that designates a bit-field.
...
<p>
</blockquote>


<h3><a name="dcl.typedef">7.1.3 The <code>typedef</code> specifier [dcl.typedef]</a></h3>

<p>
Insert a new paragraph before paragraph 3
(starting "In a given non-class scope").
</p>

<blockquote class="stdins">
<p>
A <var>typedef-name</var> shall not name an array of runtime bound.
</p>
</blockquote>


<h3><a name="dcl.type.simple">7.1.6.2 Simple type specifiers [dcl.type.simple]</a></h3>

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

<blockquote class="std">
<p>
For an expression <code>e</code>,
The type denoted by <code>decltype(e)</code> is defined as follows:
</p>
<ul>
<li><ins>if <code>e</code> has type "array of runtime bound",
the program is ill-formed;</ins></li>
<li><ins>otherwise,</ins> if <code>e</code> is an unparenthesized</li>
<li>...</li>
</ul>
</blockquote>


<h3><a name="dcl.decl">8 Declarators [dcl.decl]</a></h3>

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

<blockquote class="std">
<p>
...
</p>
<dl>
<dt><var>noptr-declarator</var>:</dt>
<dd><var>declarator-id attribute-specifier-seq<sub>opt</sub></var></dd>
<dd><var>noptr-declarator parameters-and-qualifiers</var>
<dd><var>noptr-declarator</var> <code>[</code>
<del><var>constant-expression<sub>opt</sub></var></del>
<ins><var>expression<sub>opt</sub></var></ins>
<code>]</code> <var>attribute-specifier-seq<sub>opt</sub></var></dd>
<dd><code>(</code> <var>ptr-declarator</var> <code>)</code>
</dl>
<p>
...
</p>
</blockquote>


<h3><a name="dcl.ptr">8.3.1 Pointers [dcl.ptr]</a></h3>

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

<blockquote class="std">
<p>
...
Similarly, the optional <var>attribute-specifier-seq</var> (7.6.1)
appertains to the pointer and not to the object pointed to.
<ins>There shall be no pointers to arrays of runtime bound.</ins>
</p>
</blockquote>


<h3><a name="dcl.ref">8.3.2 References [dcl.ref]</a></h3>

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

<blockquote class="std">
<p>
There shall be no references to references,
<ins>no references to arrays of runtime bound</ins>,
no arrays of references, and no pointers to references.
...
</p>
</blockquote>


<h3><a name="dcl.array">8.3.4 Arrays [dcl.array]</a></h3>

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

<blockquote class="std">
<p>
In a declaration <code>T D</code> where <code>D</code> has the form
</p>
<blockquote>
<p>
<code>D1 [</code>
<del><var>constant-expression<sub>opt</sub></var></del>
<ins><var>expression<sub>opt</sub></var></ins>
<code>]</code> <var>attribute-specifier-seq<sub>opt</sub></var>
</p>
</blockquote>
<p>
and the type of the identifier in the declaration <code>T D1</code>
is "<var>derived-declarator-type-list</var> <code>T</code>",
then the type of the identifier of <code>D</code> is an array type;
if the type of the identifier of <code>D</code>
contains the <code>auto</code> <var>type-specifier</var>,
the program is ill-formed.
<code>T</code> is called the array <dfn>element type</dfn>;
this type shall not be a reference type,
the (possibly cv-qualified) type <code>void</code>,
a function type,
<ins>an array of unknown or runtime bound,</ins>
or an abstract class type.
<ins>
Except as noted below,
if the <var>expression</var> is omitted,
the type of the identifier of <code>D</code>
is "<var>derived-declarator-type-list</var> array
of unknown bound of <code>T</code>".
If the <var>expression</var> is present,
it is implicitly converted to <code>std::size_t</code>.
The <var>expression</var> is erroneous if:
</ins>
</p>

<ul>

<li><ins>its value before converting to <code>std::size_t</code> or,
in the case of an expression of class type,
before application of the second standard conversion (13.3.3.1.2 over.ics.user)
is less than or equal to zero;</ins></li>

<li><ins>its value is such that the size of the allocated object
would exceed the implementation-defined limit (annex B implimits);</ins></li>

<li><ins>the initializer of the object is a <var>braced-init-list</var>
whose number of (top-level) <var>initializer-clause</var>s
exceeds the number of elements to initialize; or</ins></li>

<li><ins>the object is initialized with a string literal
and there are more initializers than there are array elements.</ins></li>

</ul>

<p>
<ins>
If the <var>expression</var>, after converting to <code>std::size_t</code>,
is a core constant expression and the <var>expression</var> is erroneous,
the program is ill-formed.</ins>
</p>

<p>
<ins>
If the <var>expression</var>, after converting to <code>std::size_t</code>,
is a core constant expression whose value is <code>N</code>,
the type of the identifier of <code>D</code>
is "<var>derived-declarator-type-list</var> array of <code>N T</code>".
</ins>
</p>

<p>
<ins>
Otherwise, the type of the identifier of <code>D</code>
is "<var>derived-declarator-type-list</var> array
of runtime bound of <code>T</code>"
and the value of the <var>expression</var>
designates the number of elements <code>N</code> in the array.
If the <var>expression</var> is erroneous,
an exception of a type
that would match a handler (15.3 except.handle)
of type <code>std::bad_array_length</code> (18.6.2.2 bad.array.length)
is thrown.
</ins>
</p>

<p>
<del>
If the <var>constant-expression (5.19 expr.const)</var> is present,
it shall be an integral constant expression
and its value shall be greater than zero.
The constant expression
specifies the bound of (number of elements in) the array.
If the value of the constant expression is <code>N</code>,
the array has <code>N</code> elements
numbered <code>0</code> to <code>N-1</code>,
and the type of the identifier of <code>D</code>
is "<var>derived-declarator-type-list</var> array of <code>N T</code>".
</del>
</p>

<p>
An object of array type contains
a contiguously allocated non-empty set
of <code>N</code> subobjects of type <code>T</code>.
<del>Except as noted below,
if the constant expression is omitted,
the type of the identifier of <code>D</code>
is "<var>derived-declarator-type-list</var> array
of unknown bound of <code>T</code>",
an incomplete object type.
</del>
The type "<var>derived-declarator-type-list</var> array of <code>N T</code>"
is a different type from the type
"<var>derived-declarator-type-list</var> array
of unknown bound of <code>T</code>",
see 3.9 basic.types.
Any type of the form "<var>cv-qualifier-seq</var> array of <code>N T</code>"
is adjusted to
"array of <code>N</code> <var>cv-qualifier-seq</var> <code>T</code>",
and similarly for "array of unknown bound of <code>T</code>"
<ins>and "array of runtime bound of <code>T</code>"</ins>.
The optional <var>attribute-specifier-seq</var> appertains to the array.
[<i>Example:</i>
<pre><code>
typedef int A[5], AA[2][3];
typedef const A CA;   <i>// type is "array of 5 const int"</i>
typedef const AA CAA; <i>// type is "array of 2 array of 3 const int"</i>

<ins>void f(unsigned int n) {
  int a[n]; <i>// type of "a" is "array of runtime bound of int"</i>
}</ins>
</code></pre>
<p>
&mdash;<i>end example</i>]
[<i>Note:</i> ... ]
</p>
</blockquote>

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

<blockquote class="std">
<p>
When several "array of" specifications are adjacent,
a multidimensional array is created<del>;
only the first of the constant expressions
that specify the bounds of the arrays
may be omitted</del>.
In addition to ...
</p>
</blockquote>

<p>
Add a new paragraph before paragraph 4.
</p>

<blockquote class="stdins">
<p>
An array of runtime bound
shall only be used as the type of a local object
with automatic storage duration.
If the size of the array
exceeds the size of the memory available
for objects with automatic storage duration,
the behavior is undefined.
[<i>Footnote:</i>
Implementations that detect this case
are encouraged to throw an exception
that would match a handler (15.3 except.handle)
of type <code>std::bad_array_length</code> (18.6.2.2 bad.array.length).
&mdash;<i>end footnote</i>]
It is unspecified
whether a global allocation function (3.7.4 basic.stc.dynamic)
is invoked to obtain storage for the array.
If it is invoked,
the corresponding global deallocation function
is invoked to release the storage after the lifetime of the array ended.
[<i>Footnote:</i>
Alternatively,
an implementation could allocate such an array on the usual stack
or obtain storage via <code>malloc</code> (20.6.13 c.malloc).
&mdash;<i>end footnote</i>]
</p>
</blockquote>


<h3><a name="dcl.fct">8.3.5 Functions [dcl.fct]</a></h3>

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

<blockquote class="std">
<p>
If the type of a parameter
includes a type of the form
<ins>"array of runtime bound of <code>T</code>",</ins>
"pointer to array of unknown bound of <code>T</code>"<ins>,</ins>
or "reference to array of unknown bound of <code>T</code>,"
the program is ill-formed.
[<i>Footnote:</i> ...]
Functions shall not have a return type of type array or function,
although they may have a return type
of type pointer or reference to such things.
</p>
</blockquote>


<h3><a name="dcl.init.aggr">8.5.1 Aggregates [dcl.init.aggr]</a></h3>

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

<blockquote class="std">
<p>
<ins>For types other than arrays of runtime bound (8.3.4 dcl.array),</ins>
<del>An</del> <ins>an</ins> <var>initializer-list</var>
is ill-formed if the number of <var>initializer-clause</var>s
exceeds the number of members or elements to initialize.
[<i>Example:</i> ... ]
</p>
</blockquote>


<h3><a name="dcl.init.string">8.5.2 Character arrays [dcl.init.string]</a></h3>

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

<blockquote class="std">
<p>
<ins>[<i>Note:</i></ins>
There cannot be more initializers than there are array elements<ins>;
see 8.3.4 dcl.array</ins>.
[<i>Example:</i>
</p>
<pre><code>
char cv[4] = "asdf";                 <i>// error</i>
</code></pre>
<p>
is ill-formed
since there is no space for the implied trailing <code>'\0'</code>.
<ins>&mdash;<i>end note</i>]</ins>
</p>
</blockquote>


<h3><a name="class.mem">9.2 Class members [class.mem]</a></h3>

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

<blockquote class="std">
<p>
<del>Non-static</del> <ins>A non-static</ins> (9.4 class.static)
data <del>members</del> <ins>member</ins>
shall not have incomplete <del>types.</del> <ins>type
or type "array of runtime bound".</ins>
<ins>[<i>Note:</i></ins>
In particular,
a class <code>C</code>
shall not contain a non-static member of class <code>C</code>,
but it can contain a pointer or reference to an object of class <code>C</code>.
<ins>&mdash;<i>end note</i>]</ins>
</p>
</blockquote>


<h3><a name="temp.param">14.1 Template parameters [temp.param]</a></h3>

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

<blockquote class="std">
<p>
A non-type <var>template-parameter</var>
shall not be declared to have
floating point, class, <ins>array of runtime bound</ins>, or <code>void</code>
type.
[<i>Example:</i> ... ]
</p>
</blockquote>


<h3><a name="temp.param">15.1 Throwing an exception [except.throw]</a></h3>

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

<blockquote class="std">
<p>
...
[<i>Note:</i>
An exception can be thrown from one of the following contexts:
<var>throw-expression</var> (see below),
allocation functions (3.7.4.1 basic.stc.dynamic.allocation),
dynamic_cast (5.2.7 expr.dynamic.cast),
typeid (5.2.8 expr.typeid),
new-expression (5.3.4 expr.new),
<ins>array of runtime bound (8.3.4 dcl.array),</ins> and
standard library functions (17.5.1.4 structure.specifications).
&mdash;<i>end note</i>]
...
</p>
</blockquote>


<h3><a name="bad.array.length">18.6.2.new Class <code>bad_array_length</code> [bad.array.length]</a></h3>

<p>
Add a new section just before 18.6.2.2 new.badlength as follows.
</p>

<blockquote class="stdins">
<pre><code>
namespace std {
  class bad_array_length : public bad_alloc {
    public:
      bad_array_length() noexcept;
  };
}
</code></pre>

<p>
The class <code>bad_array_length</code>
defines the type of objects thrown as exceptions by the implementation
to report an attempt to allocate an array of runtime bound
with a size less than or equal to zero
or greater than an implementation-defined limit (8.3.4 dcl.array).
</p>

<pre>
bad_array_length() noexcept;
</pre>

<blockquote>
<p>
<i>Effects:</i>
constructs an object of class <code>bad_array_length</code>.
</p>

<p>
<i>Remarks:</i>
the result of calling <code>what()</code> on the newly constructed object
is implementation-defined.
</p>
</blockquote>
</blockquote>


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

<p>
Add <code>&lt;dynarray&gt;</code> to table 87:
</p>

<blockquote class="std">
<table>
<caption>Table 87: 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>
<ins>&lt;dynarray&gt;</ins><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>&lt;queue&gt;<br>
&lt;stack&gt;</td></tr>
</tbody>
</table>
</blockquote>


<h3><a name="sequence.reqmts">23.2.3 Sequence containers [sequence.reqmts]</a></h3>

<p>
In table 101, Optional sequence container operations,
add <code>dynarray</code> to the list of containers
for operations
<code>front</code>,
<code>back</code>,
<code>a[n]</code>, and
<code>at(n)</code>.
</p>


<h3><a name="sequences">23.3.1 In general [sequences.general]</a></h3>

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

<blockquote class="stdins">
<p>
The headers <code>&lt;array&gt;</code>, <code>&lt;deque&gt;</code>,
<ins><code>&lt;dynarray&gt;</code>,</ins> <code>&lt;forward_list&gt;</code>,
<code>&lt;list&gt;</code>, and <code>&lt;vector&gt;</code>
define template classes that meet the requirements for sequence containers.
</p>
</blockquote>

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

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

<pre><code>

#include &lt;initializer_list&gt;

namespace std {

template&lt; class T &gt;
class dynarray;

template &lt;class Type, class Alloc>
struct uses_allocator&lt;dynarray&lt;Type&gt;, Alloc&gt;;

template &lt;class T, class Allocator&gt;
  bool operator==(const dynarray&lt;T&gt;&amp; x, const dynarray&lt;T&gt;&amp; y);
template &lt;class T, class Allocator&gt;
  bool operator&lt; (const dynarray&lt;T&gt;&amp; x, const dynarray&lt;T&gt;&amp; y);
template &lt;class T, class Allocator&gt;
  bool operator!=(const dynarray&lt;T&gt;&amp; x, const dynarray&lt;T&gt;&amp; y);
template &lt;class T, class Allocator&gt;
  bool operator&gt; (const dynarray&lt;T&gt;&amp; x, const dynarray&lt;T&gt;&amp; y);
template &lt;class T, class Allocator&gt;
  bool operator&gt;=(const dynarray&lt;T&gt;&amp; x, const dynarray&lt;T&gt;&amp; y);
template &lt;class T, class Allocator&gt;
  bool operator&lt;=(const dynarray&lt;T&gt;&amp; x, const dynarray&lt;T&gt;&amp; y);

} // namespace std
</code></pre>
</blockquote>


<h3><a name="dynarray">23.3.4 Class template <code>dynarray</code> [dynarray]</a></h3>

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


<h3><a name="dynarray.overview">23.3.4.1 Class template <code>dynarray</code> overview [dynarray.overview]</a></h3>

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

<blockquote class="stdins">

<p>
The header <code>&lt;dynarray&gt;</code>
defines a class template for storing sequences of objects
where the size is fixed at construction.
A <code>dynarray</code> supports random access iterators.
An instance of <code>dynarray&lt;T&gt;</code>
stores elements of type <code>T</code>.
The elements of a <code>dynarray</code> are stored contiguously,
meaning that if <code>d</code> is an <code>dynarray&lt;T&gt;</code>
then it obeys the identity
<code>&amp;d[n] == &amp;d[0] + n</code>
for all <code>0 &lt;= n &lt; d.size()</code>.
</p>

<p>
Unless otherwise specified,
all dynarray operations have the same requirements and semantics
as specified in 23.2.
</p>

<p>
All operations except construction, destruction, and <code>fill</code>
shall have constant-time complexity.
</p>

<pre><code>
namespace std {
  template &lt;class T&gt;
  class dynarray
  {
    // types:
    typedef       T                          value_type;
    typedef       T&amp;                         reference;
    typedef const T&amp;                         const_reference;
    typedef       T*                         pointer;
    typedef const T*                         const_pointer;
    typedef <var>implementation-defined</var> iterator;       // See [container.requirements]
    typedef <var>implementation-defined</var> const_iterator; // See [container.requirements]
    typedef reverse_iterator&lt;iterator&gt;       reverse_iterator;
    typedef reverse_iterator&lt;const_iterator&gt; const_reverse_iterator;
    typedef size_t                           size_type;
    typedef ptrdiff_t                        difference_type;

public:
    // [dynarray.cons] construct/copy/destroy:
    explicit dynarray(size_type <var>c</var>);
    template&lt; typename Alloc &gt;
      dynarray(size_type <var>c</var>, const Alloc&amp; alloc);
    dynarray(size_type <var>c</var>, const T&amp; <var>v</var>);
    template&lt; typename Alloc &gt;
      dynarray(size_type <var>c</var>, const T&amp; <var>v</var>, const Alloc&amp; alloc);
    dynarray(const dynarray&amp; <var>d</var>);
    template&lt; typename Alloc &gt;
      dynarray(const dynarray&amp; <var>d</var>, const Alloc&amp; alloc);
    dynarray(initializer_list&lt;T&gt;);
    template&lt; typename Alloc &gt;
      dynarray(initializer_list&lt;T&gt;, const Alloc&amp; alloc);
    ~dynarray();

    dynarray&amp; operator=(const dynarray&amp;) = delete;

    // iterators:
    iterator       begin()        noexcept;
    const_iterator begin()  const noexcept;
    const_iterator cbegin() const noexcept;
    iterator       end()          noexcept;
    const_iterator end()    const noexcept;
    const_iterator cend()   const noexcept;

    reverse_iterator       rbegin()        noexcept;
    const_reverse_iterator rbegin()  const noexcept;
    const_reverse_iterator crbegin() const noexcept;
    reverse_iterator       rend()          noexcept;
    const_reverse_iterator rend()    const noexcept;
    const_reverse_iterator crend()   const noexcept;

    // capacity:
    size_type size()     const noexcept;
    size_type max_size() const noexcept;
    bool      empty()    const noexcept;

    // element access:
    reference       operator[](size_type <var>n</var>);
    const_reference operator[](size_type <var>n</var>) const;

    reference       front();
    const_reference front() const;
    reference       back();
    const_reference back()  const;

    reference       at(size_type <var>n</var>);
    const_reference at(size_type <var>n</var>) const;

    // [dynarray.data] data access:
    T*       data()       noexcept;
    const T* data() const noexcept;

    // [dynarray.mutate] mutating member functions:
    void fill(const T&amp; <var>v</var>);
  };

} // namespace std
</code></pre>

</blockquote>


<h3><a name="dynarray.cons">23.3.4.2 <code>dynarray</code> constructor and destructor [dynarray.cons]</a></h3>

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

<blockquote class="stdins">

<p>
<code>explicit dynarray(size_type <var>c</var>);</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
Allocates storage for <var>c</var> elements.
May or may not invoke the global <code>operator new</code>.
The <tt>c</tt> elements of the <code>dynarray</code>
are default-initialized (8.5).
</p>

<p>
<i>Throws:</i>
<code>std::bad_array_length</code>
when the size requested is larger than implementable.
<code>std::bad_alloc</code>
when there is insufficient memory.
</p>

</blockquote>
<p>
<code>dynarray(size_type <var>c</var>, const T& <var>v</var>);</code>
</p>

<blockquote>

<p>
<i>Requires:</i>
<code>T</code> shall meet the <code>CopyConstructible</code> requirements.
</p>

<p>
<i>Effects:</i>
Allocates storage for <code>c</code> elements.
May or may not invoke the global <code>operator new</code>.
The <code>c</code> elements of the <code>dynarray</code>
are direct-initialized ([decl.init]) with argument <code>v</code>.
</p>

<p>
<i>Throws:</i>
<code>std::bad_array_length</code>
when the size requested is larger than implementable.
<code>std::bad_alloc</code>
when there is insufficient memory.
</p>
</blockquote>

<p>
<code>dynarray(const dynarray&amp; <var>d</var>);</code>
</p>

<blockquote>

<p>
<i>Requires:</i>
<code>T</code> shall meet the <code>CopyConstructible</code> requirements.
</p>

<blockquote>
<p>
<i>Effects:</i>
Allocates storage for <code>d.size()</code> elements.
The <code>d.size()</code> elements of the <code>dynarray</code>
are direct-initialized ([dcl.init])
with the corresponding elements of <code>d</code>.
May or may not invoke the global <code>operator new</code>.
</p>
</blockquote>

<p>
<i>Throws:</i>
<code>std::bad_alloc</code>
when there is insufficient memory.
</p>
</blockquote>


<pre>
<code>template &lt;class Alloc &gt;
  dynarray(size_type <var>c</var>, const Alloc&amp; alloc);
template &lt;class Alloc &gt;
  dynarray(size_type <var>c</var>, const T&amp; <var>v</var>, const Alloc&amp; alloc);
template &lt;class Alloc &gt;
  dynarray(const dynarray&amp; <var>d</var>, const Alloc&amp; alloc);</code>
template &lt;class Alloc &gt;
  dynarray(initializer_list&lt;T&gt;, const Alloc&amp; alloc);
</pre>

<blockquote>
<p>
<i>Requires:</i>
<code>Alloc</code>
shall meet the requirements for an Allocator ([allocator.requirements]).
</p>

<p>
<i>Effects:</i>
Equivalent to the preceding constructors
except that each element is constructed
with uses-allocator construction ([allocator.uses.construction]).
</p>
</blockquote>

<p>
<code>~dynarray();</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
Invokes the global <code>operator delete</code>
if and only if
the constructor invoked the global <code>operator new</code>.
</p>
</blockquote>

</blockquote>


<h3><a name="dynarray.data">23.3.4.3 <code>dynarray::data</code> [dynarray.data]</a></h3>

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

<blockquote class="stdins">

<p>
<code>T* data() noexcept;</code><br>
<code>const T* data() const noexcept;</code>
</p>

<blockquote>
<p>
<i>Returns:</i>
A pointer to the contiguous storage containing the elements.
</p>
</blockquote>

</blockquote>


<h3><a name="dynarray.mutate">23.3.4.4 Mutating operations [dynarray.mutate]</a></h3>

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

<blockquote class="stdins">

<p>
<code>void fill(const T&amp; <var>v</var>);</code>
</p>

<blockquote>
<p>
<i>Effects:</i>
<code>fill_n(begin(), size(), <var>v</var>);</code>
</p>
</blockquote>

</blockquote>


<h3><a name="dynarray.zero">23.3.4.5 Zero sized dynarrays [dynarray.zero]</a></h3>

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

<blockquote class="stdins">
<p>
<code>dynarray</code> shall provide support
for the special case of construction with a size of zero.
In the case that the size is zero,
<code>begin() == end() ==</code> unique value.
The return value of <code>data()</code> is unspecified.
The effect of calling <code>front()</code> or <code>back()</code>
for a zero-sized <code>dynarray</code> is undefined.
</p>
</blockquote>


<h3><a name="dynarray.traits">23.3.4.6 Traits [dynarray.traits]</a></h3>

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

<blockquote class="stdins">
<dl>
<dt>
<code>template &lt;class Type, class Alloc>
<br>
&nbsp;&nbsp;struct uses_allocator&lt;dynarray&lt;Type&gt;, Alloc&gt; : true_type { };</code>
</dt>
<dd>
<p>
<b>Requires:</b>
<code>Alloc</code> shall be an Allocator ([allocator.requirements]).
[<i>Note:</i>
Specialization of this trait informs other library components that
dynarray can be constructed with an allocator,
even though it does not have a nested <code>allocator_type</code>.
&mdash;<i>end note</i>]
</p>
</dd>
</dl>
</blockquote>


<h2><a name="Revision">Revision History</a></h2>

<p>
<em>
This section will be removed before final publication.
</em>
</p>

<dl>
<dt>N3820</dt>
<dd>

<ul>

<li>
<p>
The initial revision
originates with the papers
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3639.html">
N3639 Runtime-sized arrays with automatic storage duration (revision 5)</a>
and
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3662.html">
N3662 C++ Dynamic Arrays</a>.
</p>
</li>

<li>
<p>
The initial revision
derives from the following commits
to the source of standard managed at
<a href="https://github.com/cplusplus/draft/">
https://github.com/cplusplus/draft/</a>.
</p>

<dl>

<dt>Arrays with Runtime Bound</dt>
<dd>
<p>
<a href="https://github.com/cplusplus/draft/commit/010f14c77212bcb5dfed3c4b9a55f0ddc24c51c0">
commit/010f14c77212bcb5dfed3c4b9a55f0ddc24c51c0</a>
</p>
</dd>

<dt>Dynarray</dt>
<dd>
<p>
<a href="https://github.com/cplusplus/draft/commit/d2c727eba9f8b64be697e6d8cc6b75fb7d43193a">
commit/d2c727eba9f8b64be697e6d8cc6b75fb7d43193a</a>
<a href="https://github.com/cplusplus/draft/commit/cec76a769f35cc348805f254c22cc3d83d7eac12">
commit/cec76a769f35cc348805f254c22cc3d83d7eac12</a>
<a href="https://github.com/cplusplus/draft/commit/bb583f2005070c700c8b4405f5030e4307b5771a">
commit/bb583f2005070c700c8b4405f5030e4307b5771a</a>
<a href="https://github.com/cplusplus/draft/commit/c8054d9d8ca074ee7b125eb55fdc6774a22e3e83">
commit/c8054d9d8ca074ee7b125eb55fdc6774a22e3e83</a>
</p>
</dd>

</dl>

</ul>

</dd>
</dl>

</body>
</html>
