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 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417
|
[** ‼️ The official C++ interoperability documentation is live at Swift.org and provides an up-to-date guide for mixing Swift and C++ ‼️ **](https://www.swift.org/documentation/cxx-interop/)
# Guide: Calling Swift APIs from C++
A Swift library author might want to expose their interface to C++, to allow a C++ codebase to interoperate with the Swift library. This document describes how this can be accomplished, by first describing how Swift can expose its interface to C++, and then going into the details on how to use Swift APIs from C++.
**NOTE:** This is a work-in-progress, living guide document for how Swift APIs can be imported and used from C++. This document reflects the current state of the experimental design, and it will evolve over time
as this feature will go through Swift's evolution process. This document does not specify the final target
design for the Swift to C++ interoperability layer.
**NOTE:** This document does not go over the following Swift language features yet:
* Closures
* overriden methods/properties in classes
* Existential types (any P)
* Nested types
* Operators
* Tuples & functions returning multiple parameters
* class subclass generic constraint
* Type casting
* Recursive/indirect enums
* Associated types in generic where clauses
* Error handling
* Opaque return type `-> some P` (should we not support it)
* Character type & character literal
## Exposing Swift Codebase to C++
A Swift codebase is organized into units called modules. A module typically corresponds to a specific Xcode or Swift package manager target. Swift can generate a module interface file that presents a source view of the public Swift interface provided by the module. In addition to a Swift module interface, Swift can also generate a header file that contains C++ functions and classes that allow us to work with the Swift functions and types. We can import this header file into our C++ program to start using the Swift APIs from C++.
### Compiler Requirements
The header files generated by the Swift compiler can only be compiled by the Clang compiler, as
the generated header relies on specific ABI attributes that are only supported by Clang.
### C++ Language And Library Requirements
Importing Swift APIs into C++ requires certain C++ features introduced in newer C++ language standards. The following C++ standards are expected to work:
* C++20. It is the recommended standard, as C++ 20 concepts enable type checking for imported Swift generic APIs.
* C++17 and C++14 are supported with some restrictions. Some generic APIs might not be available prior to C++20.
## Importing Swift Modules
A Swift module can be imported over into C++ by using an `#include` that imports the generated C++ header for that module:
```swift
// Swift module 'MyModule'
func myFunction();
// C++
#include "MyModule-Swift.h"
```
A C++ namespace is used to represent the Swift module. Namespacing provides a better user experience for accessing APIs from different modules as it encapsulates the different module interfaces in their own namespace. For example, in order to use a Swift module called `MyModule` from C++, you have to go through the `MyModule::` namespace in C++:
```c++
// C++
#include "MyModule-Swift.h"
int main() {
MyModule::myFunction(); // calls into Swift.
return 0;
}
```
## Calling Swift Functions
Swift functions that are callable from C++ are available in their corresponding module namespace. Their return and parameter types are transcribed to C++ primitive types and class types that represents the underlying Swift return and parameter types.
Fundamental primitive types have a C++ fundamental type that represents them in C++:
|Swift Type |C++ Type |C Type (if different) | |target specifc |
|--- |--- |--- |--- |--- |
|Void (or no return) |void | | | |
|Int |swift::Int |ptrdiff_t |long or long long (windows) |YES |
|UInt |swift::UInt | size_t |unsigned long or unsigned long long (windows) |YES |
|Float |float | | | |
|Double |double | | | |
| | | | | |
|CInt |int | | | |
|CUnsignedInt |unsigned int | | | |
|CShort |short | | | |
|CUnsignedShort |unsigned short | | | |
|CLong |long | | | |
|CUnsignedLong |unsigned long | | | |
|CLongLong |long long | | | |
|CUnsignedLongLong |unsigned long long | | | |
| | | | | |
|OpaquePointer |void * | | | |
|UnsafePointer<T> |const T * | | | |
|UnsafeMutablePointer<T> |T * | | | |
**NOTES**: Need static_assert that std::is_same(size_t, unsigned long) or unsigned long long to ensure we can match the right type metadata using a template specialization.
A function that takes or return primitive Swift types behaves like any other C++ function, and you can pass in the C++ types when calling them, just as you’d expect.
```swift
// Swift module 'MyModule'
func myFunction(x: float, _ c: Int) -> Bool
```
```c++
// C++
#include "MyModule-Swift.h"
int main() {
return !MyModule::myFunction(2.0f, 3); // myFunction(float, swift::Int) -> bool
}
```
### In-Out Parameters
A Swift `inout` parameter is mapped to a C++ reference type in the C++ function signature that’s generated in the C++ interface. You can then pass in a value directly to an `inout` parameter from C++ side, like the example below:
```swift
// Swift module 'MyModule'
func swapTwoInts(_ a: inout Int, _ b: inout Int)
```
```c++
// C++ interface snippet
void swapTwoInts(swift::Int &a, swift::Int &b) noexcept;
// C++
#include "MyModule-Swift.h"
void testSwap() {
swift::Int x = 0, y = 42;
MyModule::swapTwoInts(x, y);
}
```
### Function Overloading
Swift allows you to specify which overload of the function you would like to call using argument labels. For example, the following snippet is explicitly calling the second definition of `greet` because of the call using `greet(person:,from:)` argument labels:
```swift
func greet(person: String, in city: String) {
print("Hello \(person)! Welcome to \(city)!")
}
func greet(person: String, from hometown: String) {
print("Hello \(person)! Glad you could visit from \(hometown).")
}
greet(person: "Bill", from: "San Jose") // calls the second overload of greet.
```
C++ only allows us to select which overload of the function we want to call by using type-based overloading. In cases where type-based overloading isn’t sufficient, like when the arguments have the same type but a different argument label, you can use the `exposed` attribute to provide a different C++ name for the C++ function, like in the following example:
```swift
@expose(C++, greetPersonIn)
func greet(person: String, in city: String) {
print("Hello \(person)! Welcome to \(city)!")
}
@expose(C++, greetPersonFrom)
func greet(person: String, from hometown: String) {
print("Hello \(person)! Glad you could visit from \(hometown).")
}
```
### Default Parameter Values
Default parameter values allow you to provide a default value for Swift function parameter, allowing the program to not specify it when calling such function. The generated C++ interface for a Swift function contains default parameter values as well, just like in the following example:
```swift
// Swift module 'MyModule'
func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {
}
```
```c++
// C++ interface snippet
void someFunction(swift::Int parameterWithoutDefault, swift::Int parameterWithDefault = 12) noexcept;
// C++
#include "MyModule-Swift.h"
using namespace MyModule;
void testSwap() {
someFunction(3, 6); // parameterWithDefault is 6
someFunction(4); // parameterWithDefault is 12
}
```
Swift default parameter values that are set to a `#file` or `#line` call site specific literal are not represented in the generated C++ interface. The user need to pass them explicitly from the C++ call site instead.
**TODO:** Any constraints for default parameter values?
**OPEN QUESTIONS:** Are there any problems here?
* YES : a problem with Swift allowing non-last parameter orders.
### Variadic Parameters
A variadic parameter is a parameter that accepts zero or more values of the specified type. It gets exposed in C++ using a `swift::variadic_parameter_pack` class template. You can pass values to a variadic parameter using the C++ initializer list syntax. For example, the following Swift function with a `Double` variadic parameter:
```swift
func arithmeticMean(_ numbers: Double...) -> Double {
...
}
```
can be called from C++ using a C++ initializer list:
```c++
arithmeticMean({ 1.0, 2.0 });
```
## Using Swift Structure Types
Swift structures that are usable from C++ are available in their corresponding module namespace. They’re bridged over as a C++ `class` that has an opaque representation and layout whose size and alignment matches the size and alignment of the Swift structure.
You can construct an instance of a structure using the static `init` method in the C++ class:
```swift
// Swift module 'Weather'
struct WeatherInformation {
var temperature: Int
}
```
```c++
// C++ use site.
#include "Weather-Swift.h"
int main() {
auto weather = Weather::WeatherInformation::init(/*temperature=*/ 25);
}
```
### Initialization
Swift’s structures that have a default initializer are given a default C++ constructor. For example, the following structure:
```swift
struct ScreenSize {
var width = 0
var height = 0
}
```
Will have a default initializer that will initialize a `width` and `height` to zero, which you can then use from C++ directly:
```c++
void constructScreenSize() {
auto size = ScreenSize();
// size.width and size.height is 0
}
```
The other initializers are bridged over as static `init` methods. The C++ initializers use type-based overloading to select the right overload for the initializer.
For example, given the following structure with two initializers:
```swift
struct Color {
let red, green, blue: Float
public init(red: Float, green: Float, blue: Float) {
self.red = red
self.green = green
self.blue = blue
}
public init(white: Float) {
self.red = white
self.green = white
self.blue = white
}
}
```
The following C++ `init` methods will be available:
```c++
class Color {
public:
Color() = delete;
static Color init(float red, float green, float blue);
static Color init(float white);
};
```
**NOTE**: Swift doesn’t allow calling constructor without argument labels. Is that a problem for us?
### Providing renamed C++ overloads for Swift Initializers
The C++ `init` overloads for Swift initializers can sometimes conflict between each other because C++ doesn’t allow us to use argument labels to select the correct overload, and so instead we need to rely on the type of the argument when calling it from C++. In order to avoid ambiguities on the C++ side, you can rename one specific initializer using something like the `@expose` attribute.
As an example, this structure renames its second `init` overload in C++ to expose them both to C++:
```swift
// Swift module 'Weather'
struct Celcius {
var temperatureInCelcius: Double
// FEEDBACK: could provide a constructor here?
// NOTE: concern about encouraging people not to use labels
init(_ t: Double) { self.temperatureInCelcius = t }
// FEEDBACK: could the compiler construct the 'initFromFahrenheit' c++ name?
@expose(c++, initFromFahrenheit)
init(fromFahrenheit fahrenheit: Double) { ... }
}
```
Both initializers can then be used from C++:
```c++
#include "Weather-Swift.h"
using namespace Weather;
void makeSunnyDay() {
auto morningTemperature = Celcius::init(25);
auto noonTemperature = Celcius::initFromFahrenheit(90);
}
```
**NOTE**: The compiler should warn here about overload ambiguities.
### Convenience Initialization of Swift Structures that conform to ExpressibleBy...Literal protocol
Certain types like Swift’s `String` and `Array` are bridged over with convenience initializers that are inferred from their conformance to the `ExpressibleByStringLiteral` and the `ExpressibleByArrayLiteral` protocols. In general, any type that conforms to a protocol like `ExpressibleByStringLiteral` will receive a C++ constructor in it’s interface that resembles the following constructor for Swift’s `String` type:
```c++
String(const char *value) {
*this = String::init(value);
}
```
Similarly, any type that conforms to `ExpressibleByArrayLiteral` will receive a C++ constructor that takes in a C++ initializer list so that it can be initialized from a C++ array literal.
### Resilient Swift Structures
Swift resilient structures are bridged over as a C++ class that boxes the Swift value on the heap. Their generated C++ interface resembles the C++ interface for a non-resilient structure, so all the methods and properties can be accessed in the same manner. For example, you can call methods and access the properties on `Foundation::URL` , which is a resilient Swif structure, in the same manner as you would for any other fixed layout Swift structure:
```c++
#include "Foundation-Swift.h"
using namespace Weather;
void workWithURL() {
auto url = Foundation::URL::init("https://swift.org");
std::cout << "Is File URL:" << url.isFileURL() << "\n";
auto absoluteURL = URL.absoluteURL();
}
```
The boxing implies that the following operations will allocate and store a new value on the heap:
* Returning a value from a call to a Swift method/function allocates a new value on the heap.
* Returning a value from a getter call to a Swift property `get` accessor allocates a new value on the heap.
* Creating a new instance of a resilient structure in C++ using the static `init` method allocates a new value on the heap.
* Copying a C++ `class` that represents a resilient Swift structure using a C++ copy constructor allocates a new value on the heap.
**NOTE**: A fixed-layout structure that contains a resilient structure as a stored property is also boxed on the C++ side.
## Calling Swift Methods
Swift’s structures, enumerations and classes can define instance methods. An instance method that’s declared in a Swift type gets its own C++ member function declaration in the C++ class that corresponds to the underlying Swift type in the generated C++ interface for a Swift module.
Instance methods in structures and enumerations are marked as `const` in C++, unless they’re marked as `mutating` in Swift. Here's how one could call a mutating method on a Swift structure from C++:
```swift
// Swift module 'Geometry'
struct Point {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
x += deltaX
y += deltaY
}
}
```
```c++
// C++ use site:
#include "Geometry-Swift.h"
using namespace Geometry;
int main() {
auto point = Point();
point.moveBy(1.0, 2.0);
std::cout << "The point is now at " << point.getX() << ", " << point.getY() << "\n";
// Prints "The point is now at 1.0, 2.0"
return 0;
}
```
Calling `mutating` methods on a value that is declared as `const` is not allowed:
```
int main() {
const auto point = Point();
point.moveBy(1.0, 2.0);
//` reports a compile time error.`
}
```
### Static Methods
A static method declared in a Swift structure or enumeration gets its own C++ static member function declaration in the C++ class that corresponds to the underlying Swift type in the generated C++ interface for a Swift module. It can be called using its qualified name directly from C++, like in the following example:
```swift
// Swift module 'Geometry'
struct Rectangle {
var left, right: Point
static func computeDeviceScreenSize() -> Rectangle {
...
}
}
```
```c++
// C++ use site:
#include "Geometry-Swift.h"
int main() {
auto screenSize = Geometry::Rectangle::computeDeviceScreenSize();
// Use screen size...
return 0;
}
```
**TODO:** Dispatching overriding / class methods
## Using Swift Enumeration Types
A Swift enumeration is imported as class in C++. That allows C++ to invoke methods and access properties that the enumeration provides. Each enumeration case is represented by a static variable that can be used in a switch to match the case of the enum, and to construct new enums values as well.
For example, given the following enum:
```swift
// Swift module 'Navigation'
enum `CompassDirection {`
case north
case south
case east
case west
}
```
The following interface will be generated:
```c++
// "Navigation-Swift.h" - C++ interface for Swift's Navigation module.
class CompassDirection {
public:
inline const static struct { ... } north;
inline const static struct { ... } south;
inline const static struct { ... } east;
inline const static struct { ... } west;
private:
// type representation details.
...
};
```
This will let you construct enumeration values from C++ using the C++ call operator on the case:
```c++
#include "Navigation-Swift.h"
void testConstructEnumValue() {
auto direction = CompassDirection::north();
}
```
### Matching Swift Enumeration Values with a C++ Switch Statement
The C++ values that correspond to Swift enumeration case values can be used directly inside the switch statement. The generated C++ interface provides a convenience C++ enum called cases inside of the generated C++ class that represents the enumeration that the switch actually operates over. This C++ enum can then be used in a switch, as the class that represents the enumeration implicitly converts to it, and so do the C++ case values. This allows us to switch over the CompassDirection class from the example above in the following manner:
```c++
#include "Navigation-Swift.h"
using namespace Navigation;
CompassDirection getOpposite(CompassDirection cd) {
switch (cd) { // implicit conversion to CompassDirection::cases
case CompassDirection::north:
return CompassDirection::south();
case CompassDirection::south:
return CompassDirection::north();
case CompassDirection::east:
return CompassDirection::west();
case CompassDirection::west:
return CompassDirection::east();
}
}
```
### Enumerations With Raw Values
Swift allows you to declare enumerations whose cases are represented using an underlying raw value type. The C++ interface for such a Swift enumeration allows you access both the raw value of such an enumeration, and also to construct such an enumeration from a raw value.
For example, given the following enum with a String type:
```swift
// Swift module 'Airport'
enum Airport : String` {`
case LosAngeles = "LAX"
case SanFrancisco = "SFO"
}
```
You can access the underlying rawValue from C++ using the `getRawValue` method:
```c++
#include "Airport-Swift.h"
using namespace Airport;
void printAirport(Airport dest) {
swift::String airportCode = dest.getRawValue();
std::cout << "landing at " << airportCode << "\n";
}
```
You can use the static `init` method to construct an optional enumeration from a raw value:
```c++
void constructRoute() {
swift::Optional<Airport> arrivingTo = Airport::init("LAX");
// arrivingTo is now Airport::LosAngeles
auto departingFrom = Airport::init("HTX");
// departingFrom is none
}
```
### Enumerations With Associated Values
Swift allows an enumeration to store values of other types alongside the enumeration’s case values. This additional information is called an associated value in Swift. Enums with associated values are represented in a different manner than enums without associated values.
For example, the following enum with two cases with associated values:
```swift
// Swift module 'Store'
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
```
Will get a C++ interface that resembles this class:
```c++
// "Store-Swift.h" - C++ interface for Swift's Store module.
class Barcode {
public:
Barcode() = delete;
inline const static struct { ... } qrCode;
inline const static struct { ... } upc;
bool isUpc() const;
using UpcType = swift::Tuple<swift::Int, swift::Int, swift::Int, swift::Int>;
// Extracts the associated valus from Barcode.upc enum case
UpcType getUpc() const;
bool isQrCode() const;
// Extracts an associated value from Barcode.qrCode enum case
swift::String getQrCode() const;
};
```
The C++ user of this enumeration can then use it by checking the type of the value in a switch and getting the associated value using the get member functions:
```c++
#include "Store-Swift.h"
using namespace Store;
Barcode normalizeBarcode(Barcode barcode) {
switch (barcode) {
case Barcode::qrCode: {
auto qrCode = barcode.getQrCode();
swift::Array<swift::Int> loadedBarcode = loadQrCode(qrCode);
return Barcode::upc(loadedBarcode[0], loadedBarcode[1], loadedBarcode[2], loadedBarcode[3]);
}
case Barcode::upc:
return barcode;
}
}
```
The use of a `get` associated value accessor for an invalid enum case for the given
enum value will abort the program.
### Resilient Enums
A resilient Swift enumeration value could represent a case that's unknown to the client.
Swift forces the client to check if the value is `@unknown default` when switching over
the enumeration to account for that. C++ follows a similar principle,
by exposing an `unknownDefault` case that can then be matched in a switch.
For example, given the following resilient enumeration:
```swift
// Swift module 'DateTime'
enum DateFormatStyle {
case medium
case full
}
```
In C++, you need do an exhaustive switch over all cases and the unknown default
case to avoid any compiler warnings:
```c++
using namespace DateTime;
void test(const DateFormatStyle &style) {
switch (style) {
case DateFormatStyle::medium:
...
break;
case DateFormatStyle::full:
...
break;
case DateFormatStyle::unknownDefault: // just like Swift's @unknown default
// Some case value added in a future version of enum.
break;
}
}
```
The `unknownDefault` case value is not a constructible case and you will get a compiler error if you try to construct it in C++.
## Using Swift Class Types
Swift class types that are usable from C++ are available in their corresponding module namespace. They’re bridged over as a C++ class that stores a referenced counted pointer inside of it. Its initializers, methods and properties are exposed as members of the C++ class.
### Reference counting in C++
C++ class types that represent Swift classes perform automatic
reference counting (ARC) operations when the C++ value that represents
the reference to the Swift class is copied and destroyed.
For example, the following Swift class:
```swift
// Swift module 'People'.
class Person {
let name: String
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
func createRandomPerson() -> Person {
return Person(name: getRandomName())
}
```
Can be used from C++ with reference counting performed
automatically:
```c++
#include "People-Swift.h"
using namespace People;
void doSomething(Person p) {
...
}
void createAndUsePerson() {
Person p = createRandomPerson();
doSomething(p); // 'p' is copied. Person referenced by p is referenced twice.
// Destructor for copy of 'p' is called. Person referenced by p is referenced once.
// Destructor for 'p' gets called here. Person referenced by p is deallocated.
}
```
The Swift `Person` class instance that C++ variable `p` referenced gets deallocated
at the end of `createAndUsePerson` as the two C++ values that referenced it
inside of `createAndUsePerson` were destroyed.
### Class inheritance
A Swift class that inherits from another class is bridged to C++ with that inheritance
relationship preserved in the C++ class hierarchy generated for these Swift classes. For example, given the following two Swift classes:
```swift
// Swift module 'Transport'
public class Vehicle {
}
public final class Bicycle: Vehicle {
}
```
Get a corresponding C++ class hierachy in C++:
```c++
class Vehicle { ... };
class Bicycle final : public Vehicle {};
```
This allows C++ code to implicitly cast derived class instances to base class reference values, like in the example below:
```c++
#include "Transport-Swift.h"
using namespace Transport;
void doSomethingWithVehicle(Transport::Vehicle vehicle) {
...
}
void useBicycle() {
auto bike = Bicycle::init();
doSomethingWithVehicle(bike);
}
```
Swift classes that are marked as `final` are also marked `final` in C++.
Swift classes that are not marked as `final` should not be derived from in C++.
## Accessing Properties In C++
Swift allows structures and classes to define stored and computed properties. Stored properties store constant and variable values as part of an instance, whereas computed properties calculate (rather than store) a value. The stored and the computed properties from Swift types are bridged over as getter `get...` and setter `set...` methods in C++. Setter methods are not marked as `const` and should only be invoked on non `const` instances of the bridged types.
For example, given the following structure with a stored and a computed property:
```swift
// Swift module 'Weather'
struct WeatherInformation {
var temperature: Int
var temperatureInFahrenheit: Int {
...
}
}
```
Both properties can be accessed with getters and setters, as demonstrated by the interface and example below:
```c++
// "Weather-Swift.h" - C++ interface for Swift's Weather module.
class WeatherInformation {
public:
WeatherInformation() = delete;
swift::Int getTemperature() const;
void setTemperature(swift::Int);
swift::Int getTemperatureInFahrenheit() const;
private:
// opaque storage representation for the Swift struct.
};
// C++ use site.
#include "Weather-Swift.h"
#include <iostream>
void printWeatherInformation(const Weather::WeatherInformation &info) {
std::cout << "Temperature (C): " << info.getTemperature() << "\n";
std::cout << "Temperature (F): " << info.getTemperatureInFahrenheit() << "\n";
}
void updateWeather(Weather::WeatherInformation &info) {
info.setTemperature(25);
}
```
Please note, however, that a getter method for property returns a copy of the value stored in the property. This means that when you mutate a value returned by the getter, it does not update the original property value. We can mutate property values using `withMutable...` member function described in the next section.
Getter-only properties of type `bool` that start with `is` or `has` can be used by their exact name from C++. For example Array’s `isEmpty` maps to `isEmpty()` call in C++:
```c++
int printArray(const swift::Array<int> &array) {
if (array.isEmpty()) {
std::cout << "[]";
return
}
...
}
```
### Mutating Property Values
Swift allows you to mutate a property by using additional operations like assignments, mutating method calls, or property mutations when accessing a property:
```swift
// Swift module 'Shapes'
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, height = 0.0
}
struct Rectangle {
var position: Point
var size: Size
}
func updatePosition(shape: inout Rectangle, by value: Double) {
shape.position.x += value // mutate `position.x` inside of given shape
shape.position.y += value // mutate `position.y` inside of given shape
}
```
The generated C++ interface allows you to mutate a property value using a `withMutating...` method, which takes in a C++ lambda that receives a reference to the underlying value that can be safely mutated within the lambda:
```c++
#include "Shapes-Swift.h"
void updatePosition(Shapes::Rectangle &shape, double value) {
shape.withMutablePosition([&](auto &position) {
position.withMutableX( [&](auto &x) { x += value; }
position.withMutableY( [&](auto &y) { y += value; }
});
}
```
It’s illegal to escape the passed reference to the value from the lambda, as that can create a dangling reference in your program.
### Static Properties
Type properties are mapped as `static` getter, setter, and mutation member functions in the C++ class that represents the Swift type. They can be accessed directly from C++ by invoking the function using its qualified name directly, like in the following example:
```swift
// Swift module 'GlobalSettings'
struct Config {
static var binaryName = ""
}
```
```c++
// C++
#include "GlobalSettings-Swift.h"
int main(const char *argv[], int argc) {
if (!GlobalSettings::Config::getBinaryName().isEmpty())
GlobalSettings::Config::setBinaryName(swift::String::init(argv[0]));
...
}
```
Open Property Questions:
* What happens when we have a name collision between a Swift `get` method that we’d like to bridge and the bridged property getter?
## Accessing Subscripts In C++
Swift subscripts allow users to use the `[]` operator to access elements in a collection. The getter of a Swift subscript is bridged over as `operator []` to C++. It takes in the index parameter and returns the subscript’s value over to C++. This is how you would use the subscript to access an element from a Swift `Array` :
```c++
#include "Swift-Swift.h"
#include <iostream>
void printElementsInArray(const swift::Array<swift::Int> &elements) {
for (size_t i = 0; i < elements.getCount(); ++i) {
std::cout << elements[i] << "\n";
}
}
```
The setter of a Swift subscript is bridged over as method named `setElementAtIndex` . It takes in the index parameter and a new value that’s being set. This how you would invoke the subscript setter for a Swift `Array`:
```c++
#include "Swift-Swift.h"
void updateArrayElement(swift::Array<swift::String> &elements) {
elements.setElementAtIndex(0, "hello world!");
}
```
### Mutating Subscript Values
Swift allows you to mutate a value that’s yielded by the subscript. For example, you can append an element to an array inside of another array by using the subscript operator:
```swift
// Swift module 'Matrix'
func appendColumn(to matrix: inout [[Int]], value: Int) {
for rowIndex in matrix.indices() {
matrix[rowIndex].append(value)
}
}
```
The generated C++ interface allows you to mutate a subscript value using a `mutateElementAtIndex` method, which takes in a C++ lambda that receives a reference to the underlying value that can be safely mutated within the lambda:
```c++
#include "Matrix-Swift.h"
void appendColumn(swift::Array<swift::Array<int>> &matrix, swift::Int value) {
for (auto rowIndex : matrix.indices()) {
elements.mutateElementAtIndex(rowIndex, [](auto &row) {
row.append(value);
});
}
}
```
It’s illegal to escape the passed reference to the value from the lambda, as that can create a dangling reference in your program.
Open Questions:
* Bridging over overloaded subscripts.
## Using Swift Optional Values
An optional type represents a value that may be absent. Swift’s optional type can be used from C++ using the `swift::Optional` class template. It must be instantiated with a C++ type that represents some Swift type.
### Constructing an Optional
The `swift::Optional` class provides a default constructor that can be used to initialize it to `none`:
```c++
auto x = swift::Optional<int>(); // x is none
```
The optional can be initialized to be `Some` using a constructor which takes the value that should be stored in the optional:
```c++
swift::Optional<int> y = 0; // y is some(0)
```
The optional class also provides a constructor that receives `nullptr_t` , so that it can be initialized from a `nullptr`, similar as to how you could initialize an optional from `nil` in Swift:
```c++
swift::Optional<double> a = nullptr; // a is none
```
An alternative constructor can receive `nullopt_t` type, so that it can be initialized from `nullopt`, just like an `std::optional`:
```c++
swift::Optional<float> b = std::nullopt; // b is none
```
### Checking If an Optional Has Value
The `swift::Optional` class provides an explicit `operator bool` that be used to check if it contains a value using an `if` statement:
```c++
void printOptionalInt(const swift::Optional<int> &x) {
if (x) {
std::cout << ".some(" << x.value() << ")";
} else {
std::cout << ".none";
}
}
```
You can also use the `hasValue` member function to check if it has a value as well.
### Extracting Value From an Optional
The `swift::Optional` class provides a `value` member function that can be used to extract the value from the optional. The C++ dereference operator `*` can also be used to extract the stored value:
```c++
void getXOrDefault(const swift::Optional<int> &x) {
return x.hasValue() ? *x : 42;
}
```
It’s illegal to try to extract a value from an optional when it has no value. A fatal error will be reported at runtime if one attempts to do that:
```c++
swift::Optional<int> x = nullptr;
std::cout << x.value() << "\n";
// Fatal error: Unexpectedly found nil while unwrapping an Optional value
```
### Mutating Value In an Optional
Swift provides optional chaining syntax that allows you to invoke mutating methods and property accessors on the stored value in a convenient manner:
```swift
func getXPerhaps() -> [Int]? { ... }
var x = getXPerhaps()
x?.append(42); // append `42` to x when it's not nil
```
The C++ interface for `Optional` provides a similar mutation mechanism, where the mutation occurs only when an optional has a value in it. The provided `withMutableValue` method allows you to pass a lambda that receives a reference to the underlying value that can be safely mutated within the lambda:
```c++
swift::Optional<swift::Array<swift::Int>> x = getXPerhaps();
x.withMutableValue([](auto &val) {
// append `42` to the array x only when x is not nil
val.append(42);
});
```
It’s illegal to escape the passed reference to the value from the lambda, as that can create a dangling reference in your program.
## Extensions
Swift extensions can be used to add new functionality to an existing class, structure, enumeration or a protocol in Swift. The C++ interface generator in the Swift compiler is capable of exposing an extension for a type or a protocol that’s defined in the same Swift module as the type/protocol itself. An extension that’s exposed to C++ can add the following members to the C++ class that represents a Swift type in the generated C++ interface:
* Getter and setter methods that expose computed instance or type properties added in the extension
* Instance and static methods that expose Swift methods added in the extension
* Static `init` methods that expose new initializers added in the extension
* Subscript operator and `setElementAtIndex` method that expose subscripts added in the extension
* Nested types added in the extension
**Note:** C++ does not have a language feature that would allow us to represent Swift extensions in their full fidelity. This is why the current implementation of the C++ interface generator in the Swift compiler only lets us expose extensions defined in the same module as the type that’s being extended.
### Accessing Extension Members
The exposed extension members are added to the C++ class that corresponds to the underlying Swift type. For example, the following extensions for a Swift type:
```swift
// Swift module 'Geometry'
struct Rect {
var x, y, width, height: Double
}
extension Rect {
init(size: Int) {
self.init(x: 0, y: 0, width: size, height: size)
}
func squareThatFits() -> Rect {
let size = max(width, height)
return Rect(x: x, y: y, width: size, height: size)
}
}
extension Rect: `CustomDebugStringConvertible` {
var debugDescription: String {
return ""
}
}
```
Are exposed in the C++ `class` Rect, as per the sample interface below:
```c++
// C++ interface for 'Geometry'
class Rect {
public:
// init(x:,y:,width:,height:)
static Rect init(double x, double y, double width, double height);
// init(size:)
static Rect init(double size);
Rect squareThatFits() const { ... }
swift::String getDebugDescription() const { ... }
};
```
### Protocol Extensions
Swift protocols can be extended to provide method, initializer, subscript, and computed property implementations to the conforming types. The exposed members from such a protocol extension are added to the C++ class that corresponds to the underlying Swift type. For example, if `Rect` receives a conformance for `Shape` like below:
```swift
protocol Shape {
var area: double { get }
}
extension Rect: Shape {
var area: double { width * height }
}
extension Shape {
func fits(inArea otherArea: double) -> Bool {
area < otherArea
}
}
```
The members from the extension of `Shape` are then added to the C++ class that corresponds to the `Rect` Swift structure:
```c++
// C++ interface for 'Geometry'
class Rect {
public:
...
bool fits(double inArea) const { ... }
};
```
A protocol extension need to be in the same Swift module as the type that conforms to such protocol in order for the extension to get exposed in the C++ interface for the module.
## Generics
Swift’s generics allow programmer to write reusable functions and types that can work with any type, subject to any requirements that are specified by the programmer. C++ templates provide similar facilities for generic programming in C++. While Swift’s generics and C++ templates look similar, there are some important differences between them:
* Generic Swift functions and types are type checked at their definition using their stated requirements. C++ templates type check the generic code only after a template is specialized for a concrete type.
* Generic Swift functions and types provide generic implementation of their generic code, that can work with any type that conforms to their stated requirements. C++ templates, however, **do not** provide generic implementation of C++ functions or classes, as they only provide concrete implementations that operate on specific types that get generated whenever a C++ template is instantiated.
Even though C++ templates have different semantics than Swift generics, they are used in the generated C++ interface to provide type parameters for Swift functions or types that are then passed to Swift generic code. A generic Swift function or a generic Swift type is represented using a C++ function template, or a C++ class template, with certain constraints on the template parameters. The constraints are checked at compile time in C++ using `requires` in C++20 , or `enabled_if` when compiling using an older C++ standard.
Generic Swift code that’s invoked from C++ always goes through Swift’s generic codepath. A programmer that’s calling Swift generic APIs from C++ should keep that in mind, as the generic Swift code is most likely going to be less performant than a comparable C++ code generated by a template instantiation, as the C++ code is specialized for a specific type instead of being generic.
### Calling Generic Functions from C++
A generic function is represented using a function template in C++. The template type parameters must represent a type that is usable from a generic context in Swift, and must conform to any other generic constraints that are specified in Swift. These requirements are verified at compile time by the template requirements specified alongside the C++ function.
A generic function can be called from C++ by calling the C++ function template that represents it. For example, the generic function `swapTwoValues` with one type parameter `T` :
```swift
// Swift module 'Swapper'
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
...
}
```
Gets exposed to C++ via the following C++ function template:
```c++
template<typename T>
void swapTwoValues(T &a, T& b)
requires swift::isUsableInGenericContext<T> {
...
}
```
And can then be called from C++ just like any other Swift function, as long as `T` is a type that can be used in a generic context in Swift:
```c++
#include "Swapper-Swift.h"
int main() {
int x, y;
Swapper::swapTwoValues(x, y); // ok.
std::string s1, s2;
Swapper::swapTwoValues(s1, s2);
// error: no matching function for call to 'Swapper::swapTwoValues'
// `because 'swift::isUsableInGenericContext<...>' evaluated to false`
return 0;
}
```
When compiling in C++ 17 mode, the C++ function template relies on `std::enable_if` to verify that `T` is a type that can be used in a generic context instead of `requires`:
```c++
template<typename T,
typename = std::enable_if_t<swift::isUsableInGenericContext<T>>>
void swapTwoValues(T& a, T& b)
```
Generic methods from Swift types are represented using a member function template in C++. They must obey the same requirements as Swift generic functions as well.
### Using Generic Types
A generic Swift structure, enumeration or class is represented using a class template in C++. The template type parameters must represent a type that is usable from a generic context in Swift, and must conform to any other generic constraints that are specified in Swift. These requirements are verified at compile time by the template requirements specified alongside the C++ class.
A generic Swift type can be used in C++ by specifying its class name and type parameters using the C++ template syntax. For example, the generic structure `Stack` with one type parameter `Element` :
```swift
// Swift module 'Datastructures'
struct Stack<Element> {
mutating func push(_ item: Element) {
...
}
...
}
```
Can then be used in C++ just like a C++ class template:
```c++
#include "Datastructures-Swift.h"
void useSwiftStack() {
Datastructures::Stack<int> intStack;
intStack.push(22);
}
```
It’s illegal to instantiate a class template for a Swift generic type like `Stack` with a type parameter that can’t be represented in a generic context in Swift. The compiler will verify that at compile-time by checking the constraints specified in the `requires` clause of the class template:
```c++
// Snippet from Datastructures-Swift.h
template<class Element>
requires swift::isUsableInGenericContext<Element>
class Stack {
...
};
// C++ use site
#include "Datastructures-Swift.h"
void useSwiftStackIncorrectly() {
Datastructures::Stack<std::string> cxxStringStack;
// error: constraints not satisfied for class template 'Stack'
// note: because 'swift::isUsableInGenericContext<...>' evaluated to false
}
```
**Open Questions:**
* How do the opaque layout type type parameters that affect structs layout work - do they need template specializations, or can we do this with constexpr if - they need to be boxed?
### Generic Type Constraints
Swift programers can specify type constraints on the types that can be used with generic functions and generic types. These constraints are exposed to C++‘s type system through a set of requirements that must be satisfied by the C++ function or class template that represents a Swift generic function or type. They are verified in C++ at compile-time to ensure that the program is not invoking generic Swift code with types that don’t satisfy the specified constraints.
A generic constraint that specifies that a generic type parameter must conform to a particular protocol or protocol composition is verified using a `swift::conformsTo` type trait in C++. For example, the following generic function with a `Comparable` protocol constraint on `T`:
```swift
// Swift module 'MyModule'
func isWithinRange<T: Comparable>(_ value: T, lowerBound: T, upperBound: T) -> Bool {
...
}
```
Gets exposed to C++ via the following C++ function template with a `requires` clause that verifies conformance of the C++ type that represents some Swift type:
```c++
template<typename T>
bool isWithinRange(const T& value, const T& lowerBound, const T& upperBound)
requires swift::isUsableInGenericContext<T> &&
swift::conformsTo<T, swift::Comparable>
```
And can then be called from C++ as long as the Swift type that’s being represented by the C++ type `T` actually conforms to `Comparable` in Swift:
```c++
#include "MyModule-Swift.h"
int main() {
MyModule::isWithinRange(1, 0, 2);
return 0;
}
```
It’s illegal to instantiate a template with such a requirement when the template type parameter does not conform to `Comparable` in Swift. The compiler will verify that at compile-time by checking the template constraints:
```c++
void useWithinRangeWithCustomSwiftType() {
MyModule::isWithinRange<MyModule::SomeSwiftStruct>({}, {}, {});
// error: no matching function for call to 'MyModule::isWithinRange'
// because 'swift::conformsTo<MyModule::SomeSwiftStruct, swift::Comparable>' evaluated to false
}
```
**TODO:** Inherit from a specific class constraint
### Extensions with a Generic Where Clause
Swift extensions can use a generic `where` clause to limit the extension to types that match certain generic constraints. The members of such extensions get exposed to C++ as described in the “Extensions” section above. These exposed members receive additional template requirements in C++ to ensure that they are available only from a C++ class template that satisfies the template requirements imposed by the generic `where` clause of the extension.
For example, an extension to the generic `Stack` structure from the previous example:
```swift
extension Stack where Element: Equatable {
`func isTop(_ item: Element) -> Bool {`
...
}
}
```
Gets exposed to C++ inside of the `Stack` class template with the added member constraint which validates that the C++ `Element` type represents a Swift type that conforms to `Equatable` :
```c++
template<class Element>
requires swift::isUsableInGenericContext<Element>
class Stack {
...
bool isTop(const Element &) const
requires swift::conformsTo<Element, swift::Equatable> {
...
}
};
```
It’s illegal to access extension members in C++ class templates that don’t satisfy the where clause imposed by such an extension. The compiler will verify that at compile-time by enforcing the requirements on the member:
```c++
void useStackInCxx() {
Datastructures::Stack<MyModule::SomeSwiftStruct> stack;
stack.push(MyModule::SomeSwiftStruct()); // ok
stack.isTop(MyModule::SomeSwiftStruct());
// error: invalid reference to function 'isTop': constraints not satisfied
// note: because 'swift::conformsTo<MyModule::SomeSwiftStruct, swift::Equatable>' evaluated to false
}
```
**TODO:** Support nested types inside of generic where clause extensions. - add a requires on them.
**TODO:** Add an example for Protocol Extensions With Contextual Where Clauses>
## Using Swift’s Standard Library Types
### Using String
String conforms to `StringLiteralConvertible` , so you can implicitly construct instances of `swift::String` directly from a C++ string literal, or any `const char *` C string:
```c++
swift::String string = "Hello world";
string.hasPrefix("Hello"); // Implicit construction of swift::String.
```
You can convert a `swift::String` to a `std::string` using `std::to_string`:
```c++
void printSwiftString(const swift::String &swStr) {
std::string str = std::to_string(swStr);
std::cout << "swift string is " << str << "\n";
}
```
You can convert an `std::string` into a `swift::String` using an explicit constructor:
```c++
void setSwiftString(swift::String &other, const std::string &str) {
other = swift::String(str);
}
```
In Objective-C++ mode, you can also convert a `swift::String` to an `NSString *` value using
a cast or by assigning to an `NSString *` value directly:
```c++
void useObjCString(const swift::String &swStr) {
// This cast will bridge the Swift String to an Objective-C NSString value.
NSString *nsStr = swStr;
}
```
Open questions:
* How do the `StringLiteralConvertible` rules work in practice?
* What happens when String.init fails for a literal? (fatalError most likely). Check what Swift does, does it ever allow an invalid utf8 sequence, and will the actual initializer fail at runtime?
* String.init - implicit initializer from C++ string is problematic potentially. Make Pointers have to go through force casting? (I think that’s probably not a problem - C++ string literal type just won’t conform to swift::isUsableInGenericContext)
### Using Array
A Swift array type can be used from C++ using the `swift::Array` class template. It must be instantiated with a C++ type that represents a Swift type.
An array can be initialized using a C++ initializer list because it conforms to `ArrayLiteralConvertible`:
```c++
swift::Array<int> intArray = {};
swift::Array<swift::String> languages = { "Swift", "C++", "Objective-C" };
```
You can iterate over the array elements using a `for` loop:
```c++
for (auto language : languages)
std::cout << std::to_string(language) << "\n";
```
You can modify the elements in the array using the `setElementAtIndex` member function:
```c++
for (size_t i = 1; i < languages.getCount(); ++i)
languages.setElementAtIndex(i, languages[i] + languages[i - 1]);
```
You can convert a `swift::Array` to a `std::vector` using the following explicit constructor of `std::vector`:
```c++
auto cxxVector = std::vector<int>(intArray.begin(), intArray.end());
```
This constructor copies over the elements from the Swift array into the constructed C++ vector.
You can also convert a vector to a `swift::Array` using the following explicit constructor of `swift::Array`:
```c++
auto swiftIntArray = swift::Array<int>(cxxVector);
```
This constructor copies over the elements from the C++ vector into the constructed Swift array.
## Appendix A: Type Traits That Model Swift’s Type System In C++
The C++ interface that’s generated by the Swift compiler for a Swift module uses a number of C++ type traits that can be used to query information about Swift’s type system from C++. These type traits are listed in this section.
### swift::isUsableInGenericContext
```c++
template<class T>
inline constexpr const bool swift::isUsableInGenericContext
```
This type trait can be used to check if a type can be passed to a generic Swift function or used as a generic type parameter for a Swift type. It evaluates to `true` in the following cases:
* When `T` is a primitive type like `int` , `float`, `swift::Int`, etc. that has a corresponding Swift primitive type.
* When T is a class or a class template that acts a proxy for a Swift type and is defined in the C++ interface generated by the Swift compiler for a Swift module.
* **TODO:** Objective-C ARC pointers , etc?
The following example illustrates how this type trait evaluates to true for types that have a Swift representation, but to false for regular C++ types:
```c++
static_assert(swift::isUsableInGenericContext<int> == true);
static_assert(swift::isUsableInGenericContext<swift::String> == true);
static_assert(swift::isUsableInGenericContext<std::string> == false);
```
### swift::conformsTo
```c++
template<class T, class P>
inline constexpr const bool swift::conformsTo
```
This type trait evaluates to true when a specific Swift type that is being proxied by the given C++ type `T` conforms to a Swift protocol that’s being proxied by the given C++ class `P`.
|