File: CppInteroperabilityStatus.md

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (222 lines) | stat: -rw-r--r-- 13,035 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
[** ‼️ 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/apple/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/apple/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/apple/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`.  |