SWIG and C++14

# 8 SWIG and C++14

- Introduction
- Core language changes
  - Binary integer literals
  - Return type deduction
  - Generic lambdas
  - Variable templates
- Standard library changes

## 8.1 Introduction

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.

## 8.2 Core language changes

### 8.2.1 Binary integer literals

C++14 added binary integer literals and SWIG supports these. Example:

    int b = 0b101011;

### 8.2.2 Return type deduction

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.

### 8.2.3 Generic lambdas

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.

### 8.2.4 Variable templates

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.

## 8.3 Standard library changes