Rename all C++0x to C++11 and cpp0x to cpp11
This commit is contained in:
parent
173c4b3bba
commit
738cc36aab
52 changed files with 309 additions and 309 deletions
788
Doc/Devel/cpp11.html
Normal file
788
Doc/Devel/cpp11.html
Normal file
|
|
@ -0,0 +1,788 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
|
||||
<TITLE></TITLE>
|
||||
<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Unix)">
|
||||
<META NAME="CREATED" CONTENT="20090712;16061100">
|
||||
<META NAME="CHANGED" CONTENT="20090817;17311900">
|
||||
<META NAME="Podatek 1" CONTENT="">
|
||||
<META NAME="Podatek 2" CONTENT="">
|
||||
<META NAME="Podatek 3" CONTENT="">
|
||||
<META NAME="Podatek 4" CONTENT="">
|
||||
<STYLE TYPE="text/css">
|
||||
<!--
|
||||
@page { margin: 2cm }
|
||||
H1 { margin-bottom: 0.21cm }
|
||||
H1.western { font-family: "Liberation Serif", serif }
|
||||
H1.cjk { font-family: "DejaVu Sans" }
|
||||
H1.ctl { font-family: "DejaVu Sans" }
|
||||
P { margin-bottom: 0.21cm }
|
||||
H2 { margin-bottom: 0.21cm }
|
||||
A:link { so-language: zxx }
|
||||
-->
|
||||
</STYLE>
|
||||
</HEAD>
|
||||
<BODY LANG="en-US" DIR="LTR">
|
||||
<H1 CLASS="western"><U>C++0x/C++11 support for SWIG</U></H1>
|
||||
<H1 CLASS="western">Summary</H1>
|
||||
<P>This is a technical overview of the C++0x/C++11 support for the Swig.
|
||||
This area of Swig is a work in progress. Initial C++0x/C++11 support for
|
||||
Swig was written during the Google Summer of Code 2009 period by
|
||||
Matevž Jekovec.</P>
|
||||
<H1 CLASS="western">SVN branch</H1>
|
||||
<P>branches/gsoc2009-matevz</P>
|
||||
<H1 CLASS="western">New C++11 features status</H1>
|
||||
<P>Wikipedia article: <A HREF="http://en.wikipedia.org/wiki/C++0x">http://en.wikipedia.org/wiki/C%2B%2B0x</A>
|
||||
</P>
|
||||
<H2>Rvalue reference and move semantics [done]</H2>
|
||||
<P>The Rvalues are used in practice to speed up the move operations
|
||||
on different containers.</P>
|
||||
<P>In the following example, we want to swap the given elements:</P>
|
||||
<PRE>template <class T> swap(T& a, T& b) {
|
||||
T tmp(a); // now we have two copies of a
|
||||
a = b; // now we have two copies of b
|
||||
b = tmp; // now we have two copies of tmp (aka a)
|
||||
}</PRE><P>
|
||||
This can now be solved using the new function std::move():</P>
|
||||
<PRE>template <class T> swap(T& a, T& b) {
|
||||
T tmp(std::move(a));
|
||||
a = std::move(b);
|
||||
b = std::move(tmp);
|
||||
}</PRE><P STYLE="margin-bottom: 0cm">
|
||||
For the move function to take effect, user needs to reimplement the
|
||||
move constructor (taking ClassType&& as an argument) and
|
||||
operator=(ClassType&&):</P>
|
||||
<PRE>class MyClass {
|
||||
MyClass(MyClass&& p) : ptr(p.ptr) {p.ptr = 0;}
|
||||
MyClass& operator=(MyClass&& p) {
|
||||
std::swap(ptr, p.ptr);
|
||||
return *this;
|
||||
}
|
||||
};</PRE><P>
|
||||
In practice, the Rvalues are used for temporaries (when passing the
|
||||
result of one function as an argument to another).</P>
|
||||
<P>Done: Added type&& to Swig parser. Added testcase
|
||||
cpp11_rvalue_reference.i. Operator && is treated the same as
|
||||
operator &. R11450</P>
|
||||
<P STYLE="margin-bottom: 0cm">Article:
|
||||
<A HREF="http://www.artima.com/cppsource/rvalue.html">http://www.artima.com/cppsource/rvalue.html</A></P>
|
||||
<H2>Generalized constant expressions [done]</H2>
|
||||
<P>In C++11 you can define functions as constant expressions.
|
||||
Functions need to return constant value in form "return expr",
|
||||
where expr is a constant expression.
|
||||
</P>
|
||||
<P>A keyword "constexpr" is introduced for this. eg.:
|
||||
constexpr int getNumber() { return 5; } const int MY_CONSTANT =
|
||||
getNumber();
|
||||
</P>
|
||||
<P>Constants are treated as normal variables in interpreted languages
|
||||
because they are not compiled into the executable. Java "final"
|
||||
constants are defined runtime as well. C++ constants need to be
|
||||
declared in the header file and defined in the implementation file,
|
||||
so swig doesn't need to know about the constant values when parsing
|
||||
the header file.
|
||||
</P>
|
||||
<P>Done: Added the “constexpr “ keyword to Swig. Added testcase
|
||||
cpp11_constexpr. R11322</P>
|
||||
<P>Problem: No compilers were known to support constexpr yet, so the
|
||||
testcase was temporarily commented out in common.mk.
|
||||
</P>
|
||||
<H2>Extern template [done]</H2>
|
||||
<P>Extern template forces the GCC compiler to not instantiate the
|
||||
template in the translation unit at that time. It's a feature
|
||||
specifically aimed at compilers to speed up the compilation process.
|
||||
</P>
|
||||
<P>Done: Added support for 'extern template class
|
||||
std::vector<MyClass>;'. Added testcase cpp11_template_explicit.
|
||||
R11385 , R11386</P>
|
||||
<H2>Initializer lists [done]</H2>
|
||||
<P>Initializer list is a new type in standard library:
|
||||
std::initializer_list<T>. New symbols {} are introduced for the
|
||||
initializer lists.
|
||||
</P>
|
||||
<P>One can now use:
|
||||
</P>
|
||||
<PRE> class A {
|
||||
public:
|
||||
A( std::initializer_list<int> );
|
||||
};
|
||||
A a1 = {1,2,3,4};</PRE><P>
|
||||
Languages like Java, C# and Python already support direct creation of
|
||||
lists natively.</P>
|
||||
<P>Problem: initializer_list cannot be treated as an ordinary list.
|
||||
The constructor containing initializer_list can only be accessed by
|
||||
assigning the value using the {} brackets. I also don't think there
|
||||
is a simple way to convert an ordinary list or a vector to the
|
||||
initializer_list.</P>
|
||||
<P>Done: Ignored the constructor having initializer_list as its
|
||||
argument. Show warning to the user. Added testcase
|
||||
cpp11_initializer_list. R11450</P>
|
||||
<P>Article:
|
||||
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1919.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1919.pdf</A></P>
|
||||
<H2>Uniform initialization [done]</H2>
|
||||
<P>The new C++11 standard will allow the following:</P>
|
||||
<PRE>struct IdString {
|
||||
std::string name;
|
||||
int identifier;
|
||||
};
|
||||
|
||||
IdString GetString() {
|
||||
return {"SomeName", 4}; //Note the lack of explicit type.
|
||||
}</PRE><P>
|
||||
The feature works exactly as it did now for POD types only (eg. int
|
||||
a[] = {1,2,3};). The following declarations are the same in the new
|
||||
C++11:</P>
|
||||
<PRE>IdString str1 = {„SomeName“, 4};
|
||||
IdString str2{„SomeName“, 4};</PRE><P>
|
||||
The new way of using uniform initialization allows the following:</P>
|
||||
<PRE>struct BasicStruct {
|
||||
int x;
|
||||
double y;
|
||||
};
|
||||
|
||||
struct AltStruct {
|
||||
AltStruct(int x, double y) : x_{x}, y_{y} {}
|
||||
|
||||
private:
|
||||
int x_;
|
||||
double y_;
|
||||
};
|
||||
|
||||
BasicStruct var1{5, 3.2}; // only fills the struct components
|
||||
AltStruct var2{2, 4.3}; // calls the constructor</PRE><P>
|
||||
The new syntax is specific to C++. Java, C# and scripting languages
|
||||
do not support this behaviour, but always need constructors. They
|
||||
support {} brackets for declaration of arrays as C does + they add
|
||||
support for creation of arrays on-the-fly (what C++11 introduced with
|
||||
this feature and more).</P>
|
||||
<P>Done: Added syntax for {} member initialization in class
|
||||
constructor. Added testcase cpp11_uniform_initialization. R11413</P>
|
||||
<H2>Type inference [partially done]</H2>
|
||||
<P>A new keyword 'auto' is introduced in C++11:</P>
|
||||
<PRE>auto a1 = 100;
|
||||
auto a2 = myFunc();</PRE><P>
|
||||
The type of a1 and a2 is automatically determined according to the
|
||||
initialization value during the semantic phase of the compiler.</P>
|
||||
<P>Another macro 'decltype()' is introduced. The macro takes the
|
||||
concrete object as an argument and returns its type. User could use
|
||||
this as:</P>
|
||||
<PRE>int i = 100;
|
||||
decltype(i) j = 200; // decltype(i) = int</PRE><P STYLE="margin-bottom: 0cm">
|
||||
Calling operators are allowed as well:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">decltype(i+j) k = 300;</PRE><P>
|
||||
Done: Added support for decltype() syntax. Test cases for normal
|
||||
decltype members and alternate function members work fine. Currently
|
||||
only syntax in form decltype(variable name) work. No support for
|
||||
custom expresions eg. decltype(i+j) yet. R11525</P>
|
||||
<P>TODO: William proposed to support the hidden variables as well
|
||||
(ones not parsed by Swig and added to symbol table). This also allows
|
||||
Swig to parse custom expressions like decltype(i+j). The idea is to
|
||||
introduce a new SwigType for this.</P>
|
||||
<H2>Range-based for-loop [ignored]</H2>
|
||||
<P>This feature is always present inside the implementation block
|
||||
only.
|
||||
</P>
|
||||
<H2>Lambda functions and expressions [done]</H2>
|
||||
<P>C++11 introduces lambda functions defined as:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">[](int x, int y) -> int { return x + y; }</PRE><P>
|
||||
If the lambda function contains a single return statement only or the
|
||||
function doesn't return any type, the return type '->' can be
|
||||
omitted. Lambda functions are function objects.</P>
|
||||
<P>The following example prints the number of items stored in a list:</P>
|
||||
<PRE>std::vector<int> someList;
|
||||
int total = 0;
|
||||
std::for_each( someList.begin(), someList.end(), [&total](int x) {total += x} );
|
||||
std::cout << total;</PRE><P>
|
||||
Parameters inside the [] are the visible parameters of the lambda
|
||||
functions. These can be & (references), = (copies), variable name
|
||||
(variable copy), &variable name (variable reference) or this
|
||||
(copy of the current object).</P>
|
||||
<P>Lambda functions can be stored using:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">auto myLambdaFunc = [this]() { this->SomePrivateMemberFunction() };</PRE><P>
|
||||
Proposal: Lambda functions are most commonly used inside the function
|
||||
block to quickly define how the sort, find and similar functions
|
||||
should work (the other way would be overriding a class – the Java
|
||||
style). The latest GCC does not support lambda functions yet so it is
|
||||
difficult to test the feature once implemented. I would implement the
|
||||
syntax support for this feature, but produce no wrapper code. Lambda
|
||||
functions still work inside the function block though.</P>
|
||||
<P>Article:
|
||||
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2550.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2550.pdf</A></P>
|
||||
<P>Done: Added syntax support for the lambda functions. Added
|
||||
testcase cpp11_lambda_functions.i. R11491, R11492</P>
|
||||
<H2>Alternate function syntax [done]</H2>
|
||||
<P>The problem with decltype() is that the parameters need to be
|
||||
defined before the decltype. The following syntax is not valid,
|
||||
because lhs and rhs hasn't been defined at the time of decltype:</P>
|
||||
<PRE>template< typename LHS, typename RHS>
|
||||
decltype(lhs+rhs) AddingFunc(const LHS &lhs, const RHS &rhs) {return lhs + rhs;} //Not legal C++11</PRE><P>
|
||||
The solution C++11 offers is the combination of the 'auto' keyword
|
||||
before and '-> rettype' after the function declaration:</P>
|
||||
<PRE>template< typename LHS, typename RHS>
|
||||
auto AddingFunc(const LHS &lhs, const RHS &rhs) -> decltype(lhs+rhs) {return lhs + rhs;}</PRE><P>
|
||||
The new syntax only makes the job for the C++ compilers easier when
|
||||
parsing such functions. The new syntax can be used for ordinary
|
||||
functions as well:</P>
|
||||
<PRE>struct SomeStruct {
|
||||
auto FuncName(int x, int y) -> int;
|
||||
};
|
||||
|
||||
auto SomeStruct::FuncName(int x, int y) -> int {
|
||||
return x + y;
|
||||
}</PRE><P>
|
||||
Done: Added support for the 'auto' return type. Added support for the
|
||||
'-> type' after the funtion declaration. Added testcases
|
||||
cpp11_alternate_function_syntax.i and
|
||||
cpp11_alternate_function_syntax_runme.py. R11414</P>
|
||||
<H2>Concepts, Axioms [ignored]</H2>
|
||||
<P>In C++ there is a common problem when you use a template in the
|
||||
class which doesn't support all the operations the functions in the
|
||||
class actually do on the type. Compiler errors are usually very long
|
||||
and unreadable. C++11 adds support for the "concepts". The
|
||||
idea is to define what operations and attributes should the template
|
||||
have. In contrast to class inheritance and polimorphism, all lookups
|
||||
are done in compile-time.
|
||||
</P>
|
||||
<P>Basic syntax (note LessThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=LessThanComparable">?</A>
|
||||
instead of "class" or "typename"):
|
||||
</P>
|
||||
<PRE> template<LessThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=LessThanComparable">?</A> T>
|
||||
const T& min(const T &x, const T &y) {
|
||||
return y < x ? y : x;
|
||||
}</PRE><P>
|
||||
Extended syntax (requires conditions are separated with &&,
|
||||
|| or !):
|
||||
</P>
|
||||
<PRE> template< typename T> requires LessThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=LessThanComparable">?</A><T>
|
||||
const T& min(const T &x, const T &y) {
|
||||
return y < x ? y : x;
|
||||
}</PRE><P>
|
||||
Definition of the concepts:
|
||||
</P>
|
||||
<PRE> concept LessThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=LessThanComparable">?</A>< typename T > {
|
||||
bool operator<(T,T);
|
||||
requires GreaterThanComparable<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=GreaterThanComparable">?</A><T>;
|
||||
typename value_type;
|
||||
typename reference;
|
||||
};</PRE><P>
|
||||
Concept maps allow usage of a specific type:
|
||||
</P>
|
||||
<PRE> template< typename T>
|
||||
concept_map InputIterator<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=InputIterator">?</A><T*> {
|
||||
typedef T value_type ;
|
||||
typedef T& reference ;
|
||||
typedef T* pointer ;
|
||||
typedef std::ptrdiff_t difference_type ;
|
||||
};</PRE><P>
|
||||
Concept maps can act as mini-types, with function definitions and
|
||||
other constructs commonly associated with classes:
|
||||
</P>
|
||||
<PRE> concept Stack< typename X> {
|
||||
typename value_type;
|
||||
void push(X&, const value_type&);
|
||||
void pop(X&);
|
||||
value_type top(const X&);
|
||||
bool empty(const X&);
|
||||
};
|
||||
template< typename T>
|
||||
concept_map Stack<std::vector<T> > {
|
||||
typedef T value_type;
|
||||
void push(std::vector<T>& v, const T& x) { v.push_back(x); }
|
||||
void pop(std::vector<T>& v) { v.pop_back(); }
|
||||
T top(const std::vector<T>& v) { return v.back(); }
|
||||
bool empty(const std::vector<T>& v) { return v.empty(); }
|
||||
};</PRE><P>
|
||||
Axioms are a facility pertaining to concepts supplied by C++11 to
|
||||
express the semantic properties of concepts. For example, the concept
|
||||
Semigroup can be defined with an axiom Associativity as:
|
||||
</P>
|
||||
<PRE> concept Semigroup< typename Op, typename T> : CopyConstructible<A HREF="http://www.dabeaz.com/cgi-bin/wiki.pl?action=change1&id=CopyConstructible">?</A><T> {
|
||||
T operator()(Op, T, T);
|
||||
axiom Associativity(Op op, T x, T y, T z) {
|
||||
op(x, op(y, z)) == op(op(x, y), z);
|
||||
}
|
||||
};</PRE><P>
|
||||
Axioms are more like hints to the compiler to speed-up the process of
|
||||
compilation.
|
||||
</P>
|
||||
<P>Ignored: Concepts and axioms were removed from the C++11 standard.
|
||||
</P>
|
||||
<H2>Object construction improvement [done]</H2>
|
||||
<P>This feature allows classes constructors to call other
|
||||
constructors with different arguments (similar to Java and C#
|
||||
behaviour).
|
||||
</P>
|
||||
<P>The syntax is as follows:
|
||||
</P>
|
||||
<PRE> class SomeType {
|
||||
int number;
|
||||
public:
|
||||
SomeType(int newNumber) : number(newNumber) {}
|
||||
SomeType() : SomeType(42) {}
|
||||
};</PRE><P>
|
||||
Also when using the inheritance, the feature introduces inheritance
|
||||
of all superclass constructors without being defined separately in
|
||||
the inherited class:
|
||||
</P>
|
||||
<PRE> class BaseClass {
|
||||
public:
|
||||
BaseClass(int iValue);
|
||||
};
|
||||
class DerivedClass: public BaseClass {
|
||||
public:
|
||||
using BaseClass::BaseClass; // Adds DerivedClass(int) constructor
|
||||
};</PRE><P>
|
||||
Swig already correctly parses and produces the correct wrapper for
|
||||
the “using” keyword.</P>
|
||||
<P>Done: Added testcase cpp11_constructors.i which covers both
|
||||
constructor delegation and constructor inheritance. R11532</P>
|
||||
<P>Problem: Constructor delegation and constructor inheritance is not
|
||||
supported by any compiler yet, so it's impossible to try and test
|
||||
this feature.</P>
|
||||
<H2>Null pointer constant [done]</H2>
|
||||
<P>nullptr is part of the standard library.
|
||||
</P>
|
||||
<P>It's defined as typedef decltype(nullptr) nullptr_t;
|
||||
</P>
|
||||
<P>nullptr_t is defined in <cstddef>.
|
||||
</P>
|
||||
<P>As far as the C++ is compatible with 0 as the pointer value, swig
|
||||
values will work for the C++. And the other way around, nullptr
|
||||
behaves as the ordinary pointer (false, if empty, true, if not
|
||||
empty), so it's ok for swig to compare it.</P>
|
||||
<P>Done: Written a testcase cpp11_null_pointer_constant.i and
|
||||
cpp11_null_pointer_constant_runme.py to prove the nullptr
|
||||
functionality. R11484</P>
|
||||
<H2>Strongly typed enumerations [partially done]</H2>
|
||||
<P>C++11 introduces a new syntax for strongly typed enum declaration:
|
||||
</P>
|
||||
<PRE> enum class Enumeration {
|
||||
Val1,
|
||||
Val2,
|
||||
Val3 = 100,
|
||||
Val4 /* = 101 */
|
||||
};</PRE><P>
|
||||
Typing if (Val4 == 101) will result in compilation error.
|
||||
</P>
|
||||
<P>The enum itself can now be explicitely of type int, long, unsigned
|
||||
int etc.:
|
||||
</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm"> enum class Enum2 : unsigned int {Val1, Val2};</PRE><P>
|
||||
And it can be forward declared as well:
|
||||
</P>
|
||||
<PRE> enum Enum1; //Illegal in C++ and C++11; no size is explicitly specified.
|
||||
enum Enum2 : unsigned int; //Legal in C++11.
|
||||
enum class Enum3; //Legal in C++11, because enum class declarations have a default type of "int".
|
||||
enum class Enum4: unsigned int; //Legal C++11.
|
||||
enum Enum2 : unsigned short; //Illegal in C++11, because Enum2 was previously declared with a different type.</PRE><P>
|
||||
Done: Added syntax 'enum class Name' and forward declarators 'enum
|
||||
Name : inherited type' or 'enum class Name : inherited type' in
|
||||
R11449.</P>
|
||||
<P>TODO: Add semantic support for enum elements not clashing with
|
||||
enum elements in other enum classes. See cpp11_strongly_typed_enums.i
|
||||
warnings.</P>
|
||||
<P>Problem: Swig currently doesn't support nested classes. This
|
||||
feature should be implemented using a new nested class when using
|
||||
“enum class” with a single anonymous “enum {elements}”
|
||||
element inside. For example:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">class A { enum class EA { a,b,c,d }; };</PRE><P>
|
||||
should be mapped to</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">class A { class EA { enum {a,b,c,d}; }; };</PRE><H2>
|
||||
Angle bracket [done]</H2>
|
||||
<P>Support for right angled brackets was implemented using the
|
||||
following article as a base:
|
||||
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html</A>
|
||||
</P>
|
||||
<P>Done: Added support for angle brackets. Used the preferred
|
||||
"Approach 1". Added a testcase named
|
||||
cpp11_template_double_brackets. R11245</P>
|
||||
<H2>Explicit conversion operators [done]</H2>
|
||||
<P>This is used when converting one type to another (eg. if
|
||||
(myObject) {}, where myObject is your custom class converted to
|
||||
bool).
|
||||
</P>
|
||||
<P>Requires both operator and function overloading which is not
|
||||
supported in any target language (eg. python, php).
|
||||
</P>
|
||||
<P>Done: Swig already supports the keyword "explicit" for
|
||||
function types as well. Added test case
|
||||
cpp11_explicit_conversion_operators. R11323</P>
|
||||
<H2>Template typedefs [partially done]</H2>
|
||||
<P>The new C++11 will allow creation of wrapper around the template.
|
||||
For example, if we want to do this:</P>
|
||||
<PRE>template< typename first, typename second, int third>
|
||||
class SomeType;
|
||||
|
||||
template< typename second>
|
||||
typedef SomeType<OtherType, second, 5> TypedefName; //Illegal in C++</PRE><P>
|
||||
This is still illegal! But we can now use the new syntax for
|
||||
achieving the same effect:</P>
|
||||
<PRE>template< typename first, typename second, int third>
|
||||
class SomeType;
|
||||
|
||||
template< typename second>
|
||||
using TypedefName = SomeType<OtherType, second, 5>;</PRE><P>
|
||||
Here we created a new wrapper TypedefName taking one template
|
||||
argument <second> which creates a type SomeType<OtherType,
|
||||
second, 5>. OtherType and 5 are predefined here and hidden from
|
||||
the user – the user only uses TypedefName type.</P>
|
||||
<P>The same goes for the following example:</P>
|
||||
<PRE>typedef void (*PFD)(double); // Old style
|
||||
using PF = void (*)(double); // New introduced syntax</PRE><P>
|
||||
Swig supports parsing typedefs for templates as well for example:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">typedef List<int> intList;</PRE><P>
|
||||
Done: Expanded support for the new 'using' syntax and template
|
||||
aliasing. Added testcase cpp11_template_typedefs. R11533</P>
|
||||
<P>TODO: Make Swig aware of the newly defined typedef. The TYPEDEF
|
||||
keyword is part of the storage_class rule and type+declarator (see
|
||||
c_decl rule) is the right part of the definition – for example void
|
||||
(*PFD)(double) cannot be transformed to void *(double) easily. To
|
||||
fully support the new 'using' form, we'll probably have to change the
|
||||
type, type_right rules and declarator, direct_declarator,
|
||||
notso_direct_declarator etc., which is PITA.</P>
|
||||
<H2>Unrestricted unions [done]</H2>
|
||||
<P>C++ currently offers usage of unions for types with trivial
|
||||
constructors only. The new C++11 standard allows usage of types with
|
||||
non-trivial constructors as well:</P>
|
||||
<PRE> struct point {
|
||||
point() {}
|
||||
point(int x, int y): x_(x), y_(y) {}
|
||||
int x_, y_;
|
||||
};
|
||||
union P {
|
||||
int z;
|
||||
double w;
|
||||
point p; // Illegal in C++; point has a non-trivial constructor. However, this is legal in C++11.
|
||||
} p1;</PRE><P>
|
||||
Swig already parses the given syntax.</P>
|
||||
<P>Done: Added testcase cpp11_unrestricted_unions. R11435, R11447</P>
|
||||
<P>Problem: GCC doesn't support unrestricted unions yet so there is
|
||||
no way to actually test, if it works.</P>
|
||||
<H2>Variadic templates [partially done]</H2>
|
||||
<P>The new C++11 offers the following syntax:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">template<typename... Values> class tuple;</PRE><P>
|
||||
This can be used for example:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">class tuple<int, std::vector<int>, std::map<std::string, std::vector<int>>> someInstanceName;</PRE><P>
|
||||
The ... is used in two cases. One is in the template header where it
|
||||
marks on the left the keywords 'typename' or 'class' and a type name
|
||||
on the right. The second case is usually in the function block to
|
||||
decompose typename on the left of the ... . For example:</P>
|
||||
<PRE>void printf(const char *s) {
|
||||
while (*s) {
|
||||
if (*s == '%' && *(++s) != '%')
|
||||
throw std::runtime_error("invalid format string: missing arguments");
|
||||
std::cout << *s++;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
void printf(const char* s, T value, Args... args) { // recursive action – split previous args to value + args
|
||||
while (*s) {
|
||||
if (*s == '%' && *(++s) != '%') {
|
||||
std::cout << value;
|
||||
printf(*s ? ++s : s, args...); // call even when *s == 0 to detect extra arguments
|
||||
return;
|
||||
}
|
||||
std::cout << *s++;
|
||||
}
|
||||
throw std::logic_error("extra arguments provided to printf");
|
||||
}</PRE><P>
|
||||
The tricky part is that variadic templates can unpack actually
|
||||
anywhere – including the class inheritance :(</P>
|
||||
<PRE>template <typename... BaseClasses> class ClassName : public BaseClasses... {
|
||||
public:
|
||||
|
||||
ClassName (BaseClasses&&... baseClasses) : BaseClasses(baseClasses)... {}
|
||||
}</PRE><P>
|
||||
A new extension to sizeof is also introduced with this feature. The
|
||||
... after sizeof returns number of arguments:</P>
|
||||
<PRE>template<typename ...Args> struct SomeStruct {
|
||||
static const int size = sizeof...(Args);
|
||||
}
|
||||
// SomeStruct<Type1, Type2>::size is 2 and SomeStruct<>::size is 0</PRE><P>
|
||||
Done: Added syntax support for 'typename' or 'class' + ... + id.
|
||||
Added testcase cpp11_variadic_templates. R11458</P>
|
||||
<P>Done: Added syntax support for BaseClass + ..., type + ... + id in
|
||||
parameters and baseclass + ... for intializers after constructor.
|
||||
Extended Swig syntax to support sizeof...(Args). R11467</P>
|
||||
<P>Done: Fixed %template to support variadic number of templates.</P>
|
||||
<P>TODO: Only (if present) first variadically defined argument is
|
||||
currently used in %template directive. The next ones are ignored.</P>
|
||||
<H2>New string literals [partially done]</H2>
|
||||
<P>Beside the implementation, the new C++11 Unicode and custom
|
||||
delimeter constants can occur in templates in the header file.
|
||||
</P>
|
||||
<P>Done: Added symbols 'u', 'u8' and 'U' to mark the beginning of the
|
||||
UTF string. Also added test case cpp11_raw_string_literals. R11327</P>
|
||||
<P>Done: Added R"DELIMITER[, ]DELIMITER" for a custom
|
||||
delimiter for the beginning/end of the string. R11328</P>
|
||||
<P>TODO: Fix the Swig's C++ preprocessor bug when parsing an odd
|
||||
number of “ inside the string brackets. See
|
||||
Source/Preprocessor/cpp.c.</P>
|
||||
<H2>User-defined literals [partially done]</H2>
|
||||
<P>C++ has different suffix literals. eg. 12.5f marks the number 12.5
|
||||
as float.
|
||||
</P>
|
||||
<P>C++11 allows user to define his own suffix for the strings always
|
||||
starting with the underscore (_). eg. int a = "hello"_mySuffix;
|
||||
</P>
|
||||
<P>The syntax is similar to other operator overloading functions:
|
||||
</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm"> OutputType operator "" _mySuffix(const char * string_values);</PRE><P>
|
||||
The null terminated const char* is the string between the "".
|
||||
The _mySuffix is the name of the suffix operator. And the OutputType
|
||||
is the outputType the operator returns.
|
||||
</P>
|
||||
<P>Other forms are:
|
||||
</P>
|
||||
<PRE> OutputType operator "" _mySuffix(const char * string_values, size_t num_chars);
|
||||
OutputType operator "" _mySuffix(const wchar_t * string_values, size_t num_chars);
|
||||
OutputType operator "" _mySuffix(const char16_t * string_values, size_t num_chars);
|
||||
OutputType operator "" _mySuffix(const char32_t * string_values, size_t num_chars);
|
||||
OutputType operator "" _mySuffix(int value); /* cooked version - ie. atoi() of string */</PRE><P>
|
||||
Another possibility is to use variadic templates:
|
||||
</P>
|
||||
<PRE> template<char...> OutputType operator "" _mySuffix();
|
||||
OutputType someVariable = "1234"_mySuffix;</PRE><P>
|
||||
This instantiates the literal processing function as
|
||||
operator""_Suffix<'1', '2', '3', '4'>. In this form,
|
||||
there is no terminating null character to the string. The main
|
||||
purpose to doing this is to use C++11's constexpr keyword and the
|
||||
compiler to allow the literal to be transformed entirely at compile
|
||||
time, assuming OutputType is a constexpr-constructable and copyable
|
||||
type, and the literal processing function is a constexpr function.</P>
|
||||
<P>Article:
|
||||
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf</A></P>
|
||||
<P>Done: Added syntax support for userdefined literals. Added
|
||||
testcase cpp11_userdefined_literals.i. R11494</P>
|
||||
<P>TODO: %rename doesn't parse operator”” yet.</P>
|
||||
<H2>Thread-local storage [done]
|
||||
</H2>
|
||||
<P>New C++11 introduces keyword "thread_local" which marks
|
||||
the following variable dynamically located depending on the current
|
||||
thread when using the address-of (&) operator.
|
||||
</P>
|
||||
<P>Syntax:
|
||||
</P>
|
||||
<PRE> struct A {
|
||||
thread_local int val;
|
||||
};</PRE><P>
|
||||
Done: Add "thread_local" keyword to Swig. Added testcase
|
||||
cpp11_thread_local. R11393</P>
|
||||
<H2>Defaulting/deleting of standard functions on C++ objects [done]</H2>
|
||||
<P>C++ automatically creates default constructor with empty
|
||||
parameters, copy constructor, operator= and destructor for any class.
|
||||
Sometimes user wants to explicitly remove one of them or enable them
|
||||
(eg. default constructor with empty parameters doesn't work any more,
|
||||
if any other constructor is defined).
|
||||
</P>
|
||||
<P>Words "default" and "delete" are introduced.
|
||||
The syntax is similar to declaration of pure virtual function:
|
||||
</P>
|
||||
<PRE> struct NonCopyable {
|
||||
NonCopyable & operator=(const NonCopyable&) = delete; /* Removes operator= */
|
||||
NonCopyable(const NonCopyable&) = delete; /* Removed copy constructor */
|
||||
NonCopyable() = default; /* Explicitly allows the empty constructor */
|
||||
void *operator new(std::size_t) = delete; /* Removes new NonCopyable */
|
||||
};</PRE><P>
|
||||
User has the ability by using keyword delete to disallow calling of
|
||||
the standard functions brought by C++ itself.
|
||||
</P>
|
||||
<PRE> struct A1 {
|
||||
void f(int i);
|
||||
void f(double i) = delete; /* Don't cast double to int. Compiler returns an error */
|
||||
};
|
||||
struct A2 {
|
||||
void f(int i);
|
||||
template<class T> void f(T) = delete; /* Only accept int */
|
||||
};</PRE><P>
|
||||
Ignored: Swig already parses the keywords "= delete" and "=
|
||||
default". These keywords are used for built-in functions (copy
|
||||
constructor, operator= etc.), which are ignored by Swig anyway.</P>
|
||||
<P>Done: Added testcase cpp11_default_delete. R11535</P>
|
||||
<H2>Type long long int [done]</H2>
|
||||
<P>Type long long int is an integer type that has at least 64 useful
|
||||
bits. C99 added it to its standard, but the C++ didn't adopt it until
|
||||
C++11. Most C++ compilers supported it though.
|
||||
</P>
|
||||
<P>Done: Swig already parses the C code including the long long type.
|
||||
</P>
|
||||
<H2>Static assertions [done]</H2>
|
||||
<P>static_assert() can be used at class scope as well eg.:
|
||||
</P>
|
||||
<PRE> template <typename T>
|
||||
struct Check {
|
||||
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
||||
};</PRE><P>
|
||||
Done: Added syntax support for "static_assert()". Added
|
||||
test case cpp11_static_assert. R11369</P>
|
||||
<H2>Allow sizeof to work on members of classes without an explicit
|
||||
object [done]</H2>
|
||||
<P>C++11 allows calls of sizeof to concrete objects as well:
|
||||
</P>
|
||||
<PRE> struct A { int member; };
|
||||
sizeof(A::member); //Does not work with C++03. Okay with C++11</PRE><P>
|
||||
This kind of syntax is already supported by Swig.</P>
|
||||
<P>Done: Added testcase cpp11_sizeof_objects. R11538
|
||||
</P>
|
||||
<H2>Threading facilities [ignored]</H2>
|
||||
<P>C++11 will add the following classes to the standard library:
|
||||
</P>
|
||||
<PRE> * std::thread
|
||||
* std::mutex, std::recursive_mutex
|
||||
* std::condition_variable, std::condition_variable_any
|
||||
* std::lock_guard, std::unique_lock
|
||||
* std::packaged_task</PRE><P>
|
||||
Ignored: No changes to the language itself is made.
|
||||
</P>
|
||||
<H2>Tuple types [TODO]</H2>
|
||||
<P>Tuple is array of various types. C++11 introduced this feature
|
||||
using variadic templates. Tuple is defined as:</P>
|
||||
<PRE STYLE="margin-bottom: 0.5cm">template <class ...Types> class tuple;</PRE><P>
|
||||
Constructor is automatically generated filling the tuple elements.
|
||||
get<X> function is introduced to get the Xth element in the
|
||||
tuple.</P>
|
||||
<PRE>typedef tuple< int, double, long &, const char * > test_tuple ;
|
||||
long lengthy = 12 ;
|
||||
test_tuple proof( 18, 6.5, lengthy, "Ciao!" ) ;
|
||||
lengthy = get<0>(proof) ; // Assign to 'lengthy' the value 18.
|
||||
get<3>(proof) = " Beautiful!" ; // Modify the tuple’s fourth element.</PRE><P>
|
||||
Tuples can be copied to each other, if all the elements are copiable:</P>
|
||||
<PRE>typedef tuple< int , double, string > tuple_1 t1 ;
|
||||
typedef tuple< char, short , const char * > tuple_2 t2( 'X', 2, "Hola!" ) ;
|
||||
t1 = t2 ; // Ok, first two elements can be converted,
|
||||
// the third one can be constructed from a 'const char *'.</PRE><P>
|
||||
TODO: Implement wrappers for the tuplet<> class.</P>
|
||||
<H2>Hash tables [TODO]</H2>
|
||||
<P>C++11 introduces the "unordered" version of existing
|
||||
types, which in practice work faster than the linear types:
|
||||
</P>
|
||||
<PRE> - unordered set
|
||||
- unordered multiset
|
||||
- unordered map
|
||||
- unordered multimap</PRE><P>
|
||||
Swig should use the "unordered" types exactly the same as
|
||||
the original linear types.</P>
|
||||
<P>Problem: Unordered types do not contain exactly same members as
|
||||
ordered ones (eg. _Hashtable_iterator does not offer operator--() and
|
||||
constructor with compare function which is required). So simply
|
||||
aliasing unordered classes to ordered ones doesn't work.</P>
|
||||
<P>TODO: Implement wrappers for unordered_ types. Initial work is
|
||||
already done in Lib/std/unordered_*.i files.</P>
|
||||
<H2>Regular expressions [ignored]</H2>
|
||||
<P>Two new classes are introduced in C++11: basic_regex and
|
||||
match_results. Both are defined in regex header file.
|
||||
</P>
|
||||
<P>Ignored: The new feature extends the standardy library only. No
|
||||
changes to Swig needed.
|
||||
</P>
|
||||
<H2>General-purpose smart pointers [done]</H2>
|
||||
<P>This feature deprecates auto_ptr and adds shared_ptr, weak_ptr and
|
||||
unique_ptr to the standard library.
|
||||
</P>
|
||||
<P>This feature only adds the smart pointers to the standard library
|
||||
and doesn't effect the C++ syntax.</P>
|
||||
<P>Done: Added test case which uses all three smart pointers in the
|
||||
class. R11394</P>
|
||||
<P>Problem: GCC standard library doesn't contain the new smart
|
||||
pointers yet.
|
||||
</P>
|
||||
<H2>Extensible random number facility [ignored]</H2>
|
||||
<P>This feature standardize the pseudo random number algorithm
|
||||
(currently, the random number generator was dependent on the
|
||||
platform/compiler). It adds functions linear_congruential,
|
||||
subtract_with_carry and mersenne_twister and symbols
|
||||
uniform_int_distribution, bernoulli_distribution,
|
||||
geometric_distribution, poisson_distribution, binomial_distribution,
|
||||
uniform_real_distribution, exponential_distribution,
|
||||
normal_distribution and gamma_distribution to the standard library.
|
||||
</P>
|
||||
<P>Ignored: The new feature extends the standardy library only. No
|
||||
changes to Swig needed.
|
||||
</P>
|
||||
<H2>Wrapper reference [ignored]</H2>
|
||||
<P>This feature adds ref and cref classes to the standard library
|
||||
(#include <utility>) usually used in tempalte functions.
|
||||
</P>
|
||||
<P>Ignored: The new feature extends the standardy library only. No
|
||||
changes to Swig needed.
|
||||
</P>
|
||||
<H2>Polymorphous wrappers for function objects [done]</H2>
|
||||
<P>Two features are introduced:
|
||||
</P>
|
||||
<UL>
|
||||
<LI><P>The function template wrapper:
|
||||
</P>
|
||||
</UL>
|
||||
<PRE STYLE="margin-bottom: 0.5cm"> function<int ( int, int )> pF;</PRE>
|
||||
<UL>
|
||||
<LI><P>and the function object:
|
||||
</P>
|
||||
</UL>
|
||||
<PRE> struct Test {
|
||||
bool operator()( short x, short y );
|
||||
};</PRE><P>
|
||||
Swig already supports the two.</P>
|
||||
<P>Done: Added a runtime testcase for function objects
|
||||
cpp11_function_objects. R11419.</P>
|
||||
<H2>Type traits for metaprogramming [ignored]</H2>
|
||||
<P>C++11 adds a new header file <type_traits> which includes
|
||||
helper functions to determine the template type while initializing
|
||||
the object at compile time.
|
||||
</P>
|
||||
<P>Swig already supports the following code:
|
||||
</P>
|
||||
<PRE> template< int B, int N >
|
||||
struct Pow {
|
||||
// recursive call and recombination.
|
||||
enum{ value = B*Pow< B, N-1 >::value };
|
||||
};
|
||||
template< int B > struct Pow< B, 0 > // <EM>N == 0</EM> condition of termination.
|
||||
{
|
||||
enum{ value = 1 };
|
||||
};
|
||||
int quartic_of_three = Pow< 3, 4 >::value ;</PRE><P>
|
||||
Functions is_convertible, is_integral, is_integral_const etc. are
|
||||
part of the new header:
|
||||
</P>
|
||||
<PRE>// First way of operating.
|
||||
template< bool B > struct algorithm {
|
||||
template< class T1, class T2 > int do_it( T1 &, T2 & ) { /*...*/ }
|
||||
};
|
||||
// Second way of operating.
|
||||
template<> struct algorithm<true> {
|
||||
template< class T1, class T2 > int do_it( T1, T2 ) { /*...*/ }
|
||||
};
|
||||
// Instantiating 'elaborate' will automatically instantiate the correct way to operate.
|
||||
template< class T1, class T2 > int elaborate( T1 A, T2 B ) {
|
||||
// Use the second way only if 'T1' is an integer and if 'T2' is
|
||||
// in floating point, otherwise use the first way.
|
||||
return algorithm< is_integral<T1>::value && is_floating_point<T2>::value >::do_it( A, B );
|
||||
}</PRE><P>
|
||||
Swig correctly parses the syntax for template<bool>,
|
||||
template<class T> and template<>.
|
||||
</P>
|
||||
<P>Ignored: Swig requires explicitly defined template class
|
||||
(%template directive) to export it to the target language.</P>
|
||||
<H2>Uniform method for computing return type of function objects
|
||||
[partially done]</H2>
|
||||
<P>The template function is introduced: std::result_of() which
|
||||
depends on decltype:
|
||||
</P>
|
||||
<PRE>template< class Obj >
|
||||
class calculus_ver2 {
|
||||
public:
|
||||
template< class Arg >
|
||||
typename std::result_of<Obj(Arg)>::type operator()( Arg& a ) const {
|
||||
return member(a);
|
||||
}
|
||||
private:
|
||||
Obj member;
|
||||
};</PRE><P>
|
||||
Swig correctly parses the result_of class.</P>
|
||||
<P>TODO: The return type (the result_of::type member) is not
|
||||
calculated by Swig. This needs a much more complex semantic parser.</P>
|
||||
<P>Done: Added testcase cpp11_result_of. R11534</P>
|
||||
</BODY>
|
||||
</HTML>
|
||||
942
Doc/Manual/CPlusPlus11.html
Normal file
942
Doc/Manual/CPlusPlus11.html
Normal file
|
|
@ -0,0 +1,942 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>SWIG and C++11</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
</head>
|
||||
|
||||
<body bgcolor="#ffffff">
|
||||
<H1><a name="CPlusPlus11"></a>7 SWIG and C++11</H1>
|
||||
<!-- INDEX -->
|
||||
<div class="sectiontoc">
|
||||
<ul>
|
||||
<li><a href="#CPlusPlus11_Introduction">Introduction</a>
|
||||
<li><a href="#CPlusPlus11_Core_language_changes">Core language changes</a>
|
||||
<ul>
|
||||
<li><a href="#CPlusPlus11_Rvalue_reference_and_move_semantics">Rvalue reference and move semantics</a>
|
||||
<li><a href="#CPlusPlus11_Generalized_constant_expressions">Generalized constant expressions</a>
|
||||
<li><a href="#CPlusPlus11_Extern_template">Extern template</a>
|
||||
<li><a href="#CPlusPlus11_Initializer_lists">Initializer lists</a>
|
||||
<li><a href="#CPlusPlus11_Uniform_initialization">Uniform initialization</a>
|
||||
<li><a href="#CPlusPlus11_Type_inference">Type inference</a>
|
||||
<li><a href="#CPlusPlus11_Range_based_for_loop">Range-based for-loop</a>
|
||||
<li><a href="#CPlusPlus11_Lambda_functions_and_expressions">Lambda functions and expressions</a>
|
||||
<li><a href="#CPlusPlus11_Alternate_function_syntax">Alternate function syntax</a>
|
||||
<li><a href="#CPlusPlus11_Object_construction_improvement">Object construction improvement</a>
|
||||
<li><a href="#CPlusPlus11_Null_pointer_constant">Null pointer constant</a>
|
||||
<li><a href="#CPlusPlus11_Strongly_typed_enumerations">Strongly typed enumerations</a>
|
||||
<li><a href="#CPlusPlus11_Double_angle_brackets">Double angle brackets</a>
|
||||
<li><a href="#CPlusPlus11_Explicit_conversion_operators">Explicit conversion operators</a>
|
||||
<li><a href="#CPlusPlus11_Alias_templates">Alias templates</a>
|
||||
<li><a href="#CPlusPlus11_Unrestricted_unions">Unrestricted unions</a>
|
||||
<li><a href="#CPlusPlus11_Variadic_templates">Variadic templates</a>
|
||||
<li><a href="#CPlusPlus11_New_string_literals">New string literals</a>
|
||||
<li><a href="#CPlusPlus11_User_defined_literals">User-defined literals</a>
|
||||
<li><a href="#CPlusPlus11_Thread_local_storage">Thread-local storage</a>
|
||||
<li><a href="#CPlusPlus11_Defaulting/deleting_of_standard_functions_on_C++_objects">Defaulting/deleting of standard functions on C++ objects</a>
|
||||
<li><a href="#CPlusPlus11_Type_long_long_int">Type long long int</a>
|
||||
<li><a href="#CPlusPlus11_Static_assertions">Static assertions</a>
|
||||
<li><a href="#CPlusPlus11_Allow_sizeof_to_work_on_members_of_classes_without_an_explicit_object">Allow sizeof to work on members of classes without an explicit object</a>
|
||||
</ul>
|
||||
<li><a href="#CPlusPlus11_Standard_library_changes">Standard library changes</a>
|
||||
<ul>
|
||||
<li><a href="#CPlusPlus11_Threading_facilities">Threading facilities</a>
|
||||
<li><a href="#CPlusPlus11_Tuple_types">Tuple types and hash tables</a>
|
||||
<li><a href="#CPlusPlus11_Regular_expressions">Regular expressions</a>
|
||||
<li><a href="#CPlusPlus11_General_purpose_smart_pointers">General-purpose smart pointers</a>
|
||||
<li><a href="#CPlusPlus11_Extensible_random_number_facility">Extensible random number facility</a>
|
||||
<li><a href="#CPlusPlus11_Wrapper_reference">Wrapper reference</a>
|
||||
<li><a href="#CPlusPlus11_Polymorphous_wrappers_for_function_objects">Polymorphous wrappers for function objects</a>
|
||||
<li><a href="#CPlusPlus11_Type_traits_for_metaprogramming">Type traits for metaprogramming</a>
|
||||
<li><a href="#CPlusPlus11_Uniform_method_for_computing_return_type_of_function_objects">Uniform method for computing return type of function objects</a>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- INDEX -->
|
||||
|
||||
|
||||
|
||||
<H2><a name="CPlusPlus11_Introduction"></a>7.1 Introduction</H2>
|
||||
|
||||
|
||||
<p>This chapter gives you a brief overview about the SWIG
|
||||
implementation of the C++11 standard. This part of SWIG is still a work in
|
||||
progress. Initial C++11 support for SWIG was written during the
|
||||
Google Summer of Code 2009 period.</p>
|
||||
<p>SWIG supports all the new C++ syntax changes with some minor limitations
|
||||
(decltype expressions, variadic templates number). Wrappers for the
|
||||
new STL types (unordered_ containers, result_of, tuples) are not supported
|
||||
yet.</p>
|
||||
|
||||
<H2><a name="CPlusPlus11_Core_language_changes"></a>7.2 Core language changes</H2>
|
||||
|
||||
|
||||
<H3><a name="CPlusPlus11_Rvalue_reference_and_move_semantics"></a>7.2.1 Rvalue reference and move semantics</H3>
|
||||
|
||||
|
||||
<p>SWIG correctly parses the new operator && the same as the reference operator &.</p>
|
||||
|
||||
<p>The wrapper for the following code is correctly produced:</p>
|
||||
<div class="code"><pre>
|
||||
class MyClass {
|
||||
MyClass(MyClass&& p) : ptr(p.ptr) {p.ptr = 0;}
|
||||
MyClass& operator=(MyClass&& p) {
|
||||
std::swap(ptr, p.ptr);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_Generalized_constant_expressions"></a>7.2.2 Generalized constant expressions</H3>
|
||||
|
||||
|
||||
<p>SWIG correctly parses the keyword <tt>constexpr</tt>, but ignores its functionality. Constant functions cannot be used as constants.</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
constexpr int myConstFunc() { return 10; }
|
||||
const int a = myConstFunc(); // results in error
|
||||
</pre></div>
|
||||
|
||||
<p>Users needs to use values or predefined constants when defining the new constant value:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
#define MY_CONST 10
|
||||
constexpr int myConstFunc() { return MY_CONST; }
|
||||
const int a = MY_CONST; // ok
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_Extern_template"></a>7.2.3 Extern template</H3>
|
||||
|
||||
|
||||
<p>SWIG correctly parses the keywords <tt>extern template</tt>. However, the explicit template instantiation is not used by SWIG, a <tt>%template</tt> is still required.</p>
|
||||
|
||||
|
||||
<div class="code"><pre>
|
||||
extern template class std::vector<MyClass>; // explicit instantiation
|
||||
|
||||
...
|
||||
|
||||
class MyClass {
|
||||
public:
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_Initializer_lists"></a>7.2.4 Initializer lists</H3>
|
||||
|
||||
<p>
|
||||
Initializer lists are very much a C++ compiler construct and are not very accessible from wrappers as
|
||||
they are intended for compile time initialization of classes using the special <tt>std::initializer_list</tt> type.
|
||||
SWIG detects usage of initializer lists and will emit a special informative warning each time one is used:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:33: Warning 476: Initialization using std::initializer_list.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Initializer lists usually appear in constructors but can appear in any function or method.
|
||||
They often appear in constructors which are overloaded with alternative approaches to initializing a class,
|
||||
such as the std container's push_back method for adding elements to a container.
|
||||
The recommended approach then is to simply ignore the initializer-list constructor, for example:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%ignore Container::Container(std::initializer_list<int>);
|
||||
class Container {
|
||||
public:
|
||||
Container(std::initializer_list<int>); // initializer-list constructor
|
||||
Container();
|
||||
void push_back(const int &);
|
||||
...
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>Alternatively you could modify the class and add another constructor for initialization by some other means,
|
||||
for example by a <tt>std::vector</tt>:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%include <std_vector.i>
|
||||
class Container {
|
||||
public:
|
||||
Container(const std::vector<int> &);
|
||||
Container(std::initializer_list<int>); // initializer-list constructor
|
||||
Container();
|
||||
void push_back(const int &);
|
||||
...
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>And then call this constructor from your target language, for example, in Python, the following will call the constructor taking the <tt>std::vector</tt>:</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
>>> c = Container( [1,2,3,4] )
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
If you are unable to modify the class being wrapped, consider ignoring the initializer-list constructor and using
|
||||
%extend to add in an alternative constructor:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%include <std_vector.i>
|
||||
%extend Container {
|
||||
Container(const std::vector<int> &elements) {
|
||||
Container *c = new Container();
|
||||
for (int element : elements)
|
||||
c->push_back(element);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
%ignore Container::Container(std::initializer_list<int>);
|
||||
|
||||
class Container {
|
||||
public:
|
||||
Container(std::initializer_list<int>); // initializer-list constructor
|
||||
Container();
|
||||
void push_back(const int &);
|
||||
...
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The above makes the wrappers look is as if the class had been declared as follows:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%include <std_vector.i>
|
||||
class Container {
|
||||
public:
|
||||
Container(const std::vector<int> &);
|
||||
// Container(std::initializer_list<int>); // initializer-list constructor (ignored)
|
||||
Container();
|
||||
void push_back(const int &);
|
||||
...
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
<tt>std::initializer_list</tt> is simply a container that can only be initialized at compile time.
|
||||
As it is just a C++ type, 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 as
|
||||
initializer lists are not designed to be constructed with a variable number of arguments at runtime.
|
||||
The example below is a very simple approach which ignores any parameters passed in and merely initializes
|
||||
with a fixed list of fixed integer values chosen at compile time:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%typemap(in) std::initializer_list<int> {
|
||||
$1 = {10, 20, 30, 40, 50};
|
||||
}
|
||||
class Container {
|
||||
public:
|
||||
Container(std::initializer_list<int>); // initializer-list constructor
|
||||
Container();
|
||||
void push_back(const int &);
|
||||
...
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Any attempt at passing in values from the target language will be ignored and replaced by <tt>{10, 20, 30, 40, 50}</tt>.
|
||||
Needless to say, this approach is very limited, but could be improved upon, but only slightly.
|
||||
A typemap could be written to map a fixed number of elements on to the <tt>std::initializer_list</tt>,
|
||||
but with values decided at runtime.
|
||||
The typemaps would be target language specific.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Note that the default typemap for <tt>std::initializer_list</tt> does nothing but issue the warning
|
||||
and hence any user supplied typemaps will override it and suppress the warning.
|
||||
</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_Uniform_initialization"></a>7.2.5 Uniform initialization</H3>
|
||||
|
||||
|
||||
<p>The curly brackets {} for member initialization are fully
|
||||
supported by SWIG:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
struct BasicStruct {
|
||||
int x;
|
||||
double y;
|
||||
};
|
||||
|
||||
struct AltStruct {
|
||||
AltStruct(int x, double y) : x_{x}, y_{y} {}
|
||||
|
||||
int x_;
|
||||
double y_;
|
||||
};
|
||||
|
||||
BasicStruct var1{5, 3.2}; // only fills the struct components
|
||||
AltStruct var2{2, 4.3}; // calls the constructor
|
||||
</pre></div>
|
||||
|
||||
<p>Uniform initialization does not affect usage from the target language, for example in Python:</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
>>> a = AltStruct(10, 142.15)
|
||||
>>> a.x_
|
||||
10
|
||||
>>> a.y_
|
||||
142.15
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_Type_inference"></a>7.2.6 Type inference</H3>
|
||||
|
||||
|
||||
<p>SWIG supports <tt>decltype()</tt> with some limitations. Single
|
||||
variables are allowed, however, expressions are not supported yet. For
|
||||
example, the following code will work:</p>
|
||||
<div class="code"><pre>
|
||||
int i;
|
||||
decltype(i) j;
|
||||
</pre></div>
|
||||
|
||||
<p>However, using an expression inside the decltype results in syntax error:</p>
|
||||
<div class="code"><pre>
|
||||
int i; int j;
|
||||
decltype(i+j) k; // syntax error
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_Range_based_for_loop"></a>7.2.7 Range-based for-loop</H3>
|
||||
|
||||
|
||||
<p>This feature is part of the implementation block only. SWIG
|
||||
ignores it.</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_Lambda_functions_and_expressions"></a>7.2.8 Lambda functions and expressions</H3>
|
||||
|
||||
|
||||
<p>SWIG correctly parses most of the Lambda functions syntax. For example:</p>
|
||||
<div class="code"><pre>
|
||||
auto val = [] { return something; };
|
||||
auto sum = [](int x, int y) { return x+y; };
|
||||
auto sum = [](int x, int y) -> int { return x+y; };
|
||||
</pre></div>
|
||||
|
||||
<p>The lambda functions are removed from the wrappers for now, because of the lack of support
|
||||
for closures (scope of the lambda functions) in the target languages.</p>
|
||||
|
||||
<p>
|
||||
Lambda functions used to create variables can also be parsed, but due to limited support of <tt>auto</tt> when
|
||||
the type is deduced from the expression, the variables are simply ignored.
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
auto six = [](int x, int y) { return x+y; }(4, 2);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Better support should be available in a later release.
|
||||
</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_Alternate_function_syntax"></a>7.2.9 Alternate function syntax</H3>
|
||||
|
||||
|
||||
<p>SWIG fully supports the new definition of functions. For example:</p>
|
||||
<div class="code"><pre>
|
||||
struct SomeStruct {
|
||||
int FuncName(int x, int y);
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>can now be written as in C++11:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
struct SomeStruct {
|
||||
auto FuncName(int x, int y) -> int;
|
||||
};
|
||||
|
||||
auto SomeStruct::FuncName(int x, int y) -> int {
|
||||
return x + y;
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
<p>The usage in the target languages remains the same, for example in Python:</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
>>> a = SomeStruct()
|
||||
>>> a.FuncName(10,5)
|
||||
15
|
||||
</pre></div>
|
||||
|
||||
<p>SWIG will also deal with type inference for the return type, as per the limitations described earlier. For example:</p>
|
||||
<div class="code"><pre>
|
||||
auto square(float a, float b) -> decltype(a);
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_Object_construction_improvement"></a>7.2.10 Object construction improvement</H3>
|
||||
|
||||
|
||||
<p>
|
||||
SWIG is able to handle constructor delegation, such as:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
class A {
|
||||
public:
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
|
||||
A() : A( 10 ) {}
|
||||
A(int aa) : A(aa, 20) {}
|
||||
A(int aa, int bb) : A(aa, bb, 30) {}
|
||||
A(int aa, int bb, int cc) { a=aa; b=bb; c=cc; }
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Constructor inheritance is parsed correctly, but the additional constructors are not currently added to the derived proxy class in the target language. Example is shown below:
|
||||
<!--
|
||||
The extra constructors provided by the <tt>using</tt> syntax will add the appropriate constructors into the target language proxy derived classes.
|
||||
In the example below a wrapper for the <tt>DerivedClass(int)</tt> is added to <tt>DerivedClass</tt>:
|
||||
-->
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
class BaseClass {
|
||||
public:
|
||||
BaseClass(int iValue);
|
||||
};
|
||||
|
||||
class DerivedClass: public BaseClass {
|
||||
public:
|
||||
using BaseClass::BaseClass; // Adds DerivedClass(int) constructor
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_Null_pointer_constant"></a>7.2.11 Null pointer constant</H3>
|
||||
|
||||
|
||||
<p>The <tt>nullptr</tt> constant is largely unimportant in wrappers. In the few places it has an effect, it is treated like <tt>NULL</tt>.</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_Strongly_typed_enumerations"></a>7.2.12 Strongly typed enumerations</H3>
|
||||
|
||||
|
||||
<p>SWIG parses the new <tt>enum class</tt> syntax and forward declarator for the enums:</p>
|
||||
<div class="code"><pre>
|
||||
enum class MyEnum : unsigned int;
|
||||
</pre></div>
|
||||
|
||||
<p>The strongly typed enumerations are treated the same as the ordinary and anonymous enums.
|
||||
This is because SWIG doesn't support nested classes. This is usually not a problem, however,
|
||||
there may be some name clashes. For example, the following code:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
class Color {
|
||||
enum class PrintingColors : unsigned int {
|
||||
Cyan, Magenta, Yellow, Black
|
||||
};
|
||||
|
||||
enum class BasicColors {
|
||||
Red, Green, Blue
|
||||
};
|
||||
|
||||
enum class AllColors {
|
||||
// produces warnings because of duplicate names
|
||||
Yellow, Orange, Red, Magenta, Blue, Cyan, Green, Pink, Black, White
|
||||
};
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>A workaround is to write these as a series of separated classes containing anonymous enums:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
class PrintingColors {
|
||||
enum : unsigned int {
|
||||
Cyan, Magenta, Yellow, Black
|
||||
};
|
||||
};
|
||||
|
||||
class BasicColors {
|
||||
enum : unsigned int {
|
||||
Red, Green, Blue
|
||||
};
|
||||
};
|
||||
|
||||
class AllColors {
|
||||
enum : unsigned int {
|
||||
Yellow, Orange, Red, Magenta, Blue, Cyan, Green, Pink, Black, White
|
||||
};
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_Double_angle_brackets"></a>7.2.13 Double angle brackets</H3>
|
||||
|
||||
|
||||
<p>SWIG correctly parses the symbols >> as closing the
|
||||
template block, if found inside it at the top level, or as the right
|
||||
shift operator >> otherwise.</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
std::vector<std::vector<int>> myIntTable;
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_Explicit_conversion_operators"></a>7.2.14 Explicit conversion operators</H3>
|
||||
|
||||
|
||||
<p>SWIG correctly parses the keyword <tt>explicit</tt> both for operators and constructors.
|
||||
For example:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
class U {
|
||||
public:
|
||||
int u;
|
||||
};
|
||||
|
||||
class V {
|
||||
public:
|
||||
int v;
|
||||
};
|
||||
|
||||
class TestClass {
|
||||
public:
|
||||
//implicit converting constructor
|
||||
TestClass( U const &val ) { t=val.u; }
|
||||
// explicit constructor
|
||||
explicit TestClass( V const &val ) { t=val.v; }
|
||||
|
||||
int t;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The usage of explicit constructors and operators is somehow specific to C++ when assigning the value
|
||||
of one object to another one of different type or translating one type to another. It requires both operator and function overloading features,
|
||||
which are not supported by the majority of SWIG target languages. Also the constructors and operators are not particulary useful in any
|
||||
SWIG target languages, because all use their own facilities (eg. classes Cloneable and Comparable in Java)
|
||||
to achieve particular copy and compare behaviours.
|
||||
</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_Alias_templates"></a>7.2.15 Alias templates</H3>
|
||||
|
||||
<p>
|
||||
The following is an example of an alias template:
|
||||
|
||||
<div class="code"><pre>
|
||||
template< typename T1, typename T2, int >
|
||||
class SomeType {
|
||||
T1 a;
|
||||
T2 b;
|
||||
int c;
|
||||
};
|
||||
|
||||
template< typename T2 >
|
||||
using TypedefName = SomeType<char*, T2, 5>;
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
These are partially supported as SWIG will parse these and identify them, however, they are ignored as they are not added to the type system. A warning such as the following is issued:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:13: Warning 342: The 'using' keyword in template aliasing is not fully supported yet.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Similarly for non-template type aliasing:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
using PFD = void (*)(double); // New introduced syntax
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
A warning will be issued:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:17: Warning 341: The 'using' keyword in type aliasing is not fully supported yet.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
||||
<p>The equivalent old style typedefs can be used as a workaround:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
typedef void (*PFD)(double); // The old style
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_Unrestricted_unions"></a>7.2.16 Unrestricted unions</H3>
|
||||
|
||||
|
||||
<p>SWIG fully supports any type inside a union even if it does not
|
||||
define a trivial constructor. For example, the wrapper for the following
|
||||
code correctly provides access to all members in the union:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
struct point {
|
||||
point() {}
|
||||
point(int x, int y) : x_(x), y_(y) {}
|
||||
int x_, y_;
|
||||
};
|
||||
|
||||
#include <new> // For placement 'new' in the constructor below
|
||||
union P {
|
||||
int z;
|
||||
double w;
|
||||
point p; // Illegal in C++03; legal in C++11.
|
||||
// Due to the point member, a constructor definition is required.
|
||||
P() {
|
||||
new(&p) point();
|
||||
}
|
||||
} p1;
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_Variadic_templates"></a>7.2.17 Variadic templates</H3>
|
||||
|
||||
|
||||
<p>SWIG supports the variadic templates syntax (inside the <>
|
||||
block, variadic class inheritance and variadic constructor and
|
||||
initializers) with some limitations. The following code is correctly parsed:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
template <typename... BaseClasses> class ClassName : public BaseClasses... {
|
||||
public:
|
||||
ClassName (BaseClasses&&... baseClasses) : BaseClasses(baseClasses)... {}
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
For now however, the <tt>%template</tt> directive only accepts one parameter substitution
|
||||
for the variable template parameters.
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%template(MyVariant1) ClassName<> // zero argument not supported yet
|
||||
%template(MyVariant2) ClassName<int> // ok
|
||||
%template(MyVariant3) ClassName<int, int> // too many arguments not supported yet
|
||||
</pre></div>
|
||||
|
||||
<p>Support for the variadic <tt>sizeof()</tt> function is correctly parsed:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
const int SIZE = sizeof...(ClassName<int, int>);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
In the above example <tt>SIZE</tt> is of course wrapped as a constant.
|
||||
</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_New_string_literals"></a>7.2.18 New string literals</H3>
|
||||
|
||||
|
||||
<p>SWIG supports unicode string constants and raw string literals.</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
// New string literals
|
||||
wstring aa = L"Wide string";
|
||||
const char *bb = u8"UTF-8 string";
|
||||
const char16_t *cc = u"UTF-16 string";
|
||||
const char32_t *dd = U"UTF-32 string";
|
||||
|
||||
// Raw string literals
|
||||
const char *xx = ")I'm an \"ascii\" \\ string.";
|
||||
const char *ee = R"XXX()I'm an "ascii" \ string.)XXX"; // same as xx
|
||||
wstring ff = LR"XXX(I'm a "raw wide" \ string.)XXX";
|
||||
const char *gg = u8R"XXX(I'm a "raw UTF-8" \ string.)XXX";
|
||||
const char16_t *hh = uR"XXX(I'm a "raw UTF-16" \ string.)XXX";
|
||||
const char32_t *ii = UR"XXX(I'm a "raw UTF-32" \ string.)XXX";
|
||||
</pre></div>
|
||||
|
||||
<p>Note: SWIG currently incorrectly parses the odd number of double quotes
|
||||
inside the string due to SWIG's C++ preprocessor.</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_User_defined_literals"></a>7.2.19 User-defined literals</H3>
|
||||
|
||||
|
||||
<p>
|
||||
SWIG parses the declaration of user-defined literals, that is, the <tt>operator "" _mysuffix()</tt> function syntax.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Some examples are the raw literal:
|
||||
</p>
|
||||
<div class="code"><pre>
|
||||
OutputType operator "" _myRawLiteral(const char * value);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
numeric cooked literals:
|
||||
</p>
|
||||
<div class="code"><pre>
|
||||
OutputType operator "" _mySuffixIntegral(unsigned long long);
|
||||
OutputType operator "" _mySuffixFloat(long double);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
and cooked string literals:
|
||||
</p>
|
||||
<div class="code"><pre>
|
||||
OutputType operator "" _mySuffix(const char * string_values, size_t num_chars);
|
||||
OutputType operator "" _mySuffix(const wchar_t * string_values, size_t num_chars);
|
||||
OutputType operator "" _mySuffix(const char16_t * string_values, size_t num_chars);
|
||||
OutputType operator "" _mySuffix(const char32_t * string_values, size_t num_chars);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Like other operators that SWIG parses, a warning is given about renaming the operator in order for it to be wrapped:
|
||||
</p>
|
||||
|
||||
<div class="shell"><pre>
|
||||
example.i:27: Warning 503: Can't wrap 'operator "" _myRawLiteral' unless renamed to a valid identifier.
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
If %rename is used, then it can be called like any other wrapped method.
|
||||
Currently you need to specify the full declaration including parameters for %rename:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%rename(MyRawLiteral) operator"" _myRawLiteral(const char * value);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Or if you just wish to ignore it altogether:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%ignore operator "" _myRawLiteral(const char * value);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Note that use of user-defined literals such as the following still give a syntax error:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
OutputType var1 = "1234"_suffix;
|
||||
OutputType var2 = 1234_suffix;
|
||||
OutputType var3 = 3.1416_suffix;
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_Thread_local_storage"></a>7.2.20 Thread-local storage</H3>
|
||||
|
||||
|
||||
<p>SWIG correctly parses the <tt>thread_local</tt> keyword. For example, variable
|
||||
reachable by the current thread can be defined as:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
struct A {
|
||||
static thread_local int val;
|
||||
};
|
||||
thread_local int global_val;
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The use of the <tt>thread_local</tt> storage specifier does not affect the wrapping process; it does not modify
|
||||
the wrapper code compared to when it is not specified.
|
||||
A variable will be thread local if accessed from different threads from the target language in the
|
||||
same way that it will be thread local if accessed from C++ code.
|
||||
</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_Defaulting/deleting_of_standard_functions_on_C++_objects"></a>7.2.21 Defaulting/deleting of standard functions on C++ objects</H3>
|
||||
|
||||
|
||||
<p>SWIG correctly parses the <tt>= delete</tt> and <tt>= default</tt>
|
||||
keywords. For example:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
struct NonCopyable {
|
||||
NonCopyable& operator=(const NonCopyable&) = delete; /* Removes operator= */
|
||||
NonCopyable(const NonCopyable&) = delete; /* Removed copy constructor */
|
||||
NonCopyable() = default; /* Explicitly allows the empty constructor */
|
||||
void *operator new(std::size_t) = delete; /* Removes new NonCopyable */
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>This feature is specific to C++ only. The defaulting/deleting is currently ignored, because SWIG
|
||||
automatically produces wrappers for special constructors and operators specific to the target language.</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_Type_long_long_int"></a>7.2.22 Type long long int</H3>
|
||||
|
||||
|
||||
<p>SWIG correctly parses and uses the new <tt>long long</tt> type already introduced in C99 some time ago.</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_Static_assertions"></a>7.2.23 Static assertions</H3>
|
||||
|
||||
|
||||
<p>SWIG correctly parses and calls the new <tt>static_assert</tt> function.</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
template <typename T>
|
||||
struct Check {
|
||||
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_Allow_sizeof_to_work_on_members_of_classes_without_an_explicit_object"></a>7.2.24 Allow sizeof to work on members of classes without an explicit object</H3>
|
||||
|
||||
|
||||
<p>SWIG correctly calls the sizeof() on types as well as on the
|
||||
objects. For example:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
struct A {
|
||||
int member;
|
||||
};
|
||||
|
||||
const int SIZE = sizeof(A::member); // does not work with C++03. Okay with C++11
|
||||
</pre></div>
|
||||
|
||||
<p>In Python:</p>
|
||||
<div class="targetlang"><pre>
|
||||
>>> SIZE
|
||||
8
|
||||
</pre></div>
|
||||
|
||||
<H2><a name="CPlusPlus11_Standard_library_changes"></a>7.3 Standard library changes</H2>
|
||||
|
||||
|
||||
<H3><a name="CPlusPlus11_Threading_facilities"></a>7.3.1 Threading facilities</H3>
|
||||
|
||||
|
||||
<p>SWIG does not currently wrap or use any of the new threading
|
||||
classes introduced (thread, mutex, locks, condition variables, task). The main reason is that
|
||||
SWIG target languages offer their own threading facilities that do not rely on C++.</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_Tuple_types"></a>7.3.2 Tuple types and hash tables</H3>
|
||||
|
||||
|
||||
<p>SWIG does not wrap the new tuple types and the unordered_ container classes yet. Variadic template support is working so it is possible to
|
||||
include the tuple header file; it is parsed without any problems.</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_Regular_expressions"></a>7.3.3 Regular expressions</H3>
|
||||
|
||||
|
||||
<p>SWIG does not wrap the new C++11 regular expressions classes, because the SWIG target languages use their own facilities for this.</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_General_purpose_smart_pointers"></a>7.3.4 General-purpose smart pointers</H3>
|
||||
|
||||
|
||||
<p>
|
||||
SWIG provides special smart pointer handling for <tt>std::tr1::shared_ptr</tt> in the same way it has support for <tt>boost::shared_ptr</tt>.
|
||||
There is no special smart pointer handling available for <tt>std::weak_ptr</tt> and <tt>std::unique_ptr</tt>.
|
||||
</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_Extensible_random_number_facility"></a>7.3.5 Extensible random number facility</H3>
|
||||
|
||||
|
||||
<p>This feature extends and standardizes the standard library only and does not effect the C++ language and SWIG.</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_Wrapper_reference"></a>7.3.6 Wrapper reference</H3>
|
||||
|
||||
|
||||
<p>The new ref and cref classes are used to instantiate a parameter as a reference of a template function. For example:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
void f( int &r ) { r++; }
|
||||
|
||||
// Template function.
|
||||
template< class F, class P > void g( F f, P t ) { f(t); }
|
||||
|
||||
int main() {
|
||||
int i = 0 ;
|
||||
g( f, i ) ; // 'g<void ( int &r ), int>' is instantiated
|
||||
// then 'i' will not be modified.
|
||||
cout << i << endl ; // Output -> 0
|
||||
|
||||
g( f, ref(i) ) ; // 'g<void(int &r),reference_wrapper<int>>' is instantiated
|
||||
// then 'i' will be modified.
|
||||
cout << i << endl ; // Output -> 1
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
<p>The ref and cref classes are not wrapped by SWIG because the SWIG target languages do not support referencing.</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_Polymorphous_wrappers_for_function_objects"></a>7.3.7 Polymorphous wrappers for function objects</H3>
|
||||
|
||||
|
||||
<p>
|
||||
SWIG supports functor classes in some languages in a very natural way.
|
||||
However nothing is provided yet for the new <tt>std::function</tt> template.
|
||||
SWIG will parse usage of the template like any other template.
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%rename(__call__) Test::operator(); // Default renaming used for Python
|
||||
|
||||
struct Test {
|
||||
bool operator()(int x, int y); // function object
|
||||
};
|
||||
|
||||
#include <functional>
|
||||
std::function<void (int, int)> pF = Test; // function template wrapper
|
||||
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Example of supported usage of the plain functor from Python is shown below.
|
||||
It does not involve <tt>std::function</tt>.
|
||||
</p>
|
||||
|
||||
<div class="targetlang">
|
||||
t = Test()
|
||||
b = t(1,2) # invoke C++ function object
|
||||
</pre></div>
|
||||
|
||||
<H3><a name="CPlusPlus11_Type_traits_for_metaprogramming"></a>7.3.8 Type traits for metaprogramming</H3>
|
||||
|
||||
|
||||
<p>The new C++ metaprogramming is useful at compile time and is aimed specifically for C++ development:</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
// First way of operating.
|
||||
template< bool B > struct algorithm {
|
||||
template< class T1, class T2 > int do_it( T1&, T2& ) { /*...*/ }
|
||||
};
|
||||
// Second way of operating.
|
||||
template<> struct algorithm<true> {
|
||||
template< class T1, class T2 > int do_it( T1, T2 ) { /*...*/ }
|
||||
};
|
||||
// Instantiating 'elaborate' will automatically instantiate the correct way to operate.
|
||||
template< class T1, class T2 > int elaborate( T1 A, T2 B ) {
|
||||
// Use the second way only if 'T1' is an integer and if 'T2' is
|
||||
// in floating point, otherwise use the first way.
|
||||
return algorithm< is_integral<T1>::value && is_floating_point<T2>::value >::do_it( A, B );
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
<p>SWIG correctly parses the template specialization, template types and values inside the <> block and the new helper functions: is_convertible, is_integral, is_const etc.
|
||||
However, SWIG still explicitly requires concrete types when using the <tt>%template</tt> directive, so the C++ metaprogramming features are not really of interest at runtime in the target languages.</p>
|
||||
|
||||
<H3><a name="CPlusPlus11_Uniform_method_for_computing_return_type_of_function_objects"></a>7.3.9 Uniform method for computing return type of function objects</H3>
|
||||
|
||||
|
||||
<p>SWIG does not wrap the new result_of class introduced in the <functional> header and map the result_of::type to the concrete type yet. For example:</p>
|
||||
<div class="code"><pre>
|
||||
%inline %{
|
||||
#include <functional>
|
||||
double square(double x) {
|
||||
return (x * x);
|
||||
}
|
||||
|
||||
template<class Fun, class Arg>
|
||||
typename std::result_of<Fun(Arg)>::type test_result_impl(Fun fun, Arg arg) {
|
||||
return fun(arg);
|
||||
}
|
||||
%}
|
||||
|
||||
%template(test_result) test_result_impl<double(*)(double), double>;
|
||||
%constant double (*SQUARE)(double) = square;
|
||||
</pre></div>
|
||||
|
||||
<p>will result in:</p>
|
||||
|
||||
<div class="targetlang"><pre>
|
||||
>>> test_result_impl(SQUARE, 5.0)
|
||||
<SWIG Object of type 'std::result_of< Fun(Arg) >::type *' at 0x7faf99ed8a50>
|
||||
</pre></div>
|
||||
|
||||
<p>Instead, please use <tt>decltype()</tt> where possible for now.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -4,7 +4,7 @@ Windows.html
|
|||
Scripting.html
|
||||
SWIG.html
|
||||
SWIGPlus.html
|
||||
Cpp0x.html
|
||||
CPlusPlus11.html
|
||||
Preprocessor.html
|
||||
Library.html
|
||||
Arguments.html
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ CPP_TEST_BROKEN += \
|
|||
overload_complicated \
|
||||
template_default_pointer \
|
||||
template_expr \
|
||||
$(CPP0X_TEST_BROKEN)
|
||||
$(CPP11_TEST_BROKEN)
|
||||
|
||||
|
||||
# Broken C test cases. (Can be run individually using: make testcase.ctest)
|
||||
|
|
@ -97,7 +97,7 @@ C_TEST_BROKEN += \
|
|||
|
||||
# C++ test cases. (Can be run individually using: make testcase.cpptest)
|
||||
CPP_TEST_CASES += \
|
||||
$(CPP0X_TEST_CASES) \
|
||||
$(CPP11_TEST_CASES) \
|
||||
abstract_access \
|
||||
abstract_inherit \
|
||||
abstract_inherit_ok \
|
||||
|
|
@ -476,41 +476,41 @@ CPP_TEST_CASES += \
|
|||
wallkw \
|
||||
wrapmacro
|
||||
|
||||
# C++0x test cases.
|
||||
CPP0X_TEST_CASES = \
|
||||
cpp0x_alternate_function_syntax \
|
||||
cpp0x_constexpr \
|
||||
cpp0x_decltype \
|
||||
cpp0x_default_delete \
|
||||
cpp0x_delegating_constructors \
|
||||
cpp0x_explicit_conversion_operators \
|
||||
cpp0x_function_objects \
|
||||
cpp0x_initializer_list \
|
||||
cpp0x_initializer_list_extend \
|
||||
cpp0x_lambda_functions \
|
||||
cpp0x_null_pointer_constant \
|
||||
cpp0x_raw_string_literals \
|
||||
cpp0x_rvalue_reference \
|
||||
cpp0x_rvalue_reference2 \
|
||||
cpp0x_rvalue_reference3 \
|
||||
cpp0x_sizeof_object \
|
||||
cpp0x_static_assert \
|
||||
cpp0x_strongly_typed_enumerations \
|
||||
cpp0x_template_double_brackets \
|
||||
cpp0x_template_explicit \
|
||||
cpp0x_template_typedefs \
|
||||
cpp0x_uniform_initialization \
|
||||
cpp0x_unrestricted_unions \
|
||||
cpp0x_userdefined_literals \
|
||||
cpp0x_variadic_templates
|
||||
# C++11 test cases.
|
||||
CPP11_TEST_CASES = \
|
||||
cpp11_alternate_function_syntax \
|
||||
cpp11_constexpr \
|
||||
cpp11_decltype \
|
||||
cpp11_default_delete \
|
||||
cpp11_delegating_constructors \
|
||||
cpp11_explicit_conversion_operators \
|
||||
cpp11_function_objects \
|
||||
cpp11_initializer_list \
|
||||
cpp11_initializer_list_extend \
|
||||
cpp11_lambda_functions \
|
||||
cpp11_null_pointer_constant \
|
||||
cpp11_raw_string_literals \
|
||||
cpp11_rvalue_reference \
|
||||
cpp11_rvalue_reference2 \
|
||||
cpp11_rvalue_reference3 \
|
||||
cpp11_sizeof_object \
|
||||
cpp11_static_assert \
|
||||
cpp11_strongly_typed_enumerations \
|
||||
cpp11_template_double_brackets \
|
||||
cpp11_template_explicit \
|
||||
cpp11_template_typedefs \
|
||||
cpp11_uniform_initialization \
|
||||
cpp11_unrestricted_unions \
|
||||
cpp11_userdefined_literals \
|
||||
cpp11_variadic_templates
|
||||
|
||||
# cpp0x_inheriting_constructors \ # not supported by gcc-4.7
|
||||
# cpp0x_hash_tables \ # not fully implemented yet
|
||||
# cpp0x_result_of \ # SWIG does not support
|
||||
# cpp0x_thread_local \ # needs gcc-4.8
|
||||
# cpp11_inheriting_constructors \ # not supported by gcc-4.7
|
||||
# cpp11_hash_tables \ # not fully implemented yet
|
||||
# cpp11_result_of \ # SWIG does not support
|
||||
# cpp11_thread_local \ # needs gcc-4.8
|
||||
|
||||
# Broken C++0x test cases.
|
||||
CPP0X_TEST_BROKEN =
|
||||
# Broken C++11 test cases.
|
||||
CPP11_TEST_BROKEN =
|
||||
|
||||
#
|
||||
# Put all the heavy STD/STL cases here, where they can be skipped if needed
|
||||
|
|
@ -626,7 +626,7 @@ all: $(NOT_BROKEN_TEST_CASES) $(BROKEN_TEST_CASES)
|
|||
|
||||
check: $(NOT_BROKEN_TEST_CASES)
|
||||
|
||||
check-cpp11: $(CPP0X_TEST_CASES:=.cpptest)
|
||||
check-cpp11: $(CPP11_TEST_CASES:=.cpptest)
|
||||
|
||||
# partialcheck target runs SWIG only, ie no compilation or running of tests (for a subset of languages)
|
||||
partialcheck:
|
||||
|
|
|
|||
18
Examples/test-suite/cpp11_alternate_function_syntax.i
Normal file
18
Examples/test-suite/cpp11_alternate_function_syntax.i
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/* This testcase checks whether SWIG correctly uses the new alternate functions
|
||||
declarations and definitions introduced in C++11. */
|
||||
%module cpp11_alternate_function_syntax
|
||||
|
||||
%inline %{
|
||||
struct SomeStruct {
|
||||
int addNormal(int x, int y);
|
||||
auto addAlternate(int x, int y) -> int;
|
||||
};
|
||||
|
||||
auto SomeStruct::addAlternate(int x, int y) -> int {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
int SomeStruct::addNormal(int x, int y) {
|
||||
return x + y;
|
||||
}
|
||||
%}
|
||||
12
Examples/test-suite/cpp11_constexpr.i
Normal file
12
Examples/test-suite/cpp11_constexpr.i
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/* This interface tests whether SWIG supports the new "constexpr" keyword
|
||||
introduced by C++11.
|
||||
*/
|
||||
%module cpp11_constexpr
|
||||
|
||||
%inline %{
|
||||
class TestClass {
|
||||
public:
|
||||
constexpr int func() { return 10; }
|
||||
};
|
||||
%}
|
||||
|
||||
19
Examples/test-suite/cpp11_decltype.i
Normal file
19
Examples/test-suite/cpp11_decltype.i
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/* This testcase checks whether SWIG correctly uses the new 'decltype()'
|
||||
introduced in C++11.
|
||||
*/
|
||||
%module cpp11_decltype
|
||||
|
||||
%inline %{
|
||||
class A {
|
||||
public:
|
||||
int i;
|
||||
decltype(i) j;
|
||||
|
||||
auto foo( decltype(i) a ) -> decltype(i) {
|
||||
if (a==5)
|
||||
return 10;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
%}
|
||||
24
Examples/test-suite/cpp11_default_delete.i
Normal file
24
Examples/test-suite/cpp11_default_delete.i
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* This testcase checks whether SWIG correctly parses the default and delete
|
||||
keywords which keep or remove default C++ object construction functions. */
|
||||
%module cpp11_default_delete
|
||||
|
||||
%{
|
||||
#include <stdlib.h>
|
||||
|
||||
class NonCopyable {
|
||||
public:
|
||||
NonCopyable& operator=(const NonCopyable&) = delete; /* Removes operator= */
|
||||
NonCopyable(const NonCopyable&) = delete; /* Removed copy constructor */
|
||||
NonCopyable() = default; /* Explicitly allows the empty constructor */
|
||||
void *operator new(size_t) = delete; /* Removes new NonCopyable */
|
||||
};
|
||||
|
||||
struct A1 {
|
||||
void f(int i);
|
||||
void f(double i) = delete; /* Don't cast double to int. Compiler returns an error */
|
||||
};
|
||||
struct A2 {
|
||||
void f(int i);
|
||||
template<class T> void f(T) = delete; /* Only accept int */
|
||||
};
|
||||
%}
|
||||
18
Examples/test-suite/cpp11_delegating_constructors.i
Normal file
18
Examples/test-suite/cpp11_delegating_constructors.i
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/* This test checks whether SWIG correctly parses the new delegating
|
||||
constructors.
|
||||
*/
|
||||
%module cpp11_delegating_constructors
|
||||
|
||||
%inline %{
|
||||
class A {
|
||||
public:
|
||||
int a;
|
||||
int b;
|
||||
int c;
|
||||
|
||||
A() : A( 10 ) {}
|
||||
A(int aa) : A(aa, 20) {}
|
||||
A(int aa, int bb) : A(aa, bb, 30) {}
|
||||
A(int aa, int bb, int cc) { a=aa; b=bb; c=cc; }
|
||||
};
|
||||
%}
|
||||
28
Examples/test-suite/cpp11_explicit_conversion_operators.i
Normal file
28
Examples/test-suite/cpp11_explicit_conversion_operators.i
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* This interface checks whether SWIG correctly compiles the new
|
||||
explicit conversion operators feature introduced in C++11.
|
||||
*/
|
||||
%module cpp11_explicit_conversion_operators
|
||||
|
||||
%inline %{
|
||||
|
||||
class U {
|
||||
public:
|
||||
int u;
|
||||
};
|
||||
|
||||
class V {
|
||||
public:
|
||||
int v;
|
||||
};
|
||||
|
||||
class TestClass {
|
||||
public:
|
||||
//implicit converting constructor
|
||||
TestClass( U const &val ) { t=val.u; }
|
||||
// explicit constructor
|
||||
explicit TestClass( V const &val ) { t=val.v; }
|
||||
|
||||
int t;
|
||||
};
|
||||
%}
|
||||
|
||||
35
Examples/test-suite/cpp11_function_objects.i
Normal file
35
Examples/test-suite/cpp11_function_objects.i
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/* This testcase checks whether SWIG correctly parses function objects
|
||||
and the templates for the functions (signature).
|
||||
Function objects are objects which overload the operator() function.
|
||||
The std::function does not provide any seamless support in the target languages yet.
|
||||
*/
|
||||
%module cpp11_function_objects
|
||||
|
||||
%rename(__call__) Test::operator();
|
||||
|
||||
%inline %{
|
||||
struct Test {
|
||||
int value;
|
||||
|
||||
void operator()(int x, int y) {
|
||||
value=x+y;
|
||||
}
|
||||
Test() : value(0) {}
|
||||
} test;
|
||||
|
||||
#include <functional>
|
||||
std::function<void ( int, int )> pF = test;
|
||||
|
||||
int testit1(Test new_test, int a, int b) {
|
||||
pF = new_test;
|
||||
pF(a, b);
|
||||
return new_test.value;
|
||||
}
|
||||
|
||||
int testit2(int a, int b) {
|
||||
test(a, b);
|
||||
return test.value;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
43
Examples/test-suite/cpp11_hash_tables.i
Normal file
43
Examples/test-suite/cpp11_hash_tables.i
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* This testcase checks the new wrappers for the new unordered_ STL types
|
||||
introduced in C++11. */
|
||||
%module cpp11_hash_tables
|
||||
|
||||
%inline %{
|
||||
#include <set>
|
||||
//#include <map>
|
||||
#include <unordered_set>
|
||||
//#include <unordered_map>
|
||||
%}
|
||||
|
||||
%include "std_set.i"
|
||||
//%include "std_map.i"
|
||||
%include "std_unordered_set.i"
|
||||
//%include "std_unordered_map.i"
|
||||
%template (SetInt) std::set<int>;
|
||||
//%template (MapIntInt) std::map<int, int>;
|
||||
%template (UnorderedSetInt) std::unordered_set<int>;
|
||||
//%template (UnorderedMapIntInt) std::unordered_map<int, int>;
|
||||
|
||||
%inline %{
|
||||
using namespace std;
|
||||
|
||||
class MyClass {
|
||||
public:
|
||||
set<int> getSet() { return _set; }
|
||||
void addSet(int elt) { _set.insert(_set.begin(), elt); }
|
||||
// map<int, int> getMap() { return _map; }
|
||||
// void addMap(int elt1, int elt2) { _map.insert(make_pair(elt1, elt2)); }
|
||||
|
||||
unordered_set<int> getUnorderedSet() { return _unordered_set; }
|
||||
void addUnorderedSet(int elt) { _unordered_set.insert(_unordered_set.begin(), elt); }
|
||||
// unordered_map<int, int> getUnorderedMap() { return _unordered_map; }
|
||||
// void addUnorderedMap(int elt1, int elt2) { _unordered_map.insert(make_pair(elt1, elt2)); }
|
||||
private:
|
||||
set<int> _set;
|
||||
// map<int, int> _map;
|
||||
|
||||
unordered_set<int> _unordered_set;
|
||||
// unordered_map<int, int> _unordered_map;
|
||||
};
|
||||
%}
|
||||
|
||||
18
Examples/test-suite/cpp11_inheriting_constructors.i
Normal file
18
Examples/test-suite/cpp11_inheriting_constructors.i
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/* This test checks whether SWIG correctly parses the new constructor
|
||||
inheritance.
|
||||
*/
|
||||
%module cpp11_inheriting_constructors
|
||||
|
||||
%inline %{
|
||||
class BaseClass {
|
||||
private:
|
||||
int _val;
|
||||
public:
|
||||
BaseClass(int iValue) { _val = iValue; }
|
||||
};
|
||||
|
||||
class DerivedClass: public BaseClass {
|
||||
public:
|
||||
using BaseClass::BaseClass; // Adds DerivedClass(int) constructor
|
||||
};
|
||||
%}
|
||||
34
Examples/test-suite/cpp11_initializer_list.i
Normal file
34
Examples/test-suite/cpp11_initializer_list.i
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* This testcase shows a few simple ways to deal with the new initializer_list
|
||||
introduced in C++11. */
|
||||
%module cpp11_initializer_list
|
||||
|
||||
%warnfilter(SWIGWARN_TYPEMAP_INITIALIZER_LIST) B::B;
|
||||
%ignore A::A(std::initializer_list<int>);
|
||||
%ignore B::method;
|
||||
|
||||
%typemap(in) std::initializer_list<const char *> {
|
||||
$1 = {"Ab", "Fab"};
|
||||
}
|
||||
|
||||
%inline %{
|
||||
#include <initializer_list>
|
||||
|
||||
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) {}
|
||||
};
|
||||
class C {
|
||||
public:
|
||||
C(std::initializer_list<const char *>) {}
|
||||
C() {}
|
||||
};
|
||||
%}
|
||||
|
||||
29
Examples/test-suite/cpp11_initializer_list_extend.i
Normal file
29
Examples/test-suite/cpp11_initializer_list_extend.i
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/* This testcase shows how to replace std_initializer_list with std_vector. */
|
||||
|
||||
%module cpp11_initializer_list_extend
|
||||
|
||||
%ignore Container::Container(std::initializer_list<int>);
|
||||
%include <std_vector.i>
|
||||
%template(VectorInt) std::vector<int>;
|
||||
|
||||
%extend Container {
|
||||
Container(const std::vector<int> &elements) {
|
||||
Container *c = new Container();
|
||||
for (int element : elements)
|
||||
c->push_back(element);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
%inline %{
|
||||
#include <initializer_list>
|
||||
|
||||
class Container {
|
||||
public:
|
||||
Container(std::initializer_list<int>) {}
|
||||
Container() {}
|
||||
void push_back(const int&) {}
|
||||
};
|
||||
%}
|
||||
|
||||
110
Examples/test-suite/cpp11_lambda_functions.i
Normal file
110
Examples/test-suite/cpp11_lambda_functions.i
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/* This testcase checks whether SWIG correctly parses the lambda expressions
|
||||
and closure syntax introduced in C++11.
|
||||
SWIG supports only lambda syntax and doesn't produce any wrapper code for
|
||||
this.
|
||||
*/
|
||||
%module cpp11_lambda_functions
|
||||
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda1;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda2;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda3;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda4;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda5;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda6;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda7;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda8;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda9;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda10;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda11;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda12;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda13;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda14;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda15;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda16;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda17;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) lambda18;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) Space1::lambda19;
|
||||
%warnfilter(SWIGWARN_CPP11_LAMBDA) Space1::Space2::lambda20;
|
||||
|
||||
%inline %{
|
||||
/* Defined lambda function with return value. */
|
||||
auto lambda1 = [](int x, int y) -> int { return x+y; };
|
||||
|
||||
/* Defined lambda function without return value.
|
||||
Return value is calculated by compiler, if the function contains a
|
||||
single statement "return expr;". */
|
||||
auto lambda2 = [](int x, int y) { return x+y; };
|
||||
|
||||
auto lambda3 = [&](int x, int y) { return x+y; };
|
||||
auto lambda4 = [=](int x, int y) { return x+y; };
|
||||
int thing = 0;
|
||||
#ifdef SWIG
|
||||
// Not strictly correct as captured variables should have non-automatic storage duration, ie shouldn't capture globals. gcc-4.7 warns about this, but we check that SWIG can parse this anyway.
|
||||
auto lambda5 = [=,&thing]() { return thing; };
|
||||
#else
|
||||
auto lambda5 = [=]() { return thing; };
|
||||
#endif
|
||||
|
||||
void fn() {
|
||||
int stuff = 0;
|
||||
auto lambdaxxxx = [=,&stuff]() { return thing; };
|
||||
}
|
||||
auto lambda6 = [] (int a, int b) mutable { return a + b; };
|
||||
auto lambda7 = [] (int x, int y) -> int { return x+y; };
|
||||
auto lambda8 = [] (int x, int y) throw() -> int { return x+y; };
|
||||
auto lambda9 = [] (int x, int y) mutable throw() -> int { return x+y; };
|
||||
auto lambda10 = [] (int x, int y) throw(int) { return x+y; };
|
||||
auto lambda11 = [] (int x, int y) mutable throw(int) { return x+y; };
|
||||
auto lambda12 = [] (int a, int b) { return a + b; }(1, 2);
|
||||
auto lambda13 = [] (int a, int b) mutable { return a + b; }(1, 2);
|
||||
auto lambda14 = [] () throw () {};
|
||||
auto lambda15 = [] () mutable throw () {};
|
||||
auto lambda16 = [] { return thing; };
|
||||
auto lambda17 = [] { return thing; }();
|
||||
constexpr auto lambda18 = [] (int x, int y) mutable throw(int) { return x+y; };
|
||||
|
||||
namespace Space1 {
|
||||
constexpr auto lambda19 = [] (int x, int y) mutable throw(int) { return x+y; };
|
||||
namespace Space2 {
|
||||
constexpr auto lambda20 = [] (int x, int y) mutable throw(int) { return x+y; };
|
||||
}
|
||||
}
|
||||
|
||||
int runLambda1() {
|
||||
return lambda1(5,6);
|
||||
}
|
||||
|
||||
int runLambda2() {
|
||||
return lambda2(5,6);
|
||||
}
|
||||
|
||||
int runLambda3() {
|
||||
return lambda3(5,6);
|
||||
}
|
||||
|
||||
int runLambda4() {
|
||||
return lambda4(5,6);
|
||||
}
|
||||
|
||||
int runLambda5() {
|
||||
thing++;
|
||||
return lambda5();
|
||||
}
|
||||
|
||||
/* Inline defined lambda function. */
|
||||
int runLambdaInline() {
|
||||
auto myLambda = [](int x, int y) { return x+y; };
|
||||
return myLambda(5,6);
|
||||
}
|
||||
%}
|
||||
|
||||
%{
|
||||
// TODO
|
||||
struct LambdaStruct {
|
||||
static constexpr auto lambda_struct1 = [=]() { return thing; };
|
||||
};
|
||||
int(*lambda101notauto)(int, int) = [] (int a, int b) { return a + b; };
|
||||
int lambda102 = [] (int a, int b) mutable { return a + b; }(1, 2);
|
||||
void lambda_init(int = ([=]{ return 0; })());
|
||||
%}
|
||||
|
||||
22
Examples/test-suite/cpp11_null_pointer_constant.i
Normal file
22
Examples/test-suite/cpp11_null_pointer_constant.i
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* This testcase checks whether SWIG correctly treats the new nullptr_t
|
||||
constant introduced in C++11.
|
||||
*/
|
||||
|
||||
%module cpp11_null_pointer_constant
|
||||
|
||||
%feature("autodoc") A::NullPtrMethod; // Triggers conversion of nullptr to None, nil etc in target language
|
||||
%feature("compactdefaultargs") A::NullPtrMethod;
|
||||
|
||||
%inline %{
|
||||
|
||||
const int *const MyIntegerPtr = nullptr;
|
||||
|
||||
class A {
|
||||
public:
|
||||
A() : _myA(nullptr) { }
|
||||
|
||||
A *_myA;
|
||||
|
||||
void NullPtrMethod(double *ptr = nullptr) {}
|
||||
};
|
||||
%}
|
||||
59
Examples/test-suite/cpp11_raw_string_literals.i
Normal file
59
Examples/test-suite/cpp11_raw_string_literals.i
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/* This module tests whether SWIG correctly parses:
|
||||
- ordinary strings (char_t)
|
||||
- L wide strings (wchar_t)
|
||||
- u8 unicode8 strings (char_t)
|
||||
- u unicode16 strings (char16_t)
|
||||
- U unicode32 strings (char32_t)
|
||||
|
||||
This module also tests whether SWIG correctly parses custom string delimiters.
|
||||
*/
|
||||
%module cpp11_raw_string_literals
|
||||
%warnfilter(SWIGWARN_TYPEMAP_CHARLEAK_MSG) bb;
|
||||
%warnfilter(SWIGWARN_TYPEMAP_CHARLEAK_MSG) ee;
|
||||
%warnfilter(SWIGWARN_TYPEMAP_CHARLEAK_MSG) gg;
|
||||
%warnfilter(SWIGWARN_TYPEMAP_CHARLEAK_MSG) xx;
|
||||
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc;
|
||||
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) dd;
|
||||
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) hh;
|
||||
%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ii;
|
||||
|
||||
%include <std_wstring.i>
|
||||
|
||||
%inline %{
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int L = 100;
|
||||
int u8 = 100;
|
||||
int u = 100;
|
||||
struct UStruct {
|
||||
static const int U = 100;
|
||||
};
|
||||
|
||||
int R = 100;
|
||||
int LR = 100;
|
||||
int u8R = 100;
|
||||
int uR = 100;
|
||||
struct URStruct {
|
||||
static const int UR = 100;
|
||||
};
|
||||
|
||||
// New string literals
|
||||
wstring aa = L"Wide string";
|
||||
const char *bb = u8"UTF-8 string";
|
||||
const char16_t *cc = u"UTF-16 string";
|
||||
const char32_t *dd = U"UTF-32 string";
|
||||
%}
|
||||
|
||||
/* Raw string literals */
|
||||
%inline %{
|
||||
const char *xx = ")I'm an \"ascii\" \\ string.";
|
||||
const char *ee = R"XXX()I'm an "ascii" \ string.)XXX";
|
||||
wstring ff = LR"XXX(I'm a "raw wide" \ string.)XXX";
|
||||
const char *gg = u8R"XXX(I'm a "raw UTF-8" \ string.)XXX";
|
||||
const char16_t *hh = uR"XXX(I'm a "raw UTF-16" \ string.)XXX";
|
||||
const char32_t *ii = UR"XXX(I'm a "raw UTF-32" \ string.)XXX";
|
||||
%}
|
||||
|
||||
20
Examples/test-suite/cpp11_result_of.i
Normal file
20
Examples/test-suite/cpp11_result_of.i
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* This testcase checks whether SWIG correctly uses the new result_of class
|
||||
and its templating capabilities introduced in C++11. */
|
||||
%module cpp11_result_of
|
||||
|
||||
%inline %{
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
||||
double square(double x) {
|
||||
return (x * x);
|
||||
}
|
||||
|
||||
template<class Fun, class Arg>
|
||||
typename std::result_of<Fun(Arg)>::type test_result_impl(Fun fun, Arg arg) {
|
||||
return fun(arg);
|
||||
}
|
||||
%}
|
||||
|
||||
%template(test_result) test_result_impl<double(*)(double), double>;
|
||||
%constant double (*SQUARE)(double) = square;
|
||||
22
Examples/test-suite/cpp11_rvalue_reference.i
Normal file
22
Examples/test-suite/cpp11_rvalue_reference.i
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* This testcase checks whether SWIG correctly parses the double ampersand &&
|
||||
move operator which is currently mapped to the reference & operator. */
|
||||
%module cpp11_rvalue_reference
|
||||
|
||||
%inline %{
|
||||
#include <utility>
|
||||
class A {
|
||||
public:
|
||||
int getAcopy() { return _a; }
|
||||
int *getAptr() { return &_a; }
|
||||
int &getAref() { return _a; }
|
||||
int &&getAmove() { return std::move(_a); }
|
||||
|
||||
void setAcopy(int a) { _a = a; }
|
||||
void setAptr(int *a) { _a = *a; }
|
||||
void setAref(int &a) { _a = a; }
|
||||
void setAmove(int &&a) { _a = a; }
|
||||
|
||||
private:
|
||||
int _a;
|
||||
};
|
||||
%}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue