Back to Swift

C++ Interoperability Status

docs/CppInteroperability/CppInteroperabilityStatus.md

latest12.7 KB
Original Source

** ‼️ The official C++ interoperability documentation and status page is live at Swift.org and provides an up-to-date guide for mixing Swift and C++ ‼️ **

C++ Interoperability Status

Swift has some experimental ability to interoperate with C++. This document provides an overview of the status of the Swift and C++ interoperability support.

C++ to Swift Interoperability Status

Swift has the experimental ability to import a large subset of C++. This section of the document describes which C++ language and standard library features can be imported and used from Swift in an experimental manner.

Example

The following example demonstrates several interop features. It compiles and runs on main.

C++
// cxx-types.h (mapped to CxxTypes module in module.modulemap)
#include <algorithm>
#include <vector>

using V = std::vector<long>;
Swift
// main.swift
import CxxTypes
import CxxStdlib

// We can extend C++ types in Swift.
extension V : RandomAccessCollection {
  public var startIndex: Int { 0 }
  public var endIndex: Int { size() }
}

// Create a vector with some data.
var numbers = V(4)
std.fill(numbers.beginMutating(), numbers.endMutating(), 41)

// Transform it using C++.
std.transform(numbers.beginMutating(), numbers.endMutating(),
              numbers.beginMutating()) { (element: Int) in
  return element + 1
}

// Loop over it in Swift.
for (index, element) in numbers.enumerated() {
  print("v[\(index)] = \(element)")
}

// We can also use anything in RandomAccessCollection, such as map and zip.
let strings = numbers.map { "\($0)" }
for (s, n) in zip(strings, numbers) {
  print("\(s) = \(n)")
}

Importing C++

There are currently two experimental ways to import C++ into Swift:

  • Clang modules: can be imported into Swift. This requires a module map.
  • Bridging header: can be imported into Swift. Headers included in the bridging header will be imported. Please note that support for importing C++ 20 modules isn’t implemented.

Both CMake and the Swift package manager can be configured to invoke Swift with the correct arguments to import C++ headers.

Note: C++ code is imported using the Objective-C++ language mode on Apple platforms.

Experimental C++ Language Support

This status table describes which of the following C++ language features can be used in Swift:

C++ Language FeatureImplemented Experimental Support For Using It In Swift
Top-level functionsYes
EnumerationsYes. That includes enum class
Struct / Class typesYes - as value types, except for types without a copy constructor. Partial experimental support for importing a C++ struct/class as a reference type
Typedefs / Type aliasesYes
Global VariablesYes
NamespacesYes
Inline NamespacesYes, with some known issues (#58217)
ExceptionsNo. Uncaught exceptions that propagate into Swift frames are UB.
FieldsYes
Member functionsYes. Some value category overloads aren't imported
Virtual Member FunctionsNo
OperatorsYes, with some known issues
Subscript OperatorsYes
ConstructorsYes. That includes implicit constructors
DestructorYes. C++ destructors are invoked automatically when the value is no longer used in Swift
Copy constructor / copy assignment operatorYes. Swift invokes the underlying copy constructor when copying a C++ value
Move constructor / move assignment operatorNo
Base class member functions / operatorsYes, with some known issues
Function templatesYes
Class templatesYes
Dependent typesPartially: imported as Any
Availability AttributesYes

The following C++ code patterns or language features have specific mappings to Swift language features when imported in Swift:

C++ Language FeatureImported Into Swift
get/set member functionsImported as computed property (starting from Swift-5.7)
const/non-const member function overload setBoth overloads are imported as a method, with non-const method being renamed to mutating… (starting from Swift-5.7). The renaming logic will change in a future version of Swift, and non-const methods won't be renamed

Unless stated otherwise (i.e., imported reference types) all Swift features work with imported types. For example: use in generic contexts, protocol conformance, extensions, etc.

C++ Standard Library Support

Parts of libc++ can be imported and used from Swift. C++ standard library types are bridged directly to Swift, and there is not automatic bridging to native Swift types. This means that if an imported C++ API returns std::string, you will get a std::string value in Swift as well, and not Swift's String.

This status table describes which of the following C++ standard library features have some experimental support for using them in Swift. Please note that this is not a comprehensive list and other libc++ APIs that use the above supported C++ language features could be imported into Swift.

C++ Standard Library FeatureCan Be Used From Swift
std::stringYes
std::vectorYes

Known Issues

Inline Namespaces

Swift to C++ Interoperability Status

This section of the document describes which Swift language and standard library features can be imported and used from C++.

Importing Swift

Swift has some experimental support for generating a header that can be imported by C++.

Swift Language Support

This status table describes which of the following Swift language features have some experimental support for using them in C++.

Functions

Swift functions can be called from C++, with some restrictions. See this table for details:

Swift Language FeatureImplemented Experimental Support For Using It In C++
Top-level @_cdecl functionsYes
Top-level Swift functionsYes
Swift MethodsYes (see the Methods section below for more details)
Primitive parameter or result typesYes
Swift struct/enum/class parameter or result typesYes
inout parametersYes
C++ struct/class parameter or result typesYes
Objective-C @interface parameter or result typesYes
Swift closure parameter or result typesNo
Swift protocol type parameter or result typesNo
SIMD type parameter or result typesNo
Variadic parametersNo
Multiple return valuesNo

Structs

Swift Language FeatureImplemented Experimental Support For Using It In C++
Fixed layout structsYes
Resilient / opaque structsYes
Copy and destroy semanticsYes
InitializersYes (except for throwing initializers)

Enums

Swift Language FeatureImplemented Experimental Support For Using It In C++
Fixed layout enumsYes
Resilient / opaque enumsYes
Copy and destroy semanticsYes
CreationYes
Enums with associated valuesPartially: only support structs and enums
Enums with raw valuesYes
Indirect enumsNo

Class types

Swift Language FeatureImplemented Experimental Support For Using It In C++
Class reference valuesYes
ARC semanticsYes (C++ copy constructor,assignment operator, destructor perform ARC operations)
InitializersYes (except for throwing initializers)

Methods

Swift Language FeatureImplemented Experimental Support For Using It In C++
Instance methodsYes on structs and enums. Instance methods on class types are partially supported (virtual calls won't be virtual due to a bug right now)
Static methodsNo

Properties

Swift Language FeatureImplemented Experimental Support For Using It In C++
Getter accessorsYes, via get<name>. Boolean properties that start with is or has are remapped directly to a getter method using their original name
Setter accessorsYes, via set<name>
Mutation accessorsNo
Static property accessorsYes

Generics

Swift Language FeatureImplemented Experimental Support For Using It In C++
Generic functionsPartially, only without generic constraints
Generic methodsPartially, only without generic constraints
Generic struct typesPartially, only without generic constraints and less than 4 generic parameters
Generic enum typesPartially, only without generic constraints and less than 4 generic parameters
Generic class typesNo

Swift standard library

This status table describes which of the following Swift standard library APIs have some experimental support for using them in C++.

Swift Library TypeCan be used from C++
StringCan be used as a type in C++. APIs in extensions are not exposed to C++. Conversion between std.string is not yet supported
Array<T>Can be used as a type in C++. Ranged for loops are supported. Limited set of APIs in some extensions are exposed to C++.
Optional<T>Can be used as a type in C++. Can be constructed. get extracts the optional value and it's also implicitly castable to bool.