diff options
-rw-r--r-- | Doc/Manual/Cpp0x.html | 32 | ||||
-rw-r--r-- | Examples/test-suite/cpp0x_initializer_list.i | 9 | ||||
-rw-r--r-- | Examples/test-suite/cpp0x_uniform_initialization.i | 31 | ||||
-rw-r--r-- | Examples/test-suite/python/cpp0x_initializer_list_runme.py | 5 | ||||
-rw-r--r-- | Examples/test-suite/python/cpp0x_uniform_initialization_runme.py | 21 | ||||
-rw-r--r-- | Source/CParse/parser.y | 12 |
6 files changed, 96 insertions, 14 deletions
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: <H3><a name="Cpp0x_Initializer_lists"></a>7.2.4 Initializer lists</H3> -<p>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.</p> -<p>Users should add another constructor with specific arguments -filling the class members manually.</p> +<p> +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. +</p> -<p>For now, if a user wants to fill the class components like this:</p> +<p>For now, if you want to fill the class components like this:</p> <div class="code"><pre> class A { @@ -142,7 +143,7 @@ public: A a1 = {1,2,3,4}; </pre></div> -<p>You should add another constructor using the std::vector for example:</p> +<p>you could add another constructor using <tt>std::vector</tt> for example:</p> <div class="code"><pre> class A { @@ -153,11 +154,26 @@ public: A a1 = {1,2,3,4}; </pre></div> -<p>And call it from your target language, for example, in Python:</p> +<p>And then construct it from your target language, for example, in Python:</p> <div class="targetlang"><pre> >>> a2 = A( [1,2,3,4] ) </pre></div> +<p> +<tt>std::initializer_list</tt> 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 +<tt>std::initializer_list</tt>. 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. +</p> + +<p> +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 <tt>%ignore</tt>. +</p> + <H3><a name="Cpp0x_Uniform_initialization"></a>7.2.5 Uniform initialization</H3> 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 <initializer_list> @@ -10,6 +10,13 @@ class A { public: A( std::initializer_list<int> ) {} A() {} + A(double d) {} +}; +class B { +public: + B( std::initializer_list<int>, std::initializer_list<double> ) {} + B() {} + void method(std::initializer_list<int> 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 <std_vector.i> + +%template(VectorInt) std::vector<int>; + %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<int> vi {1,2,3,4,5}; + + MoreInit() {} + + int more1(std::vector<int> 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 { |