You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/CppInteroperability/UserGuide-CallingSwiftFromC++.md
+78-22Lines changed: 78 additions & 22 deletions
Original file line number
Diff line number
Diff line change
@@ -424,7 +424,7 @@ int main() {
424
424
425
425
## Using Swift Enumeration Types
426
426
427
-
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 that doesn’t have associated value is exposed as a static variable in the structure.
427
+
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.
428
428
429
429
For example, given the following enum:
430
430
@@ -444,32 +444,44 @@ The following interface will be generated:
444
444
// "Navigation-Swift.h" - C++ interface for Swift's Navigation module.
445
445
classCompassDirection {
446
446
public:
447
-
static const CompassDirection north;
448
-
static const CompassDirection south;
449
-
static const CompassDirection east;
450
-
static const CompassDirection west;
447
+
static const struct { ... } north;
448
+
static const struct { ... } south;
449
+
static const struct { ... } east;
450
+
static const struct { ... } west;
451
+
private:
452
+
// type representation details.
453
+
...
451
454
};
452
455
```
453
456
457
+
This will let you construct enumeration values from C++ using the C++ call operator on the case:
458
+
459
+
```c++
460
+
#include "Navigation-Swift.h"
461
+
462
+
void testConstructEnumValue() {
463
+
auto direction = CompassDirection::north();
464
+
}
465
+
```
466
+
454
467
### Matching Swift Enumeration Values with a C++ Switch Statement
455
468
456
-
Swift’s enumerations can not be used directly in a switch, as C++ does not allow a `switch` to operate on C++ classes. However, For Swift enumerations that have an underlying integer representation, the generated C++ interface provides a convenience C++ enum called `cases` inside of the generated C++ class that represents the enumeration. This C++ enum can then be used in a switch, as the class that represents the enumeration implicitly converts to it. The `cases` C++ enum allows us to switch over the `CompassDirection` class from the example above in the following manner:
469
+
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:
The C++ user of this enumeration can then use it by checking the type of the value and getting the associated value using the `is` and `get` member functions:
568
+
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:
The use of a `get` associated value accessor for an invalid enum case for the given
588
+
enum value will abort the program.
589
+
590
+
### Resilient Enums
591
+
592
+
A resilient Swift enumeration value could represent a case that's unknown to the client.
593
+
Swift forces the client to check if the value is `@uknown default` when switching over
594
+
the enumeration to account for that. C++ follows a similar principle,
595
+
by exposing an `unknown_default` case that can then be matched in a switch.
596
+
597
+
For example, given the following resilient enumeration:
598
+
599
+
```swift
600
+
// Swift module 'DateTime'
601
+
enumDateFormatStyle {
602
+
casemedium
603
+
casefull
604
+
}
605
+
```
606
+
607
+
In C++, you need do an exhaustive switch over all cases and the unknown default
608
+
case to avoid any compiler warnings:
609
+
610
+
```c++
611
+
usingnamespaceDateTime;
612
+
voidtest(const DateFormatStyle &style) {
613
+
switch (style) {
614
+
case DateFormatStyle::medium:
615
+
...
616
+
break;
617
+
case DateFormatStyle::full:
618
+
...
619
+
break;
620
+
case DateFormatStyle::unknown_default: // just like Swift's @unknown default
621
+
// Some case value added in a future version of enum.
622
+
break;
623
+
}
570
624
}
571
625
```
572
626
627
+
The `unknown_default` case value is not a constructible case and you will get a compiler error if you try to construct it in C++.
628
+
573
629
## Using Swift Class Types
574
630
575
631
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.
0 commit comments