<div dir="ltr">I've attached the diff (generated by git). It currently does not contain updated tests, as I was unable to get the lit framework to work properly for me. I've pasted a sample program below. You can enable the proposed syntax changes with '<font face="courier new, monospace">-fproposal-n3526</font>'.<div>
<br></div><div>I'm specifically looking for comments on whether there are any corner cases that I may have missed, or if there are other types of tests that should eventually be included. I am not looking to have this code committed yet (at least not to the clang trunk), thus why I didn't send it to cfe-commits. I'm also curious if there is a procedure in place for adopting experimental implementations of proposals, particularly as it applies to enabling/disabling those implementations (I'm not sure I did it "correctly" here).<br>
<div><br></div><div><div style><font face="courier new, monospace">#include <cstddef></font></div><div style><font face="courier new, monospace"><br></font></div><div style><font face="courier new, monospace">using namespace std;</font></div>
<div style><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">namespace n3526 {<br></font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> namespace Example4 {</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> // A pared-down array implementation</font></div><div><font face="courier new, monospace"> template <class T, size_t N, size_t ... Rest></font></div>
<div><font face="courier new, monospace"> struct array</font></div><div><font face="courier new, monospace"> {</font></div><div><font face="courier new, monospace"> typedef array<T, Rest...> elem_type;</font></div>
<div><font face="courier new, monospace"> elem_type __elems_[N];</font></div><div><font face="courier new, monospace"> };</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> template <class T, size_t N></font></div>
<div><font face="courier new, monospace"> struct array<T, N></font></div><div><font face="courier new, monospace"> {</font></div><div><font face="courier new, monospace"> typedef T elem_type;</font></div>
<div><font face="courier new, monospace"> elem_type __elems_[N];</font></div><div><font face="courier new, monospace"> }; </font></div><div><font face="courier new, monospace"> }</font></div><div>
<font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> namespace Example5 {</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> // A slightly better, pared-down array implementation</font></div>
<div><font face="courier new, monospace"> template <class T, size_t N, size_t ... Rest></font></div><div><font face="courier new, monospace"> struct array</font></div><div><font face="courier new, monospace"> {</font></div>
<div><font face="courier new, monospace"> typedef typename array<T, Rest...>::value_type value_type[N];</font></div><div><font face="courier new, monospace"> value_type __elems_;</font></div><div>
<font face="courier new, monospace"> };</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> template <class T, size_t N></font></div><div><font face="courier new, monospace"> struct array<T, N></font></div>
<div><font face="courier new, monospace"> {</font></div><div><font face="courier new, monospace"> typedef T value_type[N];</font></div><div><font face="courier new, monospace"> value_type __elems_;</font></div>
<div><font face="courier new, monospace"> };</font></div><div><font face="courier new, monospace"> }</font></div><div><font face="courier new, monospace">}</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace">int main (int argc, char ** argv)</font></div><div><font face="courier new, monospace">{</font></div><div><font face="courier new, monospace"> // Example 1</font></div>
<div><font face="courier new, monospace"> {</font></div><div><font face="courier new, monospace"> int aggr_array[2] = {1, 2};</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> struct aggr_t {</font></div>
<div><font face="courier new, monospace"> int a;</font></div><div><font face="courier new, monospace"> int b;</font></div><div><font face="courier new, monospace"> } instance = {3, 4};</font></div>
<div><font face="courier new, monospace"> }</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> // Example 2</font></div><div><font face="courier new, monospace"> {</font></div>
<div><font face="courier new, monospace"> int aggr_array[2][2] = {{1, 2}, {3, 4}};</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> struct aggr_t {</font></div>
<div><font face="courier new, monospace"> struct {</font></div><div><font face="courier new, monospace"> int a;</font></div><div><font face="courier new, monospace"> int b;</font></div>
<div><font face="courier new, monospace"> } x, y;</font></div><div><font face="courier new, monospace"> } instance = {{1, 2}, {3, 4}};</font></div><div><font face="courier new, monospace"> }</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> // Example 3</font></div><div><font face="courier new, monospace"> // 'bad' will fail unless -fproposal-n3526 is provided</font></div>
<div><font face="courier new, monospace"> {</font></div><div><font face="courier new, monospace"> struct aggr_t {</font></div><div><font face="courier new, monospace"> int a;</font></div><div><font face="courier new, monospace"> int b;</font></div>
<div><font face="courier new, monospace"> } array_of_aggr[2] = {{1, 2}, {3, 4}};</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> struct aggr_ex_t {</font></div>
<div><font face="courier new, monospace"> int x[2][2];</font></div><div><font face="courier new, monospace"> };</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> aggr_ex_t bad = {{1, 2}, {3, 4}}; // Error: Too many initializers, see below for details</font></div>
<div><font face="courier new, monospace"> aggr_ex_t good = {{{1, 2}, {3, 4}}}; </font></div><div><font face="courier new, monospace"> }</font></div><div><font face="courier new, monospace"><br></font></div>
<div><font face="courier new, monospace"> // Example 4</font></div><div><font face="courier new, monospace"> {</font></div><div><font face="courier new, monospace"> // Using this (n3526::Example4::array) multidimensional array</font></div>
<div><font face="courier new, monospace"> using namespace n3526::Example4;</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> // 1-dimension, everything works as expected</font></div>
<div><font face="courier new, monospace"> int _a[2] = {0, 0};</font></div><div><font face="courier new, monospace"> array<int, 2> a = {0, 0};</font></div><div><font face="courier new, monospace"><br></font></div>
<div><font face="courier new, monospace"> // 2-dimensions, extra braces are needed</font></div><div><font face="courier new, monospace"> int _b[2][2] = {{1, 1}, {2, 2}};</font></div><div><font face="courier new, monospace"> array<int, 2, 2> b = {{{1, 1}, {2, 2}}};</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> // 3-dimensions, this begins to get out-of-hand</font></div><div><font face="courier new, monospace"> int _c[2][2][2] = {{{3, 3}, {4, 4}}, {{5, 5}, {6, 6}}};</font></div>
<div><font face="courier new, monospace"> array<int, 2, 2, 2> c = {{{{{3, 3}, {4, 4}}}, {{{5, 5}, {6, 6}}}}};</font></div><div><font face="courier new, monospace"> }</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace"> // Example 5</font></div><div><font face="courier new, monospace"> {</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> // Using this (n3526::Example5::array) multidimensional array</font></div>
<div><font face="courier new, monospace"> using namespace n3526::Example5;</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> // 1-dimension, everything works as expected</font></div>
<div><font face="courier new, monospace"> int _a[2] = {0, 0};</font></div><div><font face="courier new, monospace"> array<int, 2> a = {0, 0};</font></div><div><font face="courier new, monospace"><br></font></div>
<div><font face="courier new, monospace"> // 2-dimensions, extra braces are needed</font></div><div><font face="courier new, monospace"> int _b[2][2] = {{1, 1}, {2, 2}};</font></div><div><font face="courier new, monospace"> array<int, 2, 2> b = {{{1, 1}, {2, 2}}};</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> // 3-dimensions, this begins to get out-of-hand</font></div><div><font face="courier new, monospace"> int _c[2][2][2] = {{{3, 3}, {4, 4}}, {{5, 5}, {6, 6}}};</font></div>
<div><font face="courier new, monospace"> array<int, 2, 2, 2> c = {{{{3, 3}, {4, 4}}, {{5, 5}, {6, 6}}}}; </font></div><div><font face="courier new, monospace"> }</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace"> // Example 6</font></div><div><font face="courier new, monospace"> // 'good' should only succeed with -fproposal-n3526</font></div><div><font face="courier new, monospace"> // 'still-bad' should fail in any situation</font></div>
<div><font face="courier new, monospace"> {</font></div><div><font face="courier new, monospace"> struct aggr_ex_t {</font></div><div><font face="courier new, monospace"> int x[2][2];</font></div><div>
<font face="courier new, monospace"> };</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> aggr_ex_t fully_braced = {{{1, 2}, {3, 4}}};</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> aggr_ex_t good = {{1, 2}, {3, 4}}; // Behaves as if the</font></div><div><font face="courier new, monospace"> // initializer list had</font></div>
<div><font face="courier new, monospace"> // been {{{1, 2}, {3, 4}}}</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> // Would still be an error per paragraphs 8.5.1.6 and 8.5.1.11 since the</font></div>
<div><font face="courier new, monospace"> // initializer-list would be equivalent to {{{1, 2}, {3, 4}, {5, 6}}}</font></div><div><font face="courier new, monospace"> // and would have too many initialization-clauses.</font></div>
<div><font face="courier new, monospace"> aggr_ex_t still_bad = {{1, 2}, {3, 4}, {5, 6}}; </font></div><div><font face="courier new, monospace"> }</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace"> // Example 7</font></div><div><font face="courier new, monospace"> // 'good' and 'also_good' should only succeed with -fproposal-n3526</font></div>
<div><font face="courier new, monospace"> {</font></div><div><font face="courier new, monospace"> struct aggr_ex_t {</font></div><div><font face="courier new, monospace"> int x[2][2];</font></div><div>
<font face="courier new, monospace"> };</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> struct aggr_more_t {</font></div><div><font face="courier new, monospace"> aggr_ex_t _a;</font></div>
<div><font face="courier new, monospace"> };</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> aggr_more_t fully_braced = {{{{1, 2}, {3, 4}}}};</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> aggr_more_t good = {{{1, 2}, {3, 4}}}; // Both behave as if the</font></div><div><font face="courier new, monospace"> aggr_more_t also_good = {{1, 2}, {3, 4}}; // initializer lists had</font></div>
<div><font face="courier new, monospace"> // been {{{{1, 2}, {3, 4}}}} </font></div><div><font face="courier new, monospace"> }</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace"> // Example 8 (appears in standards text)</font></div><div><font face="courier new, monospace"> // 'a2' and 'a3' should only succeed with -fproposal-n3526</font></div>
<div><font face="courier new, monospace"> {</font></div><div><font face="courier new, monospace"> struct S {</font></div><div><font face="courier new, monospace"> int x[2][2];</font></div><div><font face="courier new, monospace"> };</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> struct A {</font></div><div><font face="courier new, monospace"> S s;</font></div><div><font face="courier new, monospace"> };</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> A a1 = {{{{1, 2}, {3, 4}}}};</font></div><div><font face="courier new, monospace"> A a2 = {{{1, 2}, {3, 4}}};</font></div>
<div><font face="courier new, monospace"> A a3 = {{1, 2}, {3, 4}};</font></div><div><font face="courier new, monospace"> A a4 = {1, 2, 3, 4}; </font></div><div><font face="courier new, monospace"> }</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">//////////////////// Tests not appearing in the proposal //////////////////////</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace"> // constexpr tests</font></div><div><font face="courier new, monospace"> // 'a2' and 'a3' should only succeed with -fproposal-n3526</font></div>
<div><font face="courier new, monospace"> {</font></div><div><font face="courier new, monospace"> struct S {</font></div><div><font face="courier new, monospace"> int x[2][2];</font></div><div><font face="courier new, monospace"> };</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> struct A {</font></div><div><font face="courier new, monospace"> S s;</font></div><div><font face="courier new, monospace"> };</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> constexpr A a1 = {{{{1, 2}, {3, 4}}}};</font></div><div><font face="courier new, monospace"> constexpr A a2 = {{{1, 2}, {3, 4}}};</font></div>
<div><font face="courier new, monospace"> constexpr A a3 = {{1, 2}, {3, 4}};</font></div><div><font face="courier new, monospace"> constexpr A a4 = {1, 2, 3, 4}; </font></div><div><font face="courier new, monospace"> }</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> // non-builtin type tests (no initializer-list ctor)</font></div><div><font face="courier new, monospace"> // 'a2' and 'a3' should only succeed with -fproposal-n3526</font></div>
<div><font face="courier new, monospace"> {</font></div><div><font face="courier new, monospace"> struct Type {</font></div><div><font face="courier new, monospace"> Type(int, const char*, bool) { /* ... */ }</font></div>
<div><font face="courier new, monospace"> };</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> struct S {</font></div><div><font face="courier new, monospace"> Type x[2][2];</font></div>
<div><font face="courier new, monospace"> };</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> struct A {</font></div><div><font face="courier new, monospace"> S s;</font></div>
<div><font face="courier new, monospace"> };</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">// TODO: These initializer_lists didn't seem to automatically call the matching constructor for 'Type', so I had to be explicit</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> A a1 = {{{{Type{1, "One", true}, Type{2, "Two", false}}, {Type{3, "Three", true}, Type{4, "Four", false}}}}};</font></div>
<div><font face="courier new, monospace"> A a2 = {{{Type{1, "One", true}, Type{2, "Two", false}}, {Type{3, "Three", true}, Type{4, "Four", false}}}};</font></div><div><font face="courier new, monospace"> A a3 = {{Type{1, "One", true}, Type{2, "Two", false}}, {Type{3, "Three", true}, Type{4, "Four", false}}};</font></div>
<div><font face="courier new, monospace"> A a4 = {Type{1, "One", true}, Type{2, "Two", false}, Type{3, "Three", true}, Type{4, "Four", false}}; </font></div><div><font face="courier new, monospace"> }</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> return 0;</font></div><div><font face="courier new, monospace">}</font></div>
</div><div><br></div></div></div>