diff --git a/.gitignore b/.gitignore
index 25cac8fec..8d72cea5d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,7 +3,7 @@
*.class
# Editor files and various other junk
-*.sw?
+.*.sw?
*.bak
*.log
.DS_Store
@@ -70,7 +70,6 @@ Examples/Makefile
Examples/guile/Makefile
Examples/test-suite/*/Makefile
Examples/xml/Makefile
-Lib/ocaml/swigp4.ml
/Makefile
Source/Include/stamp-h1
Source/Include/swigconfig.h
diff --git a/.travis.yml b/.travis.yml
index 2664890d4..6f21c4755 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,17 +1,67 @@
language: c
compiler:
- gcc
-before_script:
- - "sudo apt-get install rlwrap"
- - "sudo apt-get install python-software-properties"
- - "echo 'yes' | sudo add-apt-repository ppa:chris-lea/node.js"
- - "sudo apt-get update"
- - "sudo apt-get install nodejs"
- - "sudo npm install -g node-gyp"
- - "sudo apt-get install libv8-dev"
- - "sudo apt-get install libwebkitgtk-dev"
- - "./autogen.sh && ./configure && make"
+env:
+ - SWIGLANG=
+matrix:
+ include:
+ - compiler: gcc
+ env: SWIGLANG=csharp
+ - compiler: gcc
+ env: SWIGLANG=go
+ - compiler: gcc
+ env: SWIGLANG=guile
+ - compiler: gcc
+ env: SWIGLANG=java
+ - compiler: gcc
+ env: SWIGLANG=javascript
+ - compiler: gcc
+ env: SWIGLANG=lua
+ - compiler: gcc
+ env: SWIGLANG=octave SWIGJOBS=-j4
+ - compiler: gcc
+ env: SWIGLANG=perl5
+ - compiler: gcc
+ env: SWIGLANG=php
+ - compiler: gcc
+ env: SWIGLANG=python
+ - compiler: gcc
+ env: SWIGLANG=python PY3=1
+ - compiler: gcc
+ env: SWIGLANG=python PY3=1 VER=3.3
+ - compiler: gcc
+ env: SWIGLANG=ruby
+ - compiler: gcc
+ env: SWIGLANG=tcl
+ allow_failures:
+ # None
+before_install:
+ - date -u
+ - lsb_release -a
+ - uname -a
+ - sudo apt-get -qq update
+ - time sudo apt-get -qq install libboost-dev
+ - if test -z "$SWIGLANG"; then sudo apt-get -qq install yodl; fi
+ - if test "$SWIGLANG" = "csharp"; then sudo apt-get -qq install mono-devel; fi
+ - if test "$SWIGLANG" = "go"; then go env | sed -e 's/^/export /' > goenvsetup && source goenvsetup && rm -f goenvsetup; fi # Until configure.ac is fixed
+ - if test "$SWIGLANG" = "javascript"; then sudo apt-get install -qq rlwrap python-software-properties && echo 'yes' | sudo add-apt-repository ppa:chris-lea/node.js && sudo apt-get -qq update && sudo apt-get install -qq nodejs libv8-dev libwebkitgtk-dev && sudo npm install -g node-gyp; fi
+ - if test "$SWIGLANG" = "guile"; then sudo apt-get -qq install guile-2.0-dev; fi
+ - if test "$SWIGLANG" = "lua"; then sudo apt-get -qq install lua5.1 liblua5.1-dev; fi
+ - if test "$SWIGLANG" = "octave"; then sudo apt-get -qq install octave3.2 octave3.2-headers; fi
+ - if test "$SWIGLANG" = "php"; then sudo apt-get install php5-cli php5-dev; fi
+ - if test "$SWIGLANG" = "python" -a "$PY3" -a -z "$VER"; then sudo apt-get install -qq python3-dev; fi
+ - if test "$SWIGLANG" = "python" -a "$VER"; then sudo add-apt-repository -y ppa:fkrull/deadsnakes && sudo apt-get -qq update && sudo apt-get -qq install python${VER}-dev; fi
+ - if test "$SWIGLANG" = "tcl"; then sudo apt-get -qq install tcl8.4-dev; fi
script:
- - "make SMOKE=1 check-javascript-test-suite"
- - "make SMOKE=1 ENGINE=jsc check-javascript-test-suite"
- - "make SMOKE=1 ENGINE=v8 check-javascript-test-suite"
+ - ./autogen.sh && ./configure
+ - make -s $SWIGJOBS
+ - ./swig -version && ./swig -pcreversion
+ - if test -z "$SWIGLANG"; then make -s $SWIGJOBS check-ccache; fi
+ - if test -z "$SWIGLANG"; then make -s $SWIGJOBS check-errors-test-suite; fi
+ - if test -z "$SWIGLANG"; then sudo make -s install && swig -version && ccache-swig -V; fi
+ - if test -n "$SWIGLANG"; then make -s check-$SWIGLANG-version; fi
+ - if test -n "$SWIGLANG"; then make -k $SWIGJOBS check-$SWIGLANG-examples; fi
+ - if test -n "$SWIGLANG"; then make -k $SWIGJOBS check-$SWIGLANG-test-suite; fi
+branches:
+ only:
+ - master
diff --git a/ANNOUNCE b/ANNOUNCE
index 1c3297a5c..90cc9ba24 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,8 +1,8 @@
-*** ANNOUNCE: SWIG 2.0.10 (in progress) ***
+*** ANNOUNCE: SWIG 3.0.0 (in progress) ***
http://www.swig.org
-We're pleased to announce SWIG-2.0.10, the latest SWIG release.
+We're pleased to announce SWIG-3.0.0, the latest SWIG release.
What is SWIG?
=============
@@ -21,11 +21,11 @@ Availability
============
The release is available for download on Sourceforge at
- http://prdownloads.sourceforge.net/swig/swig-2.0.10.tar.gz
+ http://prdownloads.sourceforge.net/swig/swig-3.0.0.tar.gz
A Windows version is also available at
- http://prdownloads.sourceforge.net/swig/swigwin-2.0.10.zip
+ http://prdownloads.sourceforge.net/swig/swigwin-3.0.0.zip
Please report problems with this release to the swig-devel mailing list,
details at http://www.swig.org/mail.html.
diff --git a/CCache/ccache.h b/CCache/ccache.h
index 3c3e22311..dcbb03f0c 100644
--- a/CCache/ccache.h
+++ b/CCache/ccache.h
@@ -200,6 +200,8 @@ typedef int (*COMPAR_FN_T)(const void *, const void *);
/* mkstemp() on some versions of cygwin don't handle binary files, so
override */
+/* Seems okay in Cygwin 1.7.0
#ifdef __CYGWIN__
#undef HAVE_MKSTEMP
#endif
+*/
diff --git a/CCache/util.c b/CCache/util.c
index bba232492..66f9823b9 100644
--- a/CCache/util.c
+++ b/CCache/util.c
@@ -82,7 +82,7 @@ void copy_fd(int fd_in, int fd_out)
#ifndef HAVE_MKSTEMP
/* cheap and nasty mkstemp replacement */
-static int mkstemp(char *template)
+int mkstemp(char *template)
{
mktemp(template);
return open(template, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
diff --git a/CHANGES b/CHANGES
index 488bf7286..db9adab03 100644
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,209 @@ SWIG (Simplified Wrapper and Interface Generator)
See the CHANGES.current file for changes in the current version.
See the RELEASENOTES file for a summary of changes in each release.
+
+Version 2.0.12 (9 Feb 2014)
+===========================
+
+2014-01-16: wsfulton
+ [PHP] Fix compilation error in ZTS mode (64 bit windows) due to incorrect placement
+ of TSRMLS_FETCH() in SWIG_Php_GetModule() as reported by Mark Dawson-Butterworth.
+
+2014-01-13: kwwette
+ [Octave] update support to Octave version 3.8.0
+
+ - Octave 3.8.0 no longer defines OCTAVE_API_VERSION_NUMBER, but 3.8.1
+ will define OCTAVE_{MAJOR,MINOR,PATCH}_VERSION instead: see
+ http://hg.savannah.gnu.org/hgweb/octave/rev/b6b6e0dc700e
+ So we now use a new macro SWIG_OCTAVE_PREREQ(major,minor,patch) to
+ enable features requiring Octave version major.minor.patch or later.
+
+ For Octave versions prior to 3.8.1, we reconstruct values for
+ OCTAVE_{MAJOR,MINOR,PATCH}_VERSION based on OCTAVE_API_VERSION_NUMBER,
+ extracted from Octave's ChangeLogs. An additional hack is needed to
+ distinguish between Octave <= 3.2.x and 3.8.0, neither of which define
+ OCTAVE_API_VERSION_NUMBER.
+
+ - Octave 3.8.0 deprecates symbol_table::varref(), so remove its use
+ for this and future versions of Octave.
+
+ - Octave 3.8.0 removes octave_value::is_real_nd_array(), used in
+ octave_swig_type::dims(). Its use is not required here, so remove it.
+
+ - Retested against Octave versions 3.0.5, 3.2.4, 3.4.3, 3.6.4, and 3.8.0.
+
+ - Updated Octave documentation with tested Octave versions, and added a
+ warning against using versions <= 3.x.x, which are no longer tested.
+
+2013-12-22: wsfulton
+ C++11 support for new versions of erase and insert in the STL containers.
+
+ The erase and insert methods in the containers use const_iterator instead
+ of iterator in C++11. There are times when the methods wrapped must match
+ the parameters exactly. Specifically when full type information for
+ template types is missing or SWIG fails to look up the type correctly,
+ for example:
+
+ %include 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. branches/gsoc2009-matevz Wikipedia article: http://en.wikipedia.org/wiki/C%2B%2B0x
+ The Rvalues are used in practice to speed up the move operations
+on different containers. In the following example, we want to swap the given elements:
+This can now be solved using the new function std::move():
+For the move function to take effect, user needs to reimplement the
+move constructor (taking ClassType&& as an argument) and
+operator=(ClassType&&):
+In practice, the Rvalues are used for temporaries (when passing the
+result of one function as an argument to another). Done: Added type&& to Swig parser. Added testcase
+cpp11_rvalue_reference.i. Operator && is treated the same as
+operator &. R11450 Article:
+http://www.artima.com/cppsource/rvalue.html 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.
+ A keyword "constexpr" is introduced for this. eg.:
+constexpr int getNumber() { return 5; } const int MY_CONSTANT =
+getNumber();
+ 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.
+ Done: Added the “constexpr “ keyword to Swig. Added testcase
+cpp11_constexpr. R11322 Problem: No compilers were known to support constexpr yet, so the
+testcase was temporarily commented out in common.mk.
+ 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.
+ Done: Added support for 'extern template class
+std::vector<MyClass>;'. Added testcase cpp11_template_explicit.
+R11385 , R11386 Initializer list is a new type in standard library:
+std::initializer_list<T>. New symbols {} are introduced for the
+initializer lists.
+ One can now use:
+
+Languages like Java, C# and Python already support direct creation of
+lists natively. 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. Done: Ignored the constructor having initializer_list as its
+argument. Show warning to the user. Added testcase
+cpp11_initializer_list. R11450 Article:
+http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1919.pdf The new C++11 standard will allow the following:
+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:
+The new way of using uniform initialization allows the following:
+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). Done: Added syntax for {} member initialization in class
+constructor. Added testcase cpp11_uniform_initialization. R11413 A new keyword 'auto' is introduced in C++11:
+The type of a1 and a2 is automatically determined according to the
+initialization value during the semantic phase of the compiler. Another macro 'decltype()' is introduced. The macro takes the
+concrete object as an argument and returns its type. User could use
+this as:
+Calling operators are allowed as well:
+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 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. This feature is always present inside the implementation block
+only.
+ C++11 introduces lambda functions defined as:
+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. The following example prints the number of items stored in a list:
+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). Lambda functions can be stored using:
+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. Article:
+http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2550.pdf Done: Added syntax support for the lambda functions. Added
+testcase cpp11_lambda_functions.i. R11491, R11492 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:
+The solution C++11 offers is the combination of the 'auto' keyword
+before and '-> rettype' after the function declaration:
+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:
+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 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.
+ Basic syntax (note LessThanComparable?
+instead of "class" or "typename"):
+
+Extended syntax (requires conditions are separated with &&,
+|| or !):
+
+Definition of the concepts:
+
+Concept maps allow usage of a specific type:
+
+Concept maps can act as mini-types, with function definitions and
+other constructs commonly associated with classes:
+
+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:
+
+Axioms are more like hints to the compiler to speed-up the process of
+compilation.
+ Ignored: Concepts and axioms were removed from the C++11 standard.
+ This feature allows classes constructors to call other
+constructors with different arguments (similar to Java and C#
+behaviour).
+ The syntax is as follows:
+
+Also when using the inheritance, the feature introduces inheritance
+of all superclass constructors without being defined separately in
+the inherited class:
+
+Swig already correctly parses and produces the correct wrapper for
+the “using” keyword. Done: Added testcase cpp11_constructors.i which covers both
+constructor delegation and constructor inheritance. R11532 Problem: Constructor delegation and constructor inheritance is not
+supported by any compiler yet, so it's impossible to try and test
+this feature. nullptr is part of the standard library.
+ It's defined as typedef decltype(nullptr) nullptr_t;
+ nullptr_t is defined in <cstddef>.
+ 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. Done: Written a testcase cpp11_null_pointer_constant.i and
+cpp11_null_pointer_constant_runme.py to prove the nullptr
+functionality. R11484 C++11 introduces a new syntax for strongly typed enum declaration:
+
+Typing if (Val4 == 101) will result in compilation error.
+ The enum itself can now be explicitely of type int, long, unsigned
+int etc.:
+
+And it can be forward declared as well:
+
+Done: Added syntax 'enum class Name' and forward declarators 'enum
+Name : inherited type' or 'enum class Name : inherited type' in
+R11449. TODO: Add semantic support for enum elements not clashing with
+enum elements in other enum classes. See cpp11_strongly_typed_enums.i
+warnings. 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:
+should be mapped to Support for right angled brackets was implemented using the
+following article as a base:
+http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html
+ Done: Added support for angle brackets. Used the preferred
+"Approach 1". Added a testcase named
+cpp11_template_double_brackets. R11245 This is used when converting one type to another (eg. if
+(myObject) {}, where myObject is your custom class converted to
+bool).
+ Requires both operator and function overloading which is not
+supported in any target language (eg. python, php).
+ Done: Swig already supports the keyword "explicit" for
+function types as well. Added test case
+cpp11_explicit_conversion_operators. R11323 The new C++11 will allow creation of wrapper around the template.
+For example, if we want to do this:
+This is still illegal! But we can now use the new syntax for
+achieving the same effect:
+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. The same goes for the following example:
+Swig supports parsing typedefs for templates as well for example:
+Done: Expanded support for the new 'using' syntax and template
+aliasing. Added testcase cpp11_template_typedefs. R11533 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. 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:
+Swig already parses the given syntax. Done: Added testcase cpp11_unrestricted_unions. R11435, R11447 Problem: GCC doesn't support unrestricted unions yet so there is
+no way to actually test, if it works. The new C++11 offers the following syntax:
+This can be used for example:
+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:
+The tricky part is that variadic templates can unpack actually
+anywhere – including the class inheritance :(
+A new extension to sizeof is also introduced with this feature. The
+... after sizeof returns number of arguments:
+Done: Added syntax support for 'typename' or 'class' + ... + id.
+Added testcase cpp11_variadic_templates. R11458 Done: Added syntax support for BaseClass + ..., type + ... + id in
+parameters and baseclass + ... for intializers after constructor.
+Extended Swig syntax to support sizeof...(Args). R11467 Done: Fixed %template to support variadic number of templates. TODO: Only (if present) first variadically defined argument is
+currently used in %template directive. The next ones are ignored. Beside the implementation, the new C++11 Unicode and custom
+delimeter constants can occur in templates in the header file.
+ Done: Added symbols 'u', 'u8' and 'U' to mark the beginning of the
+UTF string. Also added test case cpp11_raw_string_literals. R11327 Done: Added R"DELIMITER[, ]DELIMITER" for a custom
+delimiter for the beginning/end of the string. R11328 TODO: Fix the Swig's C++ preprocessor bug when parsing an odd
+number of “ inside the string brackets. See
+Source/Preprocessor/cpp.c. C++ has different suffix literals. eg. 12.5f marks the number 12.5
+as float.
+ C++11 allows user to define his own suffix for the strings always
+starting with the underscore (_). eg. int a = "hello"_mySuffix;
+ The syntax is similar to other operator overloading functions:
+
+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.
+ Other forms are:
+
+Another possibility is to use variadic templates:
+
+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. Article:
+http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf Done: Added syntax support for userdefined literals. Added
+testcase cpp11_userdefined_literals.i. R11494 TODO: %rename doesn't parse operator”” yet. 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.
+ Syntax:
+
+Done: Add "thread_local" keyword to Swig. Added testcase
+cpp11_thread_local. R11393 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).
+ Words "default" and "delete" are introduced.
+The syntax is similar to declaration of pure virtual function:
+
+User has the ability by using keyword delete to disallow calling of
+the standard functions brought by C++ itself.
+
+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. Done: Added testcase cpp11_default_delete. R11535 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.
+ Done: Swig already parses the C code including the long long type.
+ static_assert() can be used at class scope as well eg.:
+
+Done: Added syntax support for "static_assert()". Added
+test case cpp11_static_assert. R11369 C++11 allows calls of sizeof to concrete objects as well:
+
+This kind of syntax is already supported by Swig. Done: Added testcase cpp11_sizeof_objects. R11538
+ C++11 will add the following classes to the standard library:
+
+Ignored: No changes to the language itself is made.
+ Tuple is array of various types. C++11 introduced this feature
+using variadic templates. Tuple is defined as:
+Constructor is automatically generated filling the tuple elements.
+get<X> function is introduced to get the Xth element in the
+tuple.
+Tuples can be copied to each other, if all the elements are copiable:
+TODO: Implement wrappers for the tuplet<> class. C++11 introduces the "unordered" version of existing
+types, which in practice work faster than the linear types:
+
+Swig should use the "unordered" types exactly the same as
+the original linear types. 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. TODO: Implement wrappers for unordered_ types. Initial work is
+already done in Lib/std/unordered_*.i files. Two new classes are introduced in C++11: basic_regex and
+match_results. Both are defined in regex header file.
+ Ignored: The new feature extends the standardy library only. No
+changes to Swig needed.
+ This feature deprecates auto_ptr and adds shared_ptr, weak_ptr and
+unique_ptr to the standard library.
+ This feature only adds the smart pointers to the standard library
+and doesn't effect the C++ syntax. Done: Added test case which uses all three smart pointers in the
+class. R11394 Problem: GCC standard library doesn't contain the new smart
+pointers yet.
+ 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.
+ Ignored: The new feature extends the standardy library only. No
+changes to Swig needed.
+ This feature adds ref and cref classes to the standard library
+(#include <utility>) usually used in tempalte functions.
+ Ignored: The new feature extends the standardy library only. No
+changes to Swig needed.
+ Two features are introduced:
+ The function template wrapper:
+ and the function object:
+
+Swig already supports the two. Done: Added a runtime testcase for function objects
+cpp11_function_objects. R11419. 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.
+ Swig already supports the following code:
+
+Functions is_convertible, is_integral, is_integral_const etc. are
+part of the new header:
+
+Swig correctly parses the syntax for template<bool>,
+template<class T> and template<>.
+ Ignored: Swig requires explicitly defined template class
+(%template directive) to export it to the target language. The template function is introduced: std::result_of() which
+depends on decltype:
+
+Swig correctly parses the result_of class. TODO: The return type (the result_of::type member) is not
+calculated by Swig. This needs a much more complex semantic parser. Done: Added testcase cpp11_result_of. R11534
Constants, as declared by the preprocessor #define macro or SWIG
- %constant directive, are included in SWIGs parse tree
+ %constant directive, are included in SWIG's parse tree
when it can be determined that they are, or could be reduced to,
a literal value. Such values are translated into defconstant
forms in the generated lisp wrapper when the -nocwrap command-line
@@ -887,7 +887,7 @@ globalvar> (globalvar.nnn::glob_float)
In C, an enumeration value is an integer value, while in C++ an
enumeration value is implicitly convertible to an integer value,
- but can also be distinguished by it's enum type. For each enum
+ but can also be distinguished by its enum type. For each enum
declaration a def-foreign-type is generated, assigning the enum
a default type of :int. Users may adjust the foreign type of
enums via SWIG typemaps.
@@ -901,7 +901,7 @@ globalvar> (globalvar.nnn::glob_float)
of it not being necessary to probe into foreign space to retrieve enum
values. When generating a .cxx wrapper file, a more general solution is
employed. A wrapper variable is created in the module_wrap.cxx file, and
- a ff:def-foreign-variable call is generated to retrieve it's value into lisp.
+ a ff:def-foreign-variable call is generated to retrieve its value into lisp.
For example, the following header file
@@ -1131,7 +1131,7 @@ namespace BAR {
inheritance of the classes in foreign code, with the
ff:foreign-pointer class at its root. ff:foreign-pointer is a thin
wrapper for pointers that is made available by the foreign function
- interface. It's key benefit is that it may be passed as an argument
+ interface. Its key benefit is that it may be passed as an argument
to any ff:def-foreign-call that is expecting a pointer as the
parameter.
C++0x/C++11 support for SWIG
+Summary
+SVN branch
+New C++11 features status
+Rvalue reference and move semantics [done]
+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)
+}
template <class T> swap(T& a, T& b) {
+ T tmp(std::move(a));
+ a = std::move(b);
+ b = std::move(tmp);
+}
class MyClass {
+ MyClass(MyClass&& p) : ptr(p.ptr) {p.ptr = 0;}
+ MyClass& operator=(MyClass&& p) {
+ std::swap(ptr, p.ptr);
+ return *this;
+ }
+};
Generalized constant expressions [done]
+Extern template [done]
+Initializer lists [done]
+ class A {
+ public:
+ A( std::initializer_list<int> );
+ };
+ A a1 = {1,2,3,4};
Uniform initialization [done]
+struct IdString {
+ std::string name;
+ int identifier;
+};
+
+IdString GetString() {
+ return {"SomeName", 4}; //Note the lack of explicit type.
+}
IdString str1 = {„SomeName“, 4};
+IdString str2{„SomeName“, 4};
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
Type inference [partially done]
+auto a1 = 100;
+auto a2 = myFunc();
int i = 100;
+decltype(i) j = 200; // decltype(i) = int
decltype(i+j) k = 300;
Range-based for-loop [ignored]
+Lambda functions and expressions [done]
+[](int x, int y) -> int { return x + y; }
std::vector<int> someList;
+int total = 0;
+std::for_each( someList.begin(), someList.end(), [&total](int x) {total += x} );
+std::cout << total;
auto myLambdaFunc = [this]() { this->SomePrivateMemberFunction() };
Alternate function syntax [done]
+template< typename LHS, typename RHS>
+ decltype(lhs+rhs) AddingFunc(const LHS &lhs, const RHS &rhs) {return lhs + rhs;} //Not legal C++11
template< typename LHS, typename RHS>
+ auto AddingFunc(const LHS &lhs, const RHS &rhs) -> decltype(lhs+rhs) {return lhs + rhs;}
struct SomeStruct {
+ auto FuncName(int x, int y) -> int;
+};
+
+auto SomeStruct::FuncName(int x, int y) -> int {
+ return x + y;
+}
Concepts, Axioms [ignored]
+ template<LessThanComparable? T>
+ const T& min(const T &x, const T &y) {
+ return y < x ? y : x;
+ }
template< typename T> requires LessThanComparable?<T>
+ const T& min(const T &x, const T &y) {
+ return y < x ? y : x;
+ }
concept LessThanComparable?< typename T > {
+ bool operator<(T,T);
+ requires GreaterThanComparable?<T>;
+ typename value_type;
+ typename reference;
+ };
template< typename T>
+ concept_map InputIterator?<T*> {
+ typedef T value_type ;
+ typedef T& reference ;
+ typedef T* pointer ;
+ typedef std::ptrdiff_t difference_type ;
+ };
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(); }
+ };
concept Semigroup< typename Op, typename T> : CopyConstructible?<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);
+ }
+ };
Object construction improvement [done]
+ class SomeType {
+ int number;
+ public:
+ SomeType(int newNumber) : number(newNumber) {}
+ SomeType() : SomeType(42) {}
+ };
class BaseClass {
+ public:
+ BaseClass(int iValue);
+ };
+ class DerivedClass: public BaseClass {
+ public:
+ using BaseClass::BaseClass; // Adds DerivedClass(int) constructor
+ };
Null pointer constant [done]
+Strongly typed enumerations [partially done]
+ enum class Enumeration {
+ Val1,
+ Val2,
+ Val3 = 100,
+ Val4 /* = 101 */
+ };
enum class Enum2 : unsigned int {Val1, Val2};
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.
class A { enum class EA { a,b,c,d }; };
class A { class EA { enum {a,b,c,d}; }; };
+Angle bracket [done]
+Explicit conversion operators [done]
+Template typedefs [partially done]
+template< typename first, typename second, int third>
+class SomeType;
+
+template< typename second>
+typedef SomeType<OtherType, second, 5> TypedefName; //Illegal in C++
template< typename first, typename second, int third>
+class SomeType;
+
+template< typename second>
+using TypedefName = SomeType<OtherType, second, 5>;
typedef void (*PFD)(double); // Old style
+using PF = void (*)(double); // New introduced syntax
typedef List<int> intList;
Unrestricted unions [done]
+ 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;
Variadic templates [partially done]
+template<typename... Values> class tuple;
class tuple<int, std::vector<int>, std::map<std::string, std::vector<int>>> someInstanceName;
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");
+}
template <typename... BaseClasses> class ClassName : public BaseClasses... {
+public:
+
+ ClassName (BaseClasses&&... baseClasses) : BaseClasses(baseClasses)... {}
+}
template<typename ...Args> struct SomeStruct {
+ static const int size = sizeof...(Args);
+}
+// SomeStruct<Type1, Type2>::size is 2 and SomeStruct<>::size is 0
New string literals [partially done]
+User-defined literals [partially done]
+ OutputType operator "" _mySuffix(const char * string_values);
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 */
template<char...> OutputType operator "" _mySuffix();
+ OutputType someVariable = "1234"_mySuffix;
Thread-local storage [done]
+
+ struct A {
+ thread_local int val;
+ };
Defaulting/deleting of standard functions on C++ objects [done]
+ 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 */
+ };
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 */
+ };
Type long long int [done]
+Static assertions [done]
+ template <typename T>
+ struct Check {
+ static_assert(sizeof(int) <= sizeof(T), "not big enough");
+ };
Allow sizeof to work on members of classes without an explicit
+object [done]
+ struct A { int member; };
+ sizeof(A::member); //Does not work with C++03. Okay with C++11
Threading facilities [ignored]
+ * std::thread
+ * std::mutex, std::recursive_mutex
+ * std::condition_variable, std::condition_variable_any
+ * std::lock_guard, std::unique_lock
+ * std::packaged_task
Tuple types [TODO]
+template <class ...Types> class tuple;
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.
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 *'.
Hash tables [TODO]
+ - unordered set
+ - unordered multiset
+ - unordered map
+ - unordered multimap
Regular expressions [ignored]
+General-purpose smart pointers [done]
+Extensible random number facility [ignored]
+Wrapper reference [ignored]
+Polymorphous wrappers for function objects [done]
+
+
+ function<int ( int, int )> pF;
+
+
+ struct Test {
+ bool operator()( short x, short y );
+ };
Type traits for metaprogramming [ignored]
+ 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 > // N == 0 condition of termination.
+ {
+ enum{ value = 1 };
+ };
+ int quartic_of_three = Pow< 3, 4 >::value ;
// 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 );
+}
Uniform method for computing return type of function objects
+[partially done]
+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;
+};
@@ -844,7 +844,7 @@ Returns a type object corresponding to the type string produced by the Swig_cloc
This function is the inverse of the clocal() function. Given a type and a name,
it produces a string containing the code needed to cast/convert the type produced by
-Swig_clocal() back into it's original type.
+Swig_clocal() back into its original type.
diff --git a/Doc/Devel/tree.html b/Doc/Devel/tree.html
index db3c6fee4..73a49ed55 100644
--- a/Doc/Devel/tree.html
+++ b/Doc/Devel/tree.html
@@ -185,7 +185,7 @@ this function merely records that those attributes did not exist in the original
This function is similar to Swig_save() except that adds additional attribute checking. There are different interpretations
of the attribute names. A name of "attr" merely requests that the function check for the presence of an attribute. If the attribute is missing, SWIG will exit with a failed assertion. An attribute name of "?attr" specifies that the attribute "attr" is optional and
-that it's old value must be saved (if any). An attribute name of "*attr" specifies that the attribute is required and that
+that its old value must be saved (if any). An attribute name of "*attr" specifies that the attribute is required and that
its value must be saved. The saving of attributes is performed in the same manner as with Swig_save(). Here is an example:
diff --git a/Doc/Manual/Allegrocl.html b/Doc/Manual/Allegrocl.html
index 12b915ee2..173777231 100644
--- a/Doc/Manual/Allegrocl.html
+++ b/Doc/Manual/Allegrocl.html
@@ -748,7 +748,7 @@ namespace car {
This typemap is not used for code generation, but purely for the transformation of types in the parameter list of the wrapper function. - It's primary use is to handle by-value to by-reference conversion in the + Its primary use is to handle by-value to by-reference conversion in the wrappers parameter list. Its default settings are:
@@ -2093,7 +2093,7 @@ foreign environment.The :type keyword argument provides more information on the type of -identifier. It's value is a symbol. This allows the +identifier. Its value is a symbol. This allows the identifier-converter to apply different heuristics when mapping different types of identifiers to symbols. SWIG will generate calls to your identifier-converter using the following types. @@ -2123,7 +2123,7 @@ scope in the specified class.
The :arity keyword argument only appears in swig:swig-defmethod forms -generated for overloaded functions. It's value is an integer +generated for overloaded functions. Its value is an integer indicating the number of arguments passed to the routine indicated by this identifier.
diff --git a/Doc/Manual/Android.html b/Doc/Manual/Android.html index 4d1be3944..e02271169 100644 --- a/Doc/Manual/Android.html +++ b/Doc/Manual/Android.html @@ -435,11 +435,11 @@ public: } virtual ~Shape() { nshapes--; - }; + } double x, y; void move(double dx, double dy); - virtual double area(void) = 0; - virtual double perimeter(void) = 0; + virtual double area() = 0; + virtual double perimeter() = 0; static int nshapes; }; @@ -447,18 +447,18 @@ class Circle : public Shape { private: double radius; public: - Circle(double r) : radius(r) { }; - virtual double area(void); - virtual double perimeter(void); + Circle(double r) : radius(r) { } + virtual double area(); + virtual double perimeter(); }; class Square : public Shape { private: double width; public: - Square(double w) : width(w) { }; - virtual double area(void); - virtual double perimeter(void); + Square(double w) : width(w) { } + virtual double area(); + virtual double perimeter(); };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. +
+SWIG supports 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 incomplete. +The wrappers for the new containers would work much like the C++03 containers and +users are welcome to help by adapting the existing container interface files and submitting them +as a patch for inclusion in future versions of SWIG. +
+ ++SWIG correctly parses the rvalue reference syntax '&&', +for example the typical usage of it in the move constructor and move assignment operator below: +
+ ++class MyClass { +... + std::vectornumbers; +public: + MyClass(MyClass &&other) : numbers(std::move(other.numbers)) {} + MyClass & operator=(MyClass &&other) { + numbers = std::move(other.numbers); + return *this; + } +}; +
+Rvalue references are designed for C++ temporaries and so are not very useful when used from non-C++ target languages. +Generally you would just ignore them via %ignore before parsing the class. +For example, ignore the move constructor: +
+ ++%ignore MyClass::MyClass(MyClass &&); +
+The plan is to ignore them by default in a future version of SWIG. Note that both normal assignment operators as well as move assignment operators are ignored by default in most target languages with the following warning: +
+ ++example.i:18: Warning 503: Can't wrap 'operator =' unless renamed to a valid identifier. ++
SWIG correctly parses the keyword constexpr, but ignores its functionality. Constant functions cannot be used as constants.
+ ++constexpr int myConstFunc() { return 10; } +const int a = myConstFunc(); // results in error +
Users needs to use values or predefined constants when defining the new constant value:
+ ++#define MY_CONST 10 +constexpr int myConstFunc() { return MY_CONST; } +const int a = MY_CONST; // ok +
SWIG correctly parses the keywords extern template. However, the explicit template instantiation is not used by SWIG, a %template is still required.
+ + ++extern template class std::vector<MyClass>; // explicit instantiation + +... + +class MyClass { +public: + int a; + int b; +}; +
+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 std::initializer_list type. +SWIG detects usage of initializer lists and will emit a special informative warning each time one is used: +
+ ++example.i:33: Warning 476: Initialization using std::initializer_list. ++
+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: +
+ ++%ignore Container::Container(std::initializer_list<int>); +class Container { +public: + Container(std::initializer_list<int>); // initializer-list constructor + Container(); + void push_back(const int &); + ... +}; +
Alternatively you could modify the class and add another constructor for initialization by some other means, +for example by a std::vector:
+ ++%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 &); + ... +}; +
And then call this constructor from your target language, for example, in Python, the following will call the constructor taking the std::vector:
+ ++>>> c = Container( [1,2,3,4] ) +
+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: +
+ ++%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 &); + ... +}; +
+The above makes the wrappers look is as if the class had been declared as follows: +
+ ++%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 &); + ... +}; +
+std::initializer_list 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 +std::initializer_list. 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: +
+ ++%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 &); + ... +}; +
+Any attempt at passing in values from the target language will be ignored and replaced by {10, 20, 30, 40, 50}. +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 std::initializer_list, +but with values decided at runtime. +The typemaps would be target language specific. +
+ ++Note that the default typemap for std::initializer_list does nothing but issue the warning +and hence any user supplied typemaps will override it and suppress the warning. +
+ +The curly brackets {} for member initialization are fully +supported by SWIG:
+ ++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 +
Uniform initialization does not affect usage from the target language, for example in Python:
+ ++>>> a = AltStruct(10, 142.15) +>>> a.x_ +10 +>>> a.y_ +142.15 +
SWIG supports decltype() with some limitations. Single +variables are allowed, however, expressions are not supported yet. For +example, the following code will work:
++int i; +decltype(i) j; +
However, using an expression inside the decltype results in syntax error:
++int i; int j; +decltype(i+j) k; // syntax error +
This feature is part of the implementation block only. SWIG +ignores it.
+ +SWIG correctly parses most of the Lambda functions syntax. For example:
++auto val = [] { return something; }; +auto sum = [](int x, int y) { return x+y; }; +auto sum = [](int x, int y) -> int { return x+y; }; +
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.
+ ++Lambda functions used to create variables can also be parsed, but due to limited support of auto when +the type is deduced from the expression, the variables are simply ignored. +
+ ++auto six = [](int x, int y) { return x+y; }(4, 2); +
+Better support should be available in a later release. +
+ +SWIG fully supports the new definition of functions. For example:
++struct SomeStruct { + int FuncName(int x, int y); +}; +
can now be written as in C++11:
+ ++struct SomeStruct { + auto FuncName(int x, int y) -> int; +}; + +auto SomeStruct::FuncName(int x, int y) -> int { + return x + y; +} +
The usage in the target languages remains the same, for example in Python:
+ ++>>> a = SomeStruct() +>>> a.FuncName(10,5) +15 +
SWIG will also deal with type inference for the return type, as per the limitations described earlier. For example:
++auto square(float a, float b) -> decltype(a); +
+SWIG is able to handle constructor delegation, such as: +
+ ++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; } +}; +
+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: + +
+ ++class BaseClass { +public: + BaseClass(int iValue); +}; + +class DerivedClass: public BaseClass { + public: + using BaseClass::BaseClass; // Adds DerivedClass(int) constructor +}; +
+The special identifiers final and override can be used on methods and destructors, +such as in the following example: +
+ ++struct BaseStruct { + virtual void ab() const = 0; + virtual void cd(); + virtual void ef(); + virtual ~BaseStruct(); +}; +struct DerivedStruct : BaseStruct { + virtual void ab() const override; + virtual void cd() final; + virtual void ef() final override; + virtual ~DerivedStruct() override; +}; +
The nullptr constant is largely unimportant in wrappers. In the few places it has an effect, it is treated like NULL.
+ +SWIG parses the new enum class syntax and forward declarator for the enums:
++enum class MyEnum : unsigned int; +
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:
+ ++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 + }; +}; +
A workaround is to write these as a series of separated classes containing anonymous enums:
+ ++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 + }; +}; +
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.
+ ++std::vector<std::vector<int>> myIntTable; +
SWIG correctly parses the keyword explicit both for operators and constructors. +For example:
+ ++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; +}; +
+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. +
+ ++The following is an example of an alias template: + +
+template< typename T1, typename T2, int > +class SomeType { + T1 a; + T2 b; + int c; +}; + +template< typename T2 > +using TypedefName = SomeType<char*, T2, 5>; +
+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: +
+ ++example.i:13: Warning 342: The 'using' keyword in template aliasing is not fully supported yet. ++
+Similarly for non-template type aliasing: +
+ ++using PFD = void (*)(double); // New introduced syntax +
+A warning will be issued: +
+ ++example.i:17: Warning 341: The 'using' keyword in type aliasing is not fully supported yet. ++
The equivalent old style typedefs can be used as a workaround:
+ ++typedef void (*PFD)(double); // The old style +
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:
+ ++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; +
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:
+ ++template <typename... BaseClasses> class ClassName : public BaseClasses... { +public: + ClassName (BaseClasses &&... baseClasses) : BaseClasses(baseClasses)... {} +} +
+For now however, the %template directive only accepts one parameter substitution +for the variable template parameters. +
+ ++%template(MyVariant1) ClassName<> // zero argument not supported yet +%template(MyVariant2) ClassName<int> // ok +%template(MyVariant3) ClassName<int, int> // too many arguments not supported yet +
Support for the variadic sizeof() function is correctly parsed:
+ ++const int SIZE = sizeof...(ClassName<int, int>); +
+In the above example SIZE is of course wrapped as a constant. +
+ +SWIG supports unicode string constants and raw string literals.
+ ++// 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"; +
Note: SWIG currently incorrectly parses the odd number of double quotes +inside the string due to SWIG's C++ preprocessor.
+ ++SWIG parses the declaration of user-defined literals, that is, the operator "" _mysuffix() function syntax. +
+ ++Some examples are the raw literal: +
++OutputType operator "" _myRawLiteral(const char * value); +
+numeric cooked literals: +
++OutputType operator "" _mySuffixIntegral(unsigned long long); +OutputType operator "" _mySuffixFloat(long double); +
+and cooked string literals: +
++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); +
+Like other operators that SWIG parses, a warning is given about renaming the operator in order for it to be wrapped: +
+ ++example.i:27: Warning 503: Can't wrap 'operator "" _myRawLiteral' unless renamed to a valid identifier. +
+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: +
+ ++%rename(MyRawLiteral) operator"" _myRawLiteral(const char * value); +
+Or if you just wish to ignore it altogether: +
+ ++%ignore operator "" _myRawLiteral(const char * value); +
+Note that use of user-defined literals such as the following still give a syntax error: +
+ ++OutputType var1 = "1234"_suffix; +OutputType var2 = 1234_suffix; +OutputType var3 = 3.1416_suffix; +
SWIG correctly parses the thread_local keyword. For example, variable +reachable by the current thread can be defined as:
+ ++struct A { + static thread_local int val; +}; +thread_local int global_val; +
+The use of the thread_local 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. +
+ +SWIG handles explicitly defaulted functions, that is, = default added to a function declaration. Deleted definitions, which are also called deleted functions, have = delete added to the function declaration. +For example:
+ ++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 */ +}; +
+Wrappers for deleted functions will not be available in the target language. +Wrappers for defaulted functions will of course be available in the target language. +Explicitly defaulted functions have no direct effect for SWIG wrapping as the declaration is handled +much like any other method declaration parsed by SWIG. +
+ +SWIG correctly parses and uses the new long long type already introduced in C99 some time ago.
+ +SWIG correctly parses and calls the new static_assert function.
+ ++template <typename T> +struct Check { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); +}; +
SWIG correctly calls the sizeof() on types as well as on the +objects. For example:
+ ++struct A { + int member; +}; + +const int SIZE = sizeof(A::member); // does not work with C++03. Okay with C++11 +
In Python:
++>>> SIZE +8 +
+C++11 added in the noexcept specification to exception specifications to indicate that a function simply may or may not throw an exception, without actually naming any exception. +SWIG understands these, although there isn't any useful way that this information can be taken advantage of by target languages, +so it is as good as ignored during the wrapping process. +Below are some examples of noexcept in function declarations: +
+ ++static void noex1() noexcept; +int noex2(int) noexcept(true); +int noex3(int, bool) noexcept(false); +
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++.
+ +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.
+ +SWIG does not wrap the new C++11 regular expressions classes, because the SWIG target languages use their own facilities for this.
+ ++SWIG provides special smart pointer handling for std::tr1::shared_ptr in the same way it has support for boost::shared_ptr. +There is no special smart pointer handling available for std::weak_ptr and std::unique_ptr. +
+ +This feature extends and standardizes the standard library only and does not effect the C++ language and SWIG.
+ +The new ref and cref classes are used to instantiate a parameter as a reference of a template function. For example:
+ ++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 +} +
The ref and cref classes are not wrapped by SWIG because the SWIG target languages do not support referencing.
+ ++SWIG supports functor classes in some languages in a very natural way. +However nothing is provided yet for the new std::function template. +SWIG will parse usage of the template like any other template. +
+ ++%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 + +
+Example of supported usage of the plain functor from Python is shown below. +It does not involve std::function. +
+ ++t = Test() +b = t(1,2) # invoke C++ function object +
The new C++ metaprogramming is useful at compile time and is aimed specifically for C++ development:
+ ++// 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); +} +
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 %template directive, so the C++ metaprogramming features are not really of interest at runtime in the target languages.
+ +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:
++%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; +
will result in:
+ ++>>> test_result_impl(SQUARE, 5.0) +<SWIG Object of type 'std::result_of< Fun(Arg) >::type *' at 0x7faf99ed8a50> +
Instead, please use decltype() where possible for now.
+ + + diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html index 6df2594c4..6ee33ac68 100644 --- a/Doc/Manual/CSharp.html +++ b/Doc/Manual/CSharp.html @@ -10,6 +10,9 @@+In order to minimize name collisions between names generated based on input to SWIG and names used in the generated code from the .NET framework, SWIG 3 fully qualifies the use of all .NET types. Furthermore, SWIG 3 avoids using directives in generated code. This breaks backwards compatibility with typemaps, pragmas, etc written for use with SWIG 2 that assume the presence of using System; or using System.Runtime.InteropServices; directives in the intermediate class imports, module imports, or proxy imports. SWIG 3 supports backwards compatibility though the use of the SWIG2_CSHARP macro. If SWIG2_CSHARP is defined, SWIG 3 generates using directives in the intermediate class, module class, and proxy class code similar to those generated by SWIG 2. This can be done without modifying any of the input code by passing the -DSWIG2_CSHARP commandline parameter when executing swig. +
+-%typemap(imtype, out="IntPtr") char * "string" +%typemap(imtype, out="global::System.IntPtr") char * "string" char * function(char *);
-public static extern IntPtr function(string jarg1); +public static extern global::System.IntPtr function(string jarg1);
%typemap(imtype, - inattributes="[MarshalAs(UnmanagedType.LPStr)]", - outattributes="[return: MarshalAs(UnmanagedType.LPStr)]") const char * "String" + inattributes="[global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPStr)]", + outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPStr)]") const char * "String" const char * GetMsg() {} void SetMsg(const char *msg) {} @@ -310,12 +319,12 @@ The intermediary class will then have the marshalling as specified by everythingclass examplePINVOKE { ... - [DllImport("example", EntryPoint="CSharp_GetMsg")] - [return: MarshalAs(UnmanagedType.LPStr)] + [global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_GetMsg")] + [return: global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPStr)] public static extern String GetMsg(); - [DllImport("example", EntryPoint="CSharp_SetMsg")] - public static extern void SetMsg([MarshalAs(UnmanagedType.LPStr)]String jarg1); + [global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_SetMsg")] + public static extern void SetMsg([global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPStr)]String jarg1); }
[ThreadSafe] -public class AClass : IDisposable { +public class AClass : global::System.IDisposable { ... [ThreadSafe(false)] public AClass(double a) ... @@ -392,9 +401,9 @@ An example for attaching attributes to the enum and enum values is shown below.-%typemap(csattributes) Couleur "[System.ComponentModel.Description(\"Colours\")]" -%csattributes Rouge "[System.ComponentModel.Description(\"Red\")]" -%csattributes Vert "[System.ComponentModel.Description(\"Green\")]" +%typemap(csattributes) Couleur "[global::System.ComponentModel.Description(\"Colours\")]" +%csattributes Rouge "[global::System.ComponentModel.Description(\"Red\")]" +%csattributes Vert "[global::System.ComponentModel.Description(\"Green\")]" %inline %{ enum Couleur { Rouge, Orange, Vert }; %} @@ -407,12 +416,12 @@ which will result in the following C# enum:-[System.ComponentModel.Description("Colours")] +[global::System.ComponentModel.Description("Colours")] public enum Couleur { - [System.ComponentModel.Description("Red")] + [global::System.ComponentModel.Description("Red")] Rouge, Orange, - [System.ComponentModel.Description("Green")] + [global::System.ComponentModel.Description("Green")] Vert }@@ -618,9 +627,9 @@ marshalling for the arrays:@@ -668,9 +677,9 @@ and intermediary class method-[DllImport("example", EntryPoint="CSharp_myArrayCopy")] -public static extern void myArrayCopy([In, MarshalAs(UnmanagedType.LPArray)]int[] jarg1, - [Out, MarshalAs(UnmanagedType.LPArray)]int[] jarg2, +[global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_myArrayCopy")] +public static extern void myArrayCopy([global::System.Runtime.InteropServices.In, global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPArray)]int[] jarg1, + [global::System.Runtime.InteropServices.Out, global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPArray)]int[] jarg2, int jarg3);@@ -743,7 +752,7 @@ As a result, we get the following method in the module class: fixed ( int *swig_ptrTo_sourceArray = sourceArray ) { fixed ( int *swig_ptrTo_targetArray = targetArray ) { { - examplePINVOKE.myArrayCopy((IntPtr)swig_ptrTo_sourceArray, (IntPtr)swig_ptrTo_targetArray, + examplePINVOKE.myArrayCopy((global::System.IntPtr)swig_ptrTo_sourceArray, (global::System.IntPtr)swig_ptrTo_targetArray, nitems); } } @@ -764,8 +773,8 @@ example - the method is expecting an IntPtr as the parameter type.- [DllImport("example", EntryPoint="CSharp_myArraySwap")] - public static extern void myArraySwap([In, Out, MarshalAs(UnmanagedType.LPArray)]int[] jarg1, - [In, Out, MarshalAs(UnmanagedType.LPArray)]int[] jarg2, + [global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_myArraySwap")] + public static extern void myArraySwap([global::System.Runtime.InteropServices.In, global::System.Runtime.InteropServices.Out, global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPArray)]int[] jarg1, + [global::System.Runtime.InteropServices.In, global::System.Runtime.InteropServices.Out, global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPArray)]int[] jarg2, int jarg3);@@ -872,7 +881,7 @@ set so should only be used when a C# exception is not created.-[DllImport("example", EntryPoint="CSharp_myArrayCopy")] -public static extern void myArrayCopy(IntPtr jarg1, IntPtr jarg2, int jarg3); +[global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_myArrayCopy")] +public static extern void myArrayCopy(global::System.IntPtr jarg1, global::System.IntPtr jarg2, int jarg3);-Lets say we have the following simple C++ method: +Let's say we have the following simple C++ method:
@@ -1220,7 +1229,7 @@ the C# code can be generated into the intermediary class using the imclassco static CustomExceptionDelegate customDelegate = new CustomExceptionDelegate(SetPendingCustomException); - [DllImport("$dllimport", EntryPoint="CustomExceptionRegisterCallback")] + [global::System.Runtime.InteropServices.DllImport("$dllimport", EntryPoint="CustomExceptionRegisterCallback")] public static extern void CustomExceptionRegisterCallback(CustomExceptionDelegate customCallback); @@ -1264,7 +1273,7 @@ The boiler plate code above must be used in addition to a handcrafted Custom@@ -1795,9 +1801,9 @@ is called using the following typemaps. // of dangling C++ pointer. Intended for methods that return pointers or // references to a member variable. %typemap(csout, excode=SWIGEXCODE) Wheel& getWheel { - IntPtr cPtr = $imcall;$excode + global::System.IntPtr cPtr = $imcall;$excode $csclassname ret = null; - if (cPtr != IntPtr.Zero) { + if (cPtr != global::System.IntPtr.Zero) { ret = new $csclassname(cPtr, $owner); ret.addReference(this); } @@ -1813,7 +1819,7 @@ The code in the second typemap constitutes the bulk of the code in the generated// Custom C# Exception -class CustomApplicationException : System.ApplicationException { +class CustomApplicationException : global::System.ApplicationException { public CustomApplicationException(string message) : base(message) { } @@ -1457,20 +1466,17 @@ Below is the generated C# Base director class.@@ -1755,9 +1761,9 @@ and the following usage from C# after running the code through SWIG: Wheel wheel = new Bike(10).getWheel(); Console.WriteLine("wheel size: " + wheel.size); // Simulate a garbage collection - System.GC.Collect(); - System.GC.WaitForPendingFinalizers(); - Console.WriteLine("wheel size: " + wheel.size); + global::System.GC.Collect(); + global::System.GC.WaitForPendingFinalizers(); + global::System.Console.WriteLine("wheel size: " + wheel.size);-using System; -using System.Runtime.InteropServices; - -public class Base : IDisposable { - private HandleRef swigCPtr; +public class Base : global::System.IDisposable { + private global::System.Runtime.InteropServices.HandleRef swigCPtr; protected bool swigCMemOwn; - internal Base(IntPtr cPtr, bool cMemoryOwn) { + internal Base(global::System.IntPtr cPtr, bool cMemoryOwn) { swigCMemOwn = cMemoryOwn; - swigCPtr = new HandleRef(this, cPtr); + swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr); } - internal static HandleRef getCPtr(Base obj) { - return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + internal static global::System.Runtime.InteropServices.HandleRef getCPtr(Base obj) { + return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr; } ~Base() { @@ -1479,12 +1485,12 @@ public class Base : IDisposable { public virtual void Dispose() { lock(this) { - if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + if(swigCPtr.Handle != global::System.IntPtr.Zero && swigCMemOwn) { swigCMemOwn = false; examplePINVOKE.delete_Base(swigCPtr); } - swigCPtr = new HandleRef(null, IntPtr.Zero); - GC.SuppressFinalize(this); + swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero); + global::System.GC.SuppressFinalize(this); } } @@ -1511,7 +1517,7 @@ public class Base : IDisposable { examplePINVOKE.Base_director_connect(swigCPtr, swigDelegate0, swigDelegate1); } - private bool SwigDerivedClassHasMethod(string methodName, Type[] methodTypes) { + private bool SwigDerivedClassHasMethod(string methodName, global::System.global::System.Type[] methodTypes) { System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(methodName, methodTypes); bool hasDerivedMethod = methodInfo.DeclaringType.IsSubclassOf(typeof(Base)); return hasDerivedMethod; @@ -1521,18 +1527,18 @@ public class Base : IDisposable { return UIntMethod(x); } - private void SwigDirectorBaseBoolMethod(IntPtr b, bool flag) { + private void SwigDirectorBaseBoolMethod(global::System.IntPtr b, bool flag) { BaseBoolMethod(new Base(b, false), flag); } internal delegate uint SwigDelegateBase_0(uint x); - internal delegate void SwigDelegateBase_1(IntPtr b, bool flag); + internal delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag); private SwigDelegateBase_0 swigDelegate0; private SwigDelegateBase_1 swigDelegate1; - private static Type[] swigMethodTypes0 = new Type[] { typeof(uint) }; - private static Type[] swigMethodTypes1 = new Type[] { typeof(Base), typeof(bool) }; + private static global::System.Type[] swigMethodTypes0 = new global::System.Type[] { typeof(uint) }; + private static global::System.Type[] swigMethodTypes1 = new global::System.Type[] { typeof(Base), typeof(bool) }; }@@ -1918,14 +1924,14 @@ One solution is to add in the appropriate references in the C# layer...-public class Wheel : IDisposable { +public class Wheel : global::System.IDisposable { ... // Ensure that the GC doesn't collect any Bike instance set from C# private Bike bikeReference; @@ -1822,12 +1828,12 @@ public class Wheel : IDisposable { } } -public class Bike : IDisposable { +public class Bike : global::System.IDisposable { ... public Wheel getWheel() { - IntPtr cPtr = examplePINVOKE.Bike_getWheel(swigCPtr); + global::System.IntPtr cPtr = examplePINVOKE.Bike_getWheel(swigCPtr); Wheel ret = null; - if (cPtr != IntPtr.Zero) { + if (cPtr != global::System.IntPtr.Zero) { ret = new Wheel(cPtr, false); ret.addReference(this); } @@ -1904,9 +1910,9 @@ In order to understand why, consider a garbage collection occuring... container.setElement(element); Console.WriteLine("element.value: " + container.getElement().value); // Simulate a garbage collection - System.GC.Collect(); - System.GC.WaitForPendingFinalizers(); - Console.WriteLine("element.value: " + container.getElement().value); + global::System.GC.Collect(); + global::System.GC.WaitForPendingFinalizers(); + global::System.Console.WriteLine("element.value: " + container.getElement().value);-public class Container : IDisposable { +public class Container : global::System.IDisposable { ... // Ensure that the GC doesn't collect any Element set from C# // as the underlying C++ class stores a shallow copy private Element elementReference; - private HandleRef getCPtrAndAddReference(Element element) { + private global::System.Runtime.InteropServices.HandleRef getCPtrAndAddReference(Element element) { elementReference = element; return Element.getCPtr(element); } @@ -1951,7 +1957,7 @@ The 'cscode' typemap simply adds in the specified code into the C# proxy class. // Ensure that the GC doesn't collect any Element set from C# // as the underlying C++ class stores a shallow copy private Element elementReference; - private HandleRef getCPtrAndAddReference(Element element) { + private global::System.Runtime.InteropServices.HandleRef getCPtrAndAddReference(Element element) { elementReference = element; return Element.getCPtr(element); } @@ -2000,7 +2006,7 @@ First let's look at the code that is generated by default, where the C# proxy cl-public class Action : IDisposable { +public class Action : global::System.IDisposable { ... public Action(CDate dateIn, CDate dateOut) : this(examplePINVOKE.new_Action(CDate.getCPtr(dateIn), CDate.getCPtr(dateOut)), true) { @@ -2081,7 +2087,7 @@ The resulting generated proxy code in the Action class follows:-public class Action : IDisposable { +public class Action : global::System.IDisposable { ... public int doSomething(System.DateTime dateIn, out System.DateTime dateOut) { CDate tempdateIn = new CDate(dateIn.Year, dateIn.Month, dateIn.Day); @@ -2099,7 +2105,7 @@ public class Action : IDisposable { } } - static private IntPtr SwigConstructAction(System.DateTime dateIn, out System.DateTime dateOut) { + static private global::System.IntPtr SwigConstructAction(System.DateTime dateIn, out System.DateTime dateOut) { CDate tempdateIn = new CDate(dateIn.Year, dateIn.Month, dateIn.Day); CDate tempdateOut = new CDate(); try { @@ -2299,8 +2305,8 @@ The typemap type required is thus CDate *. Given that the previous sect %typemap(csvarout, excode=SWIGEXCODE2) CDate * %{ /* csvarout typemap code */ get { - IntPtr cPtr = $imcall; - CDate tempDate = (cPtr == IntPtr.Zero) ? null : new CDate(cPtr, $owner);$excode + global::System.IntPtr cPtr = $imcall; + CDate tempDate = (cPtr == global::System.IntPtr.Zero) ? null : new CDate(cPtr, $owner);$excode return new System.DateTime(tempDate.getYear(), tempDate.getMonth(), tempDate.getDay(), 0, 0, 0); } %} @@ -2322,8 +2328,8 @@ public class example { } /* csvarout typemap code */ get { - IntPtr cPtr = examplePINVOKE.ImportantDate_get(); - CDate tempDate = (cPtr == IntPtr.Zero) ? null : new CDate(cPtr, false); + global::System.IntPtr cPtr = examplePINVOKE.ImportantDate_get(); + CDate tempDate = (cPtr == global::System.IntPtr.Zero) ? null : new CDate(cPtr, false); return new System.DateTime(tempDate.getYear(), tempDate.getMonth(), tempDate.getDay(), 0, 0, 0); } @@ -2389,7 +2395,7 @@ The generated proxy class code will then contain the following wrapper for calli... - private void SwigDirectorsomeCallback(IntPtr date) { + private void SwigDirectorsomeCallback(global::System.IntPtr date) { System.DateTime tempdate = new System.DateTime(); try { someCallback(out tempdate); @@ -2432,7 +2438,7 @@ The default C# proxy class generated is:-public class ExtendMe : IDisposable { +public class ExtendMe : global::System.IDisposable { ... public int Part1() { ... @@ -2468,7 +2474,7 @@ The C# proxy class becomes a partial class:-public partial class ExtendMe : IDisposable { +public partial class ExtendMe : global::System.IDisposable { ... public int Part1() { ... @@ -2483,7 +2489,7 @@ You can then of course declare another part of the partial class elsewhere, for-public partial class ExtendMe : IDisposable { +public partial class ExtendMe : global::System.IDisposable { public int Part2() { return 2; } @@ -2535,7 +2541,7 @@ The generated C# proxy class will instead be:+-public class ExtendMe : IDisposable { +public class ExtendMe : global::System.IDisposable { ... public int Part3() { return 3; diff --git a/Doc/Manual/Extending.html b/Doc/Manual/Extending.html index 5ea4e51f4..a8c15fe03 100644 --- a/Doc/Manual/Extending.html +++ b/Doc/Manual/Extending.html @@ -2761,8 +2761,8 @@ Within SWIG wrappers, there are five main sections. These are (in order)- begin: This section is a placeholder for users to put code at the beginning of the C/C++ wrapper file.
- runtime: This section has most of the common SWIG runtime code.
- header: This section holds declarations and inclusions from the .i file. -
- wrapper: This section holds all the wrappering code. -
- init: This section holds the module initalisation function +
- wrapper: This section holds all the wrapper code. +
- init: This section holds the module initialisation function (the entry point for the interpreter).
@@ -3005,7 +3005,7 @@ virtual int functionWrapper(Node *n) { /* write typemaps(in) */ .... - /* write constriants */ + /* write constraints */ .... /* Emit the function call */ @@ -3350,10 +3350,10 @@ Note that if a runtime test is available, a message "(with run test)" is display
$ make check-python-test-suite checking python test-suite -checking testcase argcargvtest (with run test) under python -checking testcase python_autodoc under python -checking testcase python_append (with run test) under python -checking testcase callback (with run test) under python +checking python testcase argcargvtest (with run test) +checking python testcase python_autodoc +checking python testcase python_append (with run test) +checking python testcase callback (with run test)@@ -3496,6 +3496,12 @@ The syntax for setting environment variables varies from one shell to the next, make ret_by_value.ctest SWIG_FEATURES="-debug-tmsearch"
+There is also a special 'errors' test-suite which is a set of regression tests checking SWIG warning and error messages. +It can be run in the same way as the other language test-suites, replacing [lang] with errors, such as make check-errors-test-suite. +The test cases used and the way it works is described in Examples/test-suite/errors/Makefile.in. +
+38.10.13 Documentation
diff --git a/Doc/Manual/Go.html b/Doc/Manual/Go.html index 7a55a4364..226acaabf 100644 --- a/Doc/Manual/Go.html +++ b/Doc/Manual/Go.html @@ -55,7 +55,7 @@ there is no convenient way to call C++ code. SWIG fills this gap.There are (at least) two different Go compilers. One is the gc -compiler, normally invoked under the names 6g, 8g, or 5g. The other +compiler, normally invoked via the go tool. The other is the gccgo compiler, which is a frontend to the gcc compiler suite. The interface to C/C++ code is completely different for the two Go compilers. SWIG supports both, selected by a command line option. @@ -80,7 +80,7 @@ code for gccgo, you should also use the -gccgo option.
-These are the command line options for SWIG's GO module. They can +These are the command line options for SWIG's Go module. They can also be seen by using:
@@ -108,7 +108,7 @@ swig -go -help-gccgo Generate code for gccgo. The default is to generate code for - 6g/8g/5g. + the gc compiler.@@ -117,26 +117,35 @@ swig -go -help package name is the SWIG module name. ++ +-use-shlib +Tell SWIG to emit code that uses a shared library. This is only + meaningful for the gc compiler, which needs to know at compile time + whether a shared library will be used. ++ + -soname %lt;name%gt; Set the runtime name of the shared library that the dynamic linker should include at runtime. The default is the package name with ".so" appended. This is only used when generating code for - 6g/8g/5g; when using gccgo, the equivalent name will be taken from - the + the gc compiler; when using gccgo, the equivalent name will be taken from + the-soname
option passed to the linker.-soname
option passed to the linker. Using this + option implies the -use-shlib option. ++ -go-pkgpath <pkgpath> +When generating code for gccgo, set the pkgpath to use. This + corresponds to the -fgo-pkgpath option to gccgo. - - -go-prefix <prefix> When generating code for gccgo, set the prefix to use. This - corresponds to the -fgo-prefix option to gccgo. -- @@ -165,25 +174,56 @@ may be helpful to include it in your code, compiled with the usual C or C++ compiler.-long-type-size <s> -Set the size for the C/C++ type long. This controls - whether long is converted to the Go type int32 - or int64. The <s> argument should be 32 or 64. + corresponds to the -fgo-prefix option to gccgo. + If -go-pkgpath is used, -go-prefix will be + ignored.- If using the gc compiler, MODULE_gc.c will contain C code which should -be compiled with the C compiler distributed as part of the gc compiler: 6c, 8c, -or 5c. It should then be combined with the compiled MODULE.go using -gopack. This file will not be generated when using gccgo. +be compiled with the C compiler distributed as part of the gc +compiler. It should then be combined with the compiled MODULE.go +using gopack. This file will not be generated when using gccgo.
-A typical command sequence would look like this: +Most Go programs are built using the go tool. The go tool has limited +support for SWIG. To use it, put your SWIG interface into a file with +the extension .swig, or, if you are wrapping C++ code, .swigcxx. Put +that file in a GOPATH/src directory as usual for Go sources. Put +other interface code in the same directory with extensions of .c and +.cxx. The go build command and go install commands will automatically +run SWIG for you and will build the interface code. +
+ ++You can also use SWIG directly yourself. When using the gc compiler +version 1.2 or later, or when using gccgo, the code generated by SWIG +can be linked directly into the Go program. A typical command +sequence when using the gc compiler would look like this:
+ +% swig -go example.i +% gcc -c code.c # The C library being wrapped. +% gcc -c example_wrap.c +% go tool 6g example.go +% go tool 6c example_gc.c +% go tool pack grc example.a example.6 example_gc.6 code.o example_wrap.o +% go tool 6g main.go +% go tool 6l main.6 ++You can also put the wrapped code into a shared library, and when +using the gc compiler before version 1.2 this is the only supported +option. A typical command sequence for this approach would look like +this: +
+ ++% swig -go -use-shlib example.i % gcc -c -fpic example.c % gcc -c -fpic example_wrap.c % gcc -shared example.o example_wrap.o -o example.so -% 6g example.go -% 6c example_gc.c -% gopack grc example.a example.6 example_gc.6 -% 6g main.go # your code, not generated by SWIG -% 6l main.6 +% go tool 6g example.go +% go tool 6c example_gc.c +% go tool pack grc example.a example.6 example_gc.6 +% go tool 6g main.go # your code, not generated by SWIG +% go tool 6l main.622.3 A tour of basic C/C++ wrapping
@@ -454,12 +494,12 @@ uses a given C/C++ type.long -int32 or int64, depending on -long-type-size +int64 unsigned long -uint32 or uint64, depending on -long-type-size +uint64 @@ -626,9 +666,31 @@ func (arg SwigcptrWrapped_MyClass) GetAValue() (int, bool) { few, then you might as well define your own struct that includes the swig-wrapped object, instead of adding methods to the swig-generated object. - This only works if your wrappers do not need to import other go modules. -There is at present no way to insert import statements in the correct place -in swig-generated go. If you need to do that, you must put your go code -in a separate file.
+If you need to import other go packages, you can do this with +
+%go_import
. For example,+++%go_import("fmt", _ "unusedPackage", rp "renamed/package") + +%insert(go_wrapper) %{ + +func foo() { + fmt.Println("Some string:", rp.GetString()) +} + +// Importing the same package twice is permitted, +// Go code will be generated with only the first instance of the import. +%go_import("fmt") + +%insert(go_wrapper) %{ + +func bar() { + fmt.Println("Hello world!") +} + +%} ++