Initialization list doc updates and new tests. Fix functions with default arguments that are initializer lists

This commit is contained in:
William S Fulton 2013-02-02 01:15:28 +00:00
commit c8ff23de0c
6 changed files with 96 additions and 14 deletions

View file

@ -126,13 +126,14 @@ public:
<H3><a name="Cpp0x_Initializer_lists"></a>7.2.4 Initializer lists</H3> <H3><a name="Cpp0x_Initializer_lists"></a>7.2.4 Initializer lists</H3>
<p>Constructors using the std::initializer_list class are removed <p>
from the wrapped class, because the only way to access such a Constructors using the std::initializer_list class are removed
constructor is at compile time using the "= {}" assignment.</p> from the wrapped class because the only way to access such a
<p>Users should add another constructor with specific arguments constructor is at compile time using the initialization list syntax.
filling the class members manually.</p> 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> <div class="code"><pre>
class A { class A {
@ -142,7 +143,7 @@ public:
A a1 = {1,2,3,4}; A a1 = {1,2,3,4};
</pre></div> </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> <div class="code"><pre>
class A { class A {
@ -153,11 +154,26 @@ public:
A a1 = {1,2,3,4}; A a1 = {1,2,3,4};
</pre></div> </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> <div class="targetlang"><pre>
&gt;&gt;&gt; a2 = A( [1,2,3,4] ) &gt;&gt;&gt; a2 = A( [1,2,3,4] )
</pre></div> </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> <H3><a name="Cpp0x_Uniform_initialization"></a>7.2.5 Uniform initialization</H3>

View file

@ -1,7 +1,7 @@
/* This testcase checks whether SWIG correctly uses the new initializer_list /* This testcase checks whether SWIG correctly uses the new initializer_list
introduced in C++0x. */ introduced in C++0x. */
%module cpp0x_initializer_list %module cpp0x_initializer_list
%warnfilter(520) A; %warnfilter(SWIGWARN_LANG_INITIALIZER_LIST) A;
%inline %{ %inline %{
#include <initializer_list> #include <initializer_list>
@ -10,6 +10,13 @@ class A {
public: public:
A( std::initializer_list<int> ) {} A( std::initializer_list<int> ) {}
A() {} A() {}
A(double d) {}
};
class B {
public:
B( std::initializer_list<int>, std::initializer_list<double> ) {}
B() {}
void method(std::initializer_list<int> init) {}
}; };
%} %}

View file

@ -1,7 +1,11 @@
/* This testcase checks whether SWIG syntactically correctly parses the curly /* This testcase checks whether SWIG syntactically correctly parses the initialization syntax using
brackets {} for uniform member initialization. */ {} braces for uniform member initialization. */
%module cpp0x_uniform_initialization %module cpp0x_uniform_initialization
%include <std_vector.i>
%template(VectorInt) std::vector<int>;
%inline %{ %inline %{
struct BasicStruct { struct BasicStruct {
int x; int x;
@ -10,6 +14,8 @@ struct BasicStruct {
struct AltStruct { struct AltStruct {
AltStruct(int x, double y) : x_{x}, y_{y} {} AltStruct(int x, double y) : x_{x}, y_{y} {}
int getX() { return x_; }
double getY() { return y_; }
private: private:
int x_; int x_;
@ -19,4 +25,25 @@ private:
BasicStruct var1{5, 3.2}; // only fills the struct components BasicStruct var1{5, 3.2}; // only fills the struct components
AltStruct var2{2, 4.3}; // calls the constructor 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} };
%} %}

View file

@ -0,0 +1,5 @@
import cpp0x_initializer_list
a = cpp0x_initializer_list.A()
a = cpp0x_initializer_list.A(11.1)

View file

@ -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

View file

@ -5165,7 +5165,7 @@ def_args : EQUAL definetype {
} }
| EQUAL LBRACE { | EQUAL LBRACE {
skip_balanced('{','}'); skip_balanced('{','}');
$$.val = 0; $$.val = NewString(scanner_ccode);
$$.rawval = 0; $$.rawval = 0;
$$.type = T_INT; $$.type = T_INT;
$$.bitfield = 0; $$.bitfield = 0;
@ -6625,7 +6625,10 @@ mem_initializer_list : mem_initializer
| mem_initializer_list COMMA mem_initializer PERIOD PERIOD PERIOD | 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. /* Uniform initialization in C++0x.
Example: Example:
struct MyStruct { struct MyStruct {
@ -6634,7 +6637,10 @@ mem_initializer : idcolon LPAREN { skip_balanced('(',')'); Clear(scanner_ccode);
double y_; double y_;
}; };
*/ */
| idcolon LBRACE { skip_balanced('{','}'); Clear(scanner_ccode); } | idcolon LBRACE {
skip_balanced('{','}');
Clear(scanner_ccode);
}
; ;
template_decl : LESSTHAN valparms GREATERTHAN { template_decl : LESSTHAN valparms GREATERTHAN {