diff --git a/Doc/Manual/Cpp0x.html b/Doc/Manual/Cpp0x.html index aa8c41225..341cb3ce5 100644 --- a/Doc/Manual/Cpp0x.html +++ b/Doc/Manual/Cpp0x.html @@ -126,13 +126,14 @@ public:

7.2.4 Initializer lists

-

Constructors using the std::initializer_list class are removed -from the wrapped class, because the only way to access such a -constructor is at compile time using the "= {}" assignment.

-

Users should add another constructor with specific arguments -filling the class members manually.

+

+Constructors using the std::initializer_list class are removed +from the wrapped class because the only way to access such a +constructor is at compile time using the initialization list syntax. +Initializer lists are very much a C++ construct and not very accessible from wrappers. +

-

For now, if a user wants to fill the class components like this:

+

For now, if you want to fill the class components like this:

 class A {
@@ -142,7 +143,7 @@ public:
 A a1 = {1,2,3,4};
 
-

You should add another constructor using the std::vector for example:

+

you could add another constructor using std::vector for example:

 class A {
@@ -153,11 +154,26 @@ public:
 A a1 = {1,2,3,4};
 
-

And call it from your target language, for example, in Python:

+

And then construct it from your target language, for example, in Python:

 >>> a2 = A( [1,2,3,4] )
 
+

+std::initializer_list is simply a container that can only be initialised at compile time. +As such it is possible to write typemaps for a target language container to map onto +std::initializer_list. However, this can only be done for a fixed number of elements ... +there is no way to construct an initializer list with a variable number of arguments at runtime. +This is not particularly flexible though outside of C++ static initialization, +hence the need to provide an alternative for use from a target language. +

+ +

+Initializer lists can appear in any function or method, not just constructors. +SWIG only ignores the constructors as this is where they commonly occur. +Users are recommended to manually ignore any other methods using an initialization list with %ignore. +

+

7.2.5 Uniform initialization

diff --git a/Examples/test-suite/cpp0x_initializer_list.i b/Examples/test-suite/cpp0x_initializer_list.i index aa2791833..9d85766e2 100644 --- a/Examples/test-suite/cpp0x_initializer_list.i +++ b/Examples/test-suite/cpp0x_initializer_list.i @@ -1,7 +1,7 @@ /* This testcase checks whether SWIG correctly uses the new initializer_list introduced in C++0x. */ %module cpp0x_initializer_list -%warnfilter(520) A; +%warnfilter(SWIGWARN_LANG_INITIALIZER_LIST) A; %inline %{ #include @@ -10,6 +10,13 @@ class A { public: A( std::initializer_list ) {} A() {} + A(double d) {} +}; +class B { +public: + B( std::initializer_list, std::initializer_list ) {} + B() {} + void method(std::initializer_list init) {} }; %} diff --git a/Examples/test-suite/cpp0x_uniform_initialization.i b/Examples/test-suite/cpp0x_uniform_initialization.i index 083fac377..81a3e45de 100644 --- a/Examples/test-suite/cpp0x_uniform_initialization.i +++ b/Examples/test-suite/cpp0x_uniform_initialization.i @@ -1,7 +1,11 @@ -/* This testcase checks whether SWIG syntactically correctly parses the curly - brackets {} for uniform member initialization. */ +/* This testcase checks whether SWIG syntactically correctly parses the initialization syntax using + {} braces for uniform member initialization. */ %module cpp0x_uniform_initialization +%include + +%template(VectorInt) std::vector; + %inline %{ struct BasicStruct { int x; @@ -10,6 +14,8 @@ struct BasicStruct { struct AltStruct { AltStruct(int x, double y) : x_{x}, y_{y} {} + int getX() { return x_; } + double getY() { return y_; } private: int x_; @@ -19,4 +25,25 @@ private: BasicStruct var1{5, 3.2}; // only fills the struct components AltStruct var2{2, 4.3}; // calls the constructor +class MoreInit +{ +public: + int yarray[5] {1,2,3,4,5}; + char *charptr {nullptr}; + std::vector vi {1,2,3,4,5}; + + MoreInit() {} + + int more1(std::vector vv = {1,2,3,4}) { + int sum = 0; + for (int i : vv) + sum += i; + return sum; + } +}; +const int arr1[] = {1,2,3}; +const int arr2[]{1,2,3}; +const int arr3[][3]{ {1,2,3}, {4,5,6} }; +const int arr4[][3] = { {1,2,3}, {4,5,6} }; %} + diff --git a/Examples/test-suite/python/cpp0x_initializer_list_runme.py b/Examples/test-suite/python/cpp0x_initializer_list_runme.py new file mode 100644 index 000000000..5c8c153a5 --- /dev/null +++ b/Examples/test-suite/python/cpp0x_initializer_list_runme.py @@ -0,0 +1,5 @@ +import cpp0x_initializer_list + +a = cpp0x_initializer_list.A() +a = cpp0x_initializer_list.A(11.1) + diff --git a/Examples/test-suite/python/cpp0x_uniform_initialization_runme.py b/Examples/test-suite/python/cpp0x_uniform_initialization_runme.py new file mode 100644 index 000000000..42228f3d7 --- /dev/null +++ b/Examples/test-suite/python/cpp0x_uniform_initialization_runme.py @@ -0,0 +1,21 @@ +import cpp0x_uniform_initialization + +var1 = cpp0x_uniform_initialization.cvar.var1 +if var1.x != 5: + raise RuntimeError +var2 = cpp0x_uniform_initialization.cvar.var2 +if var2.getX() != 2: + raise RuntimeError + +m = cpp0x_uniform_initialization.MoreInit() +if m.charptr != None: + raise RuntimeError, m.charptr +m.charptr = "hello sir" +if m.charptr != "hello sir": + raise RuntimeError, m.charptr +if m.more1(m.vi) != 15: + raise RuntimeError, m.vi +if m.more1( [-1,1,2] ) != 2: + raise RuntimeError, m.vi +if m.more1() != 10: + raise RuntimeError diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index f5b5f6e2b..b3eb72493 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -5165,7 +5165,7 @@ def_args : EQUAL definetype { } | EQUAL LBRACE { skip_balanced('{','}'); - $$.val = 0; + $$.val = NewString(scanner_ccode); $$.rawval = 0; $$.type = T_INT; $$.bitfield = 0; @@ -6625,7 +6625,10 @@ mem_initializer_list : mem_initializer | mem_initializer_list COMMA mem_initializer PERIOD PERIOD PERIOD ; -mem_initializer : idcolon LPAREN { skip_balanced('(',')'); Clear(scanner_ccode); } +mem_initializer : idcolon LPAREN { + skip_balanced('(',')'); + Clear(scanner_ccode); + } /* Uniform initialization in C++0x. Example: struct MyStruct { @@ -6634,7 +6637,10 @@ mem_initializer : idcolon LPAREN { skip_balanced('(',')'); Clear(scanner_ccode); double y_; }; */ - | idcolon LBRACE { skip_balanced('{','}'); Clear(scanner_ccode); } + | idcolon LBRACE { + skip_balanced('{','}'); + Clear(scanner_ccode); + } ; template_decl : LESSTHAN valparms GREATERTHAN {