mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
223 lines
13 KiB
Markdown
223 lines
13 KiB
Markdown
[** ‼️ 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++ ‼️ **](https://www.swift.org/documentation/cxx-interop/status)
|
||
|
||
# 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 Feature** | **Implemented Experimental Support For Using It In Swift** |
|
||
|---------------------------------------------|---------------------------------------------------------------|
|
||
| Top-level functions | Yes |
|
||
| Enumerations | Yes. That includes `enum class` |
|
||
| Struct / Class types | Yes - 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 aliases | Yes |
|
||
| Global Variables | Yes |
|
||
| Namespaces | Yes |
|
||
| Inline Namespaces | Yes, with some known issues ([#58217](https://github.com/swiftlang/swift/issues/58217)) |
|
||
| Exceptions | No. Uncaught exceptions that propagate into Swift frames are UB. |
|
||
| Fields | Yes |
|
||
| Member functions | Yes. Some value category overloads aren't imported |
|
||
| Virtual Member Functions | No |
|
||
| Operators | Yes, with some known issues |
|
||
| Subscript Operators | Yes |
|
||
| Constructors | Yes. That includes implicit constructors |
|
||
| Destructor | Yes. C++ destructors are invoked automatically when the value is no longer used in Swift |
|
||
| Copy constructor / copy assignment operator | Yes. Swift invokes the underlying copy constructor when copying a C++ value |
|
||
| Move constructor / move assignment operator | No |
|
||
| Base class member functions / operators | Yes, with some known issues |
|
||
| Function templates | Yes |
|
||
| Class templates | Yes |
|
||
| Dependent types | Partially: imported as Any |
|
||
| Availability Attributes | Yes |
|
||
|
||
|
||
The following C++ code patterns or language features have specific mappings to Swift language features when imported in Swift:
|
||
|
||
|
||
| **C++ Language Feature** | **Imported Into Swift** |
|
||
|------------------------------------------------------|------------------------------------------------------------------------------------------|
|
||
| `get`/`set` member functions | Imported as computed property (starting from Swift-5.7) |
|
||
| `const`/non-`const` member function overload set | Both 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 Feature** | **Can Be Used From Swift** |
|
||
|------------------------------------|----------------------------------------------|
|
||
| `std::string` | Yes |
|
||
| `std::vector` | Yes |
|
||
|
||
## Known Issues
|
||
|
||
### Inline Namespaces
|
||
- [#58217](https://github.com/swiftlang/swift/issues/58217): Swift's typechecker currently doesn't allow calling a function from an inline namespace when it's referenced through the parent namespace. Example of a test that fails: https://github.com/swiftlang/swift/blob/main/test/Interop/Cxx/namespace/inline-namespace-function-call-broken.swift
|
||
|
||
|
||
## 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 Feature** | **Implemented Experimental Support For Using It In C++** |
|
||
|--------------------------------|----------------------------------------------------------|
|
||
| Top-level `@_cdecl` functions | Yes |
|
||
| Top-level Swift functions | Yes |
|
||
| Swift Methods | Yes (see the **Methods** section below for more details) |
|
||
| Primitive parameter or result types | Yes |
|
||
| Swift `struct`/`enum`/`class` parameter or result types | Yes |
|
||
| `inout` parameters | Yes |
|
||
| C++ `struct`/`class` parameter or result types | Yes |
|
||
| Objective-C `@interface` parameter or result types | Yes |
|
||
| Swift closure parameter or result types | No |
|
||
| Swift protocol type parameter or result types | No |
|
||
| SIMD type parameter or result types | No |
|
||
| Variadic parameters | No |
|
||
| Multiple return values | No |
|
||
|
||
**Structs**
|
||
|
||
| **Swift Language Feature** | **Implemented Experimental Support For Using It In C++** |
|
||
|--------------------------------|----------------------------------------------------------|
|
||
| Fixed layout structs | Yes |
|
||
| Resilient / opaque structs | Yes |
|
||
| Copy and destroy semantics | Yes |
|
||
| Initializers | Yes (except for throwing initializers) |
|
||
|
||
**Enums**
|
||
|
||
| **Swift Language Feature** | **Implemented Experimental Support For Using It In C++** |
|
||
|------------------------------|----------------------------------------------------------|
|
||
| Fixed layout enums | Yes |
|
||
| Resilient / opaque enums | Yes |
|
||
| Copy and destroy semantics | Yes |
|
||
| Creation | Yes |
|
||
| Enums with associated values | Partially: only support structs and enums |
|
||
| Enums with raw values | Yes |
|
||
| Indirect enums | No |
|
||
|
||
**Class types**
|
||
|
||
| **Swift Language Feature** | **Implemented Experimental Support For Using It In C++** |
|
||
|--------------------------------|----------------------------------------------------------|
|
||
| Class reference values | Yes |
|
||
| ARC semantics | Yes (C++ copy constructor,assignment operator, destructor perform ARC operations) |
|
||
| Initializers | Yes (except for throwing initializers) |
|
||
|
||
**Methods**
|
||
|
||
| **Swift Language Feature** | **Implemented Experimental Support For Using It In C++** |
|
||
|--------------------------------|----------------------------------------------------------|
|
||
| Instance methods | Yes 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 methods | No |
|
||
|
||
**Properties**
|
||
|
||
| **Swift Language Feature** | **Implemented Experimental Support For Using It In C++** |
|
||
|--------------------------------|----------------------------------------------------------|
|
||
| Getter accessors | Yes, via `get<name>`. Boolean properties that start with `is` or `has` are remapped directly to a getter method using their original name |
|
||
| Setter accessors | Yes, via `set<name>` |
|
||
| Mutation accessors | No |
|
||
| Static property accessors | Yes |
|
||
|
||
**Generics**
|
||
|
||
| **Swift Language Feature** | **Implemented Experimental Support For Using It In C++** |
|
||
|------------------------------|----------------------------------------------------------|
|
||
| Generic functions | Partially, only without generic constraints |
|
||
| Generic methods | Partially, only without generic constraints |
|
||
| Generic `struct` types | Partially, only without generic constraints and less than 4 generic parameters |
|
||
| Generic `enum` types | Partially, only without generic constraints and less than 4 generic parameters |
|
||
| Generic `class` types | No |
|
||
|
||
### 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 Type** | **Can be used from C++** |
|
||
|--------------------------------|----------------------------------------------------------|
|
||
| `String` | Can 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`. |
|