[cfe-dev] RFC on N3526 implementation
Michael Price
michael.b.price.dev at gmail.com
Fri Mar 29 07:55:16 PDT 2013
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 '-fproposal-n3526'.
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).
#include <cstddef>
using namespace std;
namespace n3526 {
namespace Example4 {
// A pared-down array implementation
template <class T, size_t N, size_t ... Rest>
struct array
{
typedef array<T, Rest...> elem_type;
elem_type __elems_[N];
};
template <class T, size_t N>
struct array<T, N>
{
typedef T elem_type;
elem_type __elems_[N];
};
}
namespace Example5 {
// A slightly better, pared-down array implementation
template <class T, size_t N, size_t ... Rest>
struct array
{
typedef typename array<T, Rest...>::value_type value_type[N];
value_type __elems_;
};
template <class T, size_t N>
struct array<T, N>
{
typedef T value_type[N];
value_type __elems_;
};
}
}
int main (int argc, char ** argv)
{
// Example 1
{
int aggr_array[2] = {1, 2};
struct aggr_t {
int a;
int b;
} instance = {3, 4};
}
// Example 2
{
int aggr_array[2][2] = {{1, 2}, {3, 4}};
struct aggr_t {
struct {
int a;
int b;
} x, y;
} instance = {{1, 2}, {3, 4}};
}
// Example 3
// 'bad' will fail unless -fproposal-n3526 is provided
{
struct aggr_t {
int a;
int b;
} array_of_aggr[2] = {{1, 2}, {3, 4}};
struct aggr_ex_t {
int x[2][2];
};
aggr_ex_t bad = {{1, 2}, {3, 4}}; // Error: Too many
initializers, see below for details
aggr_ex_t good = {{{1, 2}, {3, 4}}};
}
// Example 4
{
// Using this (n3526::Example4::array) multidimensional array
using namespace n3526::Example4;
// 1-dimension, everything works as expected
int _a[2] = {0, 0};
array<int, 2> a = {0, 0};
// 2-dimensions, extra braces are needed
int _b[2][2] = {{1, 1}, {2, 2}};
array<int, 2, 2> b = {{{1, 1}, {2, 2}}};
// 3-dimensions, this begins to get out-of-hand
int _c[2][2][2] = {{{3, 3}, {4, 4}}, {{5, 5}, {6, 6}}};
array<int, 2, 2, 2> c = {{{{{3, 3}, {4, 4}}}, {{{5, 5}, {6, 6}}}}};
}
// Example 5
{
// Using this (n3526::Example5::array) multidimensional array
using namespace n3526::Example5;
// 1-dimension, everything works as expected
int _a[2] = {0, 0};
array<int, 2> a = {0, 0};
// 2-dimensions, extra braces are needed
int _b[2][2] = {{1, 1}, {2, 2}};
array<int, 2, 2> b = {{{1, 1}, {2, 2}}};
// 3-dimensions, this begins to get out-of-hand
int _c[2][2][2] = {{{3, 3}, {4, 4}}, {{5, 5}, {6, 6}}};
array<int, 2, 2, 2> c = {{{{3, 3}, {4, 4}}, {{5, 5}, {6, 6}}}};
}
// Example 6
// 'good' should only succeed with -fproposal-n3526
// 'still-bad' should fail in any situation
{
struct aggr_ex_t {
int x[2][2];
};
aggr_ex_t fully_braced = {{{1, 2}, {3, 4}}};
aggr_ex_t good = {{1, 2}, {3, 4}}; // Behaves as if the
// initializer list had
// been {{{1, 2}, {3, 4}}}
// Would still be an error per paragraphs 8.5.1.6 and 8.5.1.11
since the
// initializer-list would be equivalent to {{{1, 2}, {3, 4}, {5,
6}}}
// and would have too many initialization-clauses.
aggr_ex_t still_bad = {{1, 2}, {3, 4}, {5, 6}};
}
// Example 7
// 'good' and 'also_good' should only succeed with -fproposal-n3526
{
struct aggr_ex_t {
int x[2][2];
};
struct aggr_more_t {
aggr_ex_t _a;
};
aggr_more_t fully_braced = {{{{1, 2}, {3, 4}}}};
aggr_more_t good = {{{1, 2}, {3, 4}}}; // Both behave as if the
aggr_more_t also_good = {{1, 2}, {3, 4}}; // initializer lists had
// been {{{{1, 2}, {3,
4}}}}
}
// Example 8 (appears in standards text)
// 'a2' and 'a3' should only succeed with -fproposal-n3526
{
struct S {
int x[2][2];
};
struct A {
S s;
};
A a1 = {{{{1, 2}, {3, 4}}}};
A a2 = {{{1, 2}, {3, 4}}};
A a3 = {{1, 2}, {3, 4}};
A a4 = {1, 2, 3, 4};
}
//////////////////// Tests not appearing in the proposal
//////////////////////
// constexpr tests
// 'a2' and 'a3' should only succeed with -fproposal-n3526
{
struct S {
int x[2][2];
};
struct A {
S s;
};
constexpr A a1 = {{{{1, 2}, {3, 4}}}};
constexpr A a2 = {{{1, 2}, {3, 4}}};
constexpr A a3 = {{1, 2}, {3, 4}};
constexpr A a4 = {1, 2, 3, 4};
}
// non-builtin type tests (no initializer-list ctor)
// 'a2' and 'a3' should only succeed with -fproposal-n3526
{
struct Type {
Type(int, const char*, bool) { /* ... */ }
};
struct S {
Type x[2][2];
};
struct A {
S s;
};
// TODO: These initializer_lists didn't seem to automatically call the
matching constructor for 'Type', so I had to be explicit
A a1 = {{{{Type{1, "One", true}, Type{2, "Two", false}}, {Type{3,
"Three", true}, Type{4, "Four", false}}}}};
A a2 = {{{Type{1, "One", true}, Type{2, "Two", false}}, {Type{3,
"Three", true}, Type{4, "Four", false}}}};
A a3 = {{Type{1, "One", true}, Type{2, "Two", false}}, {Type{3,
"Three", true}, Type{4, "Four", false}}};
A a4 = {Type{1, "One", true}, Type{2, "Two", false}, Type{3,
"Three", true}, Type{4, "Four", false}};
}
return 0;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130329/fff24b49/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: n3526.diff
Type: application/octet-stream
Size: 4724 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130329/fff24b49/attachment.obj>
More information about the cfe-dev
mailing list