This chapter gives you a brief overview about the SWIG implementation of the C++14 standard. There isn't much in C++14 that affects SWIG, however, work has only just begun on adding C++14 support.
Compatibility note: SWIG-4.0.0 is the first version to support any C++14 features.
C++14 added binary integer literals and SWIG supports these. Example:
int b = 0b101011;
C++14 added the ability to specify auto for the return type of a function and have the compiler deduce it from the body of the function (in C++11 you had to explicitly specify a trailing return type if you used auto for the return type).
SWIG parses these types of functions, but with one significant limitation: SWIG can't actually deduce the return type! If you want to wrap such a function you will need to tell SWIG the return type explicitly.
The trick for specifying the return type is to use %ignore to tell SWIG to ignore the function with the deduced return type, but first provide SWIG with an alternative declaration of the function with an explicit return type. The generated wrapper will wrap this alternative declaration, and the call in the wrapper to the function will call the actual declaration. Here is an actual example:
std::tuple<int, int> va_static_cast();
%ignore va_static_cast();
#pragma SWIG nowarn=SWIGWARN_CPP14_AUTO
%inline %{
#include <tuple>
auto va_static_cast() {
return std::make_tuple(0, 0);
}
%}
For member methods the trick is to use %extend to redeclare the method and call it as follows:
%extend X {
const char * a() const { return $self->a(); }
}
%inline %{
struct X {
auto a() const {
return "a string";
}
};
%}
Compatibility note: SWIG-4.2.0 first introduced support for functions declared with an auto return without a trailing return type. SWIG 4.4.0 added support for forward declarations of such functions.
C++14 lifted the restriction that lambda parameters be explicit types and allowed auto as a parameter type, making the lambda a templated function object whose operator() deduces each auto parameter at the call site. SWIG parses generic lambdas, but - like non-templated Lambda functions and expressions - they are not currently automatically wrapped. Users should write additional code to call the lambda from an ordinary wrapped function as a workaround, for example:
%inline %{
auto twice = [](auto x) { return x + x; };
auto add = [](auto a, auto b) { return a + b; };
int run_twice(int x) { return twice(x); }
int run_add(int a, int b) { return add(a, b); }
%}
Compatibility note: SWIG-4.5.0 is the first version to parse generic lambdas with auto parameters.
C++14 added variable templates - templated constexpr (or const) variables whose value depends on the template arguments. The pattern mirrors the _v aliases the standard library uses for type traits: a typed compile time constant derived from a template parameter, written once and instantiated wherever the parameter changes. SWIG parses variable templates, and a %template instantiation of one is wrapped as a read only variable holding the value:
%inline %{
template<typename T>
constexpr int bits_in = sizeof(T) * 8;
%}
%template(bits_in_char) bits_in<char>; // wraps as read only int = 8
Non-type template parameters are also accepted, so a variable template can hold the result of a compile time computation indexed by an integer. Precomputing the result at instantiation avoids the work being repeated on each call at runtime:
%inline %{
constexpr int compute_factorial(int n) {
return n <= 1 ? 1 : n * compute_factorial(n - 1);
}
template<int N>
constexpr int factorial = compute_factorial(N);
%}
%template(factorial_5) factorial<5>; // 120
%template(factorial_10) factorial<10>; // 3628800
Compatibility note: SWIG-3.0.0 is the first version to parse C++14 variable templates and wrap a %template instantiation of one as a read only variable.