File: CppInteroperabilityManifesto.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 (3556 lines) | stat: -rw-r--r-- 130,154 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
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
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
# Interoperability between Swift and C++

# ⚠️ Warning: document is out of date. ⚠️

**This document has not had significant updates in the last three years. The goals and design outlined here do not necessarily reflect those established by the C++ Interop Work Group. For an up-to-date document, please see [the Forward Vision document](https://github.com/apple/swift-evolution/blob/main/visions/using-swift-from-c%2B%2B.md).**

[** ‼️ Additionally, 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/)

This document discusses the design and tradeoffs for bidirectional API-level
interoperability between Swift and C++.

Assumptions:

* We can make changes to the Swift language and the standard library.
  * The proposed changes must fit Swift's goals and philosophy. In other words,
    the proposed changes must have a reasonable chance to be accepted by the
    Swift community. For example, a change that requires an ABI break on Apple
    platforms is a non-starter.
  * Forking the Swift language or standard library, or creating a dialect
    without a fork (and therefore, being able to make radical changes to Swift's
    goals, philosophy, safety, or ergonomics) are not interesting options, and
    therefore, are not considered or discussed.
* We can make limited changes to the C++ code, toolchain, standard library
  implementation, and runtime environment.
  * The cost of such changes must be taken into account. Changes that require an
    ABI break for C++ might be interesting for users who control the complete
    toolchain, but are non-starters for the community at large; therefore, such
    changes can only be considered an optimization. Changes that require
    significant manual work on existing C++ code by end users can also be
    considered only as optimizations or improvements for ergonomics.

- [Goals](#goals)
- [Current state of art: importing C code into Swift](#current-state-of-art-importing-c-code-into-swift)
- [Importing C++ APIs into Swift](#importing-c-apis-into-swift)
  * [Names, identifiers and keywords](#names-identifiers-and-keywords)
  * [Functions](#functions)
    + [Non-const pointer and reference parameters](#non-const-pointer-and-reference-parameters)
    + [Const reference parameters](#const-reference-parameters)
    + [Mapping overload sets](#mapping-overload-sets)
    + [Inline functions](#inline-functions)
  * [Namespaces and modules](#namespaces-and-modules)
    + [The "std" namespace](#the-std-namespace)
  * [Structs and classes](#structs-and-classes)
    + [Mapping the type itself and its special member functions](#mapping-the-type-itself-and-its-special-member-functions)
    + [Special member functions with incorrect semantics](#special-member-functions-with-incorrect-semantics)
    + [Special member functions that throw exceptions](#special-member-functions-that-throw-exceptions)
    + [Precise destruction semantics](#precise-destruction-semantics)
    + [Member functions that return inner pointers](#member-functions-that-return-inner-pointers)
    + [Differences in move semantics between C++ and Swift](#differences-in-move-semantics-between-c-and-swift)
    + [Move-only C++ classes](#move-only-c-classes)
    + [Move-only C++ classes: mapping in Swift 5](#move-only-c-classes-mapping-in-swift-5)
    + [Move-only C++ classes: mapping to move-only Swift types (in future Swift versions)](#move-only-c-classes-mapping-to-move-only-swift-types-in-future-swift-versions)
    + [Non-destructive moves](#non-destructive-moves)
    + [Non-movable C++ classes](#non-movable-c-classes)
    + [Member functions](#member-functions)
    + [Const-qualified member functions in C++ classes](#const-qualified-member-functions-in-c-classes)
    + [Volatile-qualified member functions](#volatile-qualified-member-functions)
    + [Ref-qualified member functions](#ref-qualified-member-functions)
    + [Final functions](#final-functions)
    + [Getters and setters](#getters-and-setters)
    + [Pointers to members](#pointers-to-members)
    + [Virtual member functions](#virtual-member-functions)
    + [Inherited APIs](#inherited-apis)
    + [Conversions between derived and base classes](#conversions-between-derived-and-base-classes)
    + [Subclassing C++ classes in Swift](#subclassing-c-classes-in-swift)
    + [Making C++ classes conform to Swift protocols](#making-c-classes-conform-to-swift-protocols)
  * [Enums](#enums)
  * [Templates](#templates)
    + [Function templates](#function-templates)
    + [Function templates: import as Swift generic functions](#function-templates-import-as-swift-generic-functions)
    + [Function templates: allow to specify template arguments](#function-templates-allow-to-specify-template-arguments)
    + [Function templates: calls to specific specializations](#function-templates-calls-to-specific-specializations)
    + [Function templates: calls with generic type parameters](#function-templates-calls-with-generic-type-parameters)
    + [Function templates: importing as real generic functions](#function-templates-importing-as-real-generic-functions)
    + [Class templates](#class-templates)
    + [Class templates: importing full class template instantiations](#class-templates-importing-full-class-template-instantiations)
    + [Class templates: importing specific specializations](#class-templates-importing-specific-specializations)
    + [Class templates: using with generic type parameters](#class-templates-using-with-generic-type-parameters)
    + [Class templates: using in generic code through a synthesized protocol](#class-templates-using-in-generic-code-through-a-synthesized-protocol)
    + [Class templates: importing as real generic structs](#class-templates-importing-as-real-generic-structs)
    + [Mapping SFINAE](#mapping-sfinae)
    + [Variadic templates](#variadic-templates)
    + [Non-type template parameters](#non-type-template-parameters)
    + [Template template parameters](#template-template-parameters)
  * [Overloaded operators](#overloaded-operators)
  * [`operator*`, `operator->`](#operator-star-operator-arrow)
  * [`operator[]`](#operator-square-brackets)
  * [`operator()`](#operator-parentheses)
  * [Literal operators](#literal-operators)
  * [Exceptions](#exceptions)
  * [Atomics](#atomics)
  * [Importing non-const pointer as extra return values](#importing-non-const-pointer-as-extra-return-values)
- [Enhancing C++ API mapping into Swift with bridging](#enhancing-c-api-mapping-into-swift-with-bridging)
  * [Bridging data types with different memory layout](#bridging-data-types-with-different-memory-layout)
  * [Bridging: behind the scenes](#bridging-behind-the-scenes)
  * [Bridging does not work in every context](#bridging-does-not-work-in-every-context)
  * [Bridging `std::function`](#bridging-std-function)
  * [Bridging `std::string`](#bridging-std-string)
  * [Bridging `std::vector`](#bridging-std-vector)
  * [Bridging `std::set`, `std::map`](#bridging-std-set-std-map)
  * [Bridging `std::unordered_set`, `std::unordered_map`](#bridging-std-unordered-set-std-unordered-map)
  * [Bridging `std::tuple`, `std::pair`](#bridging-std-tuple-std-pair)
  * [Bridging `std::span`](#bridging-std-span)
  * [Standard C++ containers in general](#standard-c-containers-in-general)
  * [Custom C++ containers](#custom-c-containers)
  * [Bridging `absl::flat_hash_{set,map}`, `absl::node_hash_{set,map}`](#bridging-absl-hash-set-map)
- [Enhancing C++ API mapping into Swift with annotations](#enhancing-c-api-mapping-into-swift-with-annotations)
  * [Annotation workflow](#annotation-workflow)
  * [Tooling to infer nullability annotations](#tooling-to-infer-nullability-annotations)
  * [APIs that take a pointer and count](#apis-that-take-a-pointer-and-count)
- [Current state of art: importing Swift code into C](#current-state-of-art-importing-swift-code-into-c)
- [Importing Swift APIs into C++](#importing-swift-apis-into-c)
  * [Resilient types](#resilient-types)
- [Forum discussions](#forum-discussions)

# Goals

What are the properties of a good interoperability layer? Exercising
interoperability is not in itself a goal of any Swift or C++ user. Therefore,
for API users interoperability should be maximally transparent in all aspects:
API design and ergonomics, editor integration and tooling, and performance. For
API vendors, interoperability should not be a significant extra burden, while
allowing API vendors to own and curate the imported API surface. Let's discuss
what these points mean.

**API design and ergonomics.** Ideally, users working in Swift should not feel
any difference between native Swift APIs and imported C++ APIs.

For example, while it is possible to write a custom hashtable in Swift, it is
done extremely rarely, and most code uses the vocabulary types `Set` and
`Dictionary`. Therefore, if C++ APIs that used `std::unordered_map` or
`flat_hash_map` types, when imported in Swift, would continue using those C++
map types, they would look weird and foreign in Swift. Idiomatic Swift code that
uses `Set` and `Dictionary` will have to convert the data into these foreign
hashtable types before calling imported C++ APIs.

As another example, C++ functions often receive values by const reference or by
const pointer. Semantically, the closest equivalent in Swift is `UnsafePointer`.
However, `UnsafePointer` is not as common in Swift as const references are in
C++; it is not idiomatic for Swift APIs to accept `UnsafePointer` outside of a
couple exceptional situations (for example, implementations of low-level
facilities, performance-sensitive code, etc.) Therefore, if C++ APIs, when
imported in Swift, would use `UnsafePointer` a lot, they would look weird and
foreign in Swift. Imported C APIs, when they are not operating on Objective-C
types, already use `UnsafePointer` a lot, and look non-idiomatic because of
that. Swift provides some affordances that make calling them easier.

**Editor integration and tooling** should transparently support code in both
languages. To the extent possible, all editor operations should "see through"
the interop. For example, if the user invokes the "rename function" refactoring,
it should rename all definitions, declarations, and usages across Swift and C++
code. This goal has been largely achieved for Swift/Objective-C interop, and we
are planning to rely on the same mechanisms for Swift/C++ interop.

**Performance.** C++ APIs, when used from Swift, ideally, should have
performance characteristics identical to when they are used from C++.

**Interop must not be a burden for API vendors.** Enabling Swift code to call a
certain C++ library should create minimal burden for the owners of that C++
library. Ideally, it should be possible without any involvement of the owners.

For example, requiring the API owners to create an API description file (like in
CLIF for Python), or a glue layer (like in JNI for Java) is a significant
burden. Most API owners are not going to do it without specific requests from
users, and even when such request is received, many API owners will carefully
consider if they want to take on maintenance of this extra file.

It may be possible to allow users to do the work necessary to expose a C++
library to Swift, however, that is not a great option either. A C++ library
might end up with multiple (incompatible) bindings of varying quality, covering
different parts of the API. In addition, the owner of the API loses control of
the API surface.

**Allow API vendors to own and curate the imported API surface.** While the
minimal amount of work to expose a C++ library to Swift should be ideally "none"
(it should just work), API vendors should own the Swift API surface of their C++
libraries, and should be able to adjust it where the automated interop is not
satisfactory.

**Tension and conflicts between goals.** These goals are conflicting. For
example, API ergonomics are in conflict with performance: we can provide a more
ergonomic API if we automatically bridge C++ types to corresponding Swift
vocabulary types at the API boundary, however, these type conversions will cost
CPU cycles. The solutions will be designed on a case by case basis: sometimes,
we will pick one side of the tradeoff, sometimes we will pick one side but allow
the user to override the default, and sometimes we will add multiple facilities
that pick different sides, forcing the user to choose.

# Current state of art: importing C code into Swift

Swift/C++ interoperability builds on top of the Swift/C interoperability, so it
helps to be familiar with [Swift's strategy for importing C
modules](../HowSwiftImportsCAPIs.md).

# Importing C++ APIs into Swift

Now let's talk about extending existing rules to handle C++.

## Names, identifiers and keywords

C++ allows defining names that are not identifiers:

* Destructors
* Overloaded operators
* Literal operators

Member functions with non-identifier names are discussed in the section about
classes. Other constructs are discussed in their respective sections.

## Functions

### Non-const pointer and reference parameters

In C++, there are no language requirements for pointers passed as function
arguments. For example, given a function signature like this:

```c++
void increment(int *value);
```

C++ as a language poses no requirements for `value` to live long enough during
the function call, or even that `value` points to valid memory when the
function is called; `value` can be null or it can be an invalid (for example,
freed) pointer. There are also no requirements about the memory pointed to by
`value` being initialized, or valid to dereference without data races. Pointers
are also allowed to alias other memory, as long as the types are compatible.
Pointers also don't imply anything about ownership or non-ownership.

Rules in C++ about references are a bit tighter, but not much. The only
differences are that a reference can't be null, and that it must be bound to a
valid object when it is initially created.

In practice, engineers working in C++ often make the following assumptions about
third-party APIs, even though these properties are not guaranteed by the
language, and are often not explicitly documented by the API:

- All pointers passed to a function are valid to dereference.

- Almost all pointers passed to a function remain valid to dereference while the
  function is running.

- Almost all pointers passed to a function are valid to dereference without data
  races.

- Almost all pointers passed to a function point to initialized data. Passing a
  pointer to uninitialized memory and expecting the function to initialize it
  happens occasionally, but it is not common.

- Often enough, pointers passed to a function are not null.

- Often enough, pointers of different types don't alias each other's subobjects.

- Almost all `const &T` parameters are semantically equivalent to passing `T` by
  value.

In Swift, passing unsafe pointers as function arguments is not idiomatic.
Idiomatic code passes structs by value, and classes by reference. `inout`
parameters in Swift allow functions to read and modify storage specified by the
caller.  The argument for the `inout` parameter must be a storage reference
expression.

```swift
func increment(_ value: inout Int) {
  value += 1
}

struct TwoInts {
  var x: Int = 0
  var y: Int = 0
}

func caller() {
  var ints = TwoInts()
  increment(&ints.x)
  // ints.x is 1
  // ints.y is 0
}
```

To understand the constraints that Swift puts on `inout` parameters, let's take
a look at the mental model for introduced in the [Ownership
manifesto](OwnershipManifesto.md) and in [SE-0176 Enforce Exclusive Access to
Memory](https://github.com/apple/swift-evolution/blob/main/proposals/0176-enforce-exclusive-access-to-memory.md).
When the caller binds a storage reference to an `inout` parameter, it starts a
non-instantaneous access to the whole value that occupies the storage. This
access ends when the callee returns.  Overlapping accesses are not allowed, and
therefore, while an `inout` parameter is live, original value may not be
accessed.

(Note that before the ownership manifesto, `inout` parameters were explained in
terms of a different model that might be easier to understand. Nevertheless,
both models are equivalent. The old model stated that on function entry, the
value is moved from the caller-specified storage reference into the `inout`
parameter, and moved from the `inout` parameter back into the original storage
on function exit.  During the execution of the function, the original storage
remains uninitialized, and therefore, the whole value that occupied that storage
remains inaccessible until the function returns.)

In practice, `inout` parameters are implemented as passing a pointer to the
storage that should be mutated, while maintaining behavior identical to the
models explained above. As a consequence of these models, `inout` parameters
provide the following guarantees:

- the memory backing an `inout` parameter is valid to access throughout the
  execution of a function.

- since `inout` parameters are not pointers, there is no such thing as "null
  `inout` parameter".

- `inout` parameters are valid to read and modify throughout the execution of
  a function without data races, unless the function itself has shared the
  parameter with multiple threads.

- `inout` are backed by initialized memory on function entry and function exit
  (an implication of the copy-in/copy-out semantics). Destroying the object in
  `inout` requires using unsafe constructs. Therefore, in safe Swift `inout`
  parameters are backed by initialized memory throughout function execution.

- `inout` parameters don't alias each other or any other values that program is
  allowed to access at that point. Remember that the original value that is
  bound to an `inout` parameter is inaccessible for the duration of the `inout`
  binding.

In practice, non-const pointers and references in function parameters are most
often used for the same purpose as Swift's `inout`, so it is desirable to map
them to each other.

```c++
// C++ header.

void incrementBoth(int *value1, int *value2);
```

```swift
// C++ header imported in Swift (possible mapping).

func incrementBoth(_ value1: inout Int, _ value2: inout Int)
```

The `incrementBoth` function imported like this has more restrictions in Swift
than in C++ (for example, arguments may not alias). Calling this C++ function
from Swift does not create a new kind of safety issues in Swift, because a
language with more restrictions calls a language with fewer restrictions. From
the API point of view, it should not be a problem either, unless the caller
needs to pass arguments that alias (Swift's enforcement of exclusivity will
prevent that).

Based on the comparison above, it looks like Swift's `inout` provides strictly
more guarantees than C++'s non-const pointers and references. Therefore, it is
not safe to map them to each other in all cases.  For example, we can't apply
this mapping when Swift is implementing a function exposed to C++, for example:

```c++
// C++ header.

class Incrementer {
public:
  virtual void incrementBoth(int *value1, int *value2) = 0;
};
```

```swift
// C++ header imported in Swift (possible mapping).

protocol Incrementer {
  func incrementBoth(_ value1: inout Int, _ value2: inout Int)
}

struct MyIncrementer: Incrementer {
  func incrementBoth(_ value1: inout Int, _ value2: inout Int) {
    // The language requires that `value1` and `value2` don't alias.
  }
}
```

It would be unsafe to expose an Swift implementation of
`Incrementer.incrementBoth` through the C++ signature, unless the C++ function
already has Swift-like preconditions for pointer arguments. For true inout
parameters in C++, those preconditions should in fact hold, even if the C++
function does not formally document them.

### Const reference parameters

In C++, const references in function arguments are most often used to avoid
copying objects passed to functions. Swift solves this problem in two ways:

- by providing language features that allow the engineer to introduce
  indirections (for example, reference types, existential types, indirect enum
  cases, tools for defining copy-on-write types),

- by automatically passing large arguments indirectly without copying them,
  where possible.

It is not feasible to automatically map C++ const references to Swift-specific
indirections like class types, because that would require changing the memory
layout through non-trivial bridging.

**Option 1: Import `const T&` as `UnsafePointer<T>`.**

We can easily map C++ const references in function parameters to
`UnsafePointer<T>` in Swift, however, the resulting APIs will not look
idiomatic. They will be usable from Swift, because Swift code can make an unsafe
pointer with the `&` operator, however, it can only be applied to mutable
storage locations. Therefore, more variables will be mutable in Swift than
necessary. Furthermore, to make some values mutable, the code will need to
make a copy that will be stored in a mutable variable -- defeating the point of
the C++ API taking a const reference.

```c++
void printInt(const int &value);
```

```swift
// C++ header imported in Swift.

func printInt(_ value: UnsafePointer<Int>)
```

```swift
// Usage example.

func caller() {
  var x = 42
  printInt(&x) // OK

  let y = 42
  printInt(y) // error: type mismatch: `Int` is not an `UnsafePointer<Int>`
  printInt(&y) // error: can't apply `&` to an immutable value
}
```

**Improvement for option 1: Allow using `&` on immutable values.**

To eliminate the extra copies that the code would have to perform to make some
values mutable, we could extend the Swift language to allow applying `&` to
immutable values, producing an `UnsafePointer<T>`.

```swift
// Usage example.

void caller() {
  let x = 42
  printInt(&x) // OK
}
```

**Option 2: Import `const T&` as `T`.**

A more ergonomic approach would be to import C++ const references to value types
as values, but still use a by-reference calling convention behind the scenes.

```c++
void printInt(const int &value);
```

```swift
// C++ header imported in Swift.

func printInt(_ value: Int)
```

```swift
// Usage example.

func caller() {
  let x = 42
  printInt(y) // OK
}
```

The imported `printInt` function that takes an `Int` by value would be a thunk
that calls the actual C++ entry point that takes an `Int` by a const reference.
A mandatory optimization pass would inline that thunk into its callers, and
eliminate the copies that now became unnecessary.

It is important to understand that this approach only works in cases where the
compiler can insert a thunk. Here's an example where the compiler can't
transparently wrap a function pointer into a thunk, and therefore can't import
`const int&` as `Int32`:

```c++
struct Example {
  void (*printInt)(const int &);
};
```

This approach is much more ergonomic. However, it has a few disadvantages.

One disadvantage is that this approach provides less control: the caller can't
specify or predict the exact address that is passed to the C++ function (because
Swift can make copies of values or move them around in memory). Most functions
receiving `const T&` parameters should not care about the exact address, but
some might.

Another disadvantage of this approach is that it is safe in many cases in
practice, but users can construct unsafe cases. Specifically, if the C++ code
being called persists the reference that was passed by Swift beyond the duration
of the function call, that reference can become invalid (because Swift code
could pass an address of a temporary, implicitly materialized by the compiler).
The nature of unsafety is identical between option 1, option 2, and existing
Swift/C interop, however, in option 2, where we import C++ references as Swift
values, it is not visible to the Swift programmer that the function being called
accepts an address.

### Mapping overload sets

C++ has complex overload resolution rules, in part to support certain API design
patterns. Some API design patterns appeared as a consequence of overload
resolution rules. Therefore, in C++ an "API atom" is an overload set, not an
individual function ([CppCon 2018: Titus Winters "Modern C++ Design (part 1 of
2)"](https://www.youtube.com/watch?v=xTdeZ4MxbKo)). The same is also the case in
Swift, so, fundamentally, there is no impedance mismatch here.

However, C and Objective-C interoperability imports each function and method
separately. For C++ interoperability, we should recognize design patterns that
use overload sets, and map them appropriately to Swift.

One such C++ pattern is providing two overloads: one that takes a `const T&` and
another that takes a `T&&`. If we attempt to naively map them to Swift, they
would map to the same signature. If we import just one of them and ignore the
other, we would be leaving performance on the table.

The easiest way to map such overload sets is to import the `T&&` overload as a
function that takes the argument by value, and ignore the `const T&` overload.
This approach does create a small amount of performance overhead (an extra
move), but does not require changing the Swift language or type checker to
recognize the concept of temporaries. The SIL optimizer seems like the
appropriate place to opportunistically reclaim that performance, by removing
unnecessary moves of temporaries where possible, and replacing calls to the
thunk with calls to the most appropriate C++ entry point.

```c++
// C++ header.

struct Tensor { ... };

void processTensor(const Tensor&);
void processTensor(Tensor&&);
```

```swift
// C++ header imported in Swift.

struct Tensor { ... }

func processTensor(_: Tensor) {
  // call `void processTensor(Tensor&&)`
}
```

```swift
// Usage example.

func useTensor() {
  var x = Tensor()
  processTensor(x)
  processTensor(x)
}
```

```swift
// Equivalent of SIL code after optimizations.

// void processTensor(const Tensor&);
func processTensorByConstRef(_: UnsafePointer<Tensor>)

// void processTensor(Tensor&&);
func processTensorByRvalueRef(_: UnsafeMutablePointer<Tensor>)

func useTensor() {
  var x = Tensor()
  processTensorByConstRef(x)
  processTensorByRvalueRef(x) // Automatically move the value because it is obviously not used anymore.
}
```

Once move-only types are added to Swift, the same mapping technique becomes
applicable to C++ move-only value types as well, with the only difference that
argument of the imported function would be marked as being consumed.

### Inline functions

Inline functions (both free and member functions) are used in C++ a lot more
than inline functions in C. For inline functions in C++, Swift should use the
same strategy as it uses currently for C: use Clang's CodeGen libraries to
emit definitions of inline functions into one LLVM module together with Swift
code.

## Namespaces and modules

Namespaces and modules in C++ are orthogonal concepts. Namespaces in C++ can
span multiple modules; C++ namespaces can also be nested. In Swift, modules are
namespaces.

**Option 1: Map C++ namespaces to empty enums in Swift.**

There are precedents for using empty enums as namespaces in Swift (for example,
`CommandLine`, `Unicode`, `Unicode.UTF8` in the standard library).
However, empty enums are not a perfect substitute for C++ namespaces:

- Swift has no `using`-like construct that allows code to avoid qualifying names
  nested in an enum (in other words, names nested within an enum must be always
  qualified with the name of that enum when used).

- C++ namespaces can span multiple modules. We don't want every imported C++
  module to define its own empty enum, as that will lead to name collisions,
  which will require even more qualification from users.

```c++
// C++ header in module `CppButton`.

namespace widgets {
class Button {};
}
```

```c++
// C++ header in module `CppTextbox`.

namespace widgets {
class Textbox {};
}
```

```swift
// C++ module `CppButton` imported to Swift.

enum widgets {
  struct Button {}
}
```

```swift
// C++ module `CppTextbox` imported to Swift.

enum widgets {
  struct Textbox {}
}
```

```swift
// Usage example: everything works well when we import only `CppButton`.

import CppButton

func makeButton() {
  var b1 = Button() // error: no such type
  var b2 = widgets.Button() // OK
}
```

```swift
// Usage example: ambiguities when we import both `CppButton` and `CppTextbox`.

import CppButton
import CppTextbox

func makeButton() {
  var b1 = Button() // error: no such type
  var b2 = widgets.Button() // error: name `widgets` is ambiguous, did you mean `CppButton.widgets` or `CppTextbox.widgets`?
  var b3 = CppButton.widgets.Button()
}
```

**Improvement for option 1: Move all empty enums to one synthetic module.**

We could fix the ambiguity between same-named namespace enums defined by
multiple C++ modules by synthesizing an extra Swift module that will contain
only the enums that make up the namespace structure, and then making all other
C++ modules define extensions for those enums.

```swift
// Swift module `CppNamespaces` synthesized by the C++ importer.

enum widgets {}
```

```swift
// C++ module `CppButton` imported to Swift.

import CppNamespaces

extension widgets {
  struct Button {}
}
```

```swift
// C++ module `CppTextbox` imported to Swift.

import CppNamespaces

extension widgets {
  struct Textbox {}
}
```

```swift
// Usage example.

import CppButton
import CppTextbox
// Implicitly injected: import CppNamespaces

func makeButton() {
  var b1 = Button() // error: no such type
  var b2 = widgets.Button() // OK
}
```

An incidental readability advantage of using enum extensions is that the
pretty-printed module interface for C++ modules will use the keyword `extension`
for namespaces instead of `enum`, reducing the confusion potential.

**Improvement for option 1: Add a `using`-like construct to Swift.**

Some C++ libraries define namespaces with long names, or deeply nested
namespaces. C++ users of such libraries often prefer to avoid typing and seeing
such namespace qualifiers in their code. To help use these libraries in Swift,
we could add a construct similar to C++ `using`, that would expand the name
lookup into the given empty enum.

```swift
// Usage example.

import CppButton
import CppTextbox
// Implicitly injected: import CppNamespaces
import CppNamespaces.widgets

func makeButton() {
  var b1 = Button() // OK
}
```

We could limit this construct to only work with enums in the `CppNamespaces`
module, if such feature is not deemed to be appropriate for APIs defined in
Swift.

**Option 2: Introduce namespaces into Swift as a C++ interoperability feature.**

From the implementation point of view, option 1 feels like a pile of hacks and
tricks. We could add C++-style namespaces to Swift, and only allow the C++
importer to define them, clearly designating namespaces as a C++
interoperability feature. From the point of view of users, there will be very
few, if any, differences between option 1 and option 2.

**Option 3: Introduce namespaces into Swift.**

We could add C++-like namespaces to Swift as a generally available language
feature, and then use it to import C++ into Swift.

### The "std" namespace

An interesting question is how to import the `std` namespace in Swift.
Continuing to call it `std` might invoke incorrect associations, because APIs in
`std` are not a part of the Swift standard library. We could rename `std` to
something that suggests that it is the C++ standard library, like `cxx_std`.

## Structs and classes

### Mapping the type itself and its special member functions

For the purposes of this discussion, we will consider C++ classes only.  There
are no important technical differences between C++ structs and classes, both
have exactly the same capabilities. In C++, structs and classes differ in how
they are typically used, however, it is not enforced by the compiler.  Different
style guides have different rules about when to define a struct or a class, and
these rules are often not toolable in principle.  Therefore, struct/class
distinction in C++ can be used at best as a hint to guide the API importer.

Swift's structs and classes are two completely different concepts. Structs are
the building block for value types, and classes are the building block for
reference types. References to Swift class instances are similar to
`std::shared_ptr<T>` in C++ (but are more efficient, because they use an
intrusive refcount), and therefore are not suitable for mapping an arbitrary C++
class type.

As far as value/reference semantics go, C++ classes are similar to structs in
Swift: both inherit value/reference semantics from constituent parts (if you
compose value types in a C++ class or a Swift struct, you get a value type; if
you embed a reference type in a C++ class or in a Swift struct, the composite
type behaves like a reference type). They are also similar in their memory
allocation strategy: both are allocated inline (local variables are allocated on
the stack, member variables are allocated in the containing object without an
indirection).

C++ classes allow the API owner to separately control whether the value is
copyable, movable, copy-assignable, move-assignable, and destructible. Moreover,
behavior for those operations can be customized. User-defined structs in Swift
can't customize such operations. User-defined Swift classes can only customize
the `deinit`, which corresponds to the destructor in C++. Nevertheless, this
limitation only applies to user-defined Swift structs and classes. There are
more mechanisms in the Swift object model, compiler, and runtime, that are not
exposed as language features, but exist as hooks for future extension (e.g.,
some were added specifically for potential C++ interop), or exist to support
Swift language features like resilience.

Let's take a look at what types look like in the compiler and runtime, and what
sorts of customization hooks are available.

The compiler classifies types as loadable or address-only (either one or the
other). Address-only types are always manipulated through a pointer. Loadable
types can be loaded from memory into SIL and LLVM IR values, and then
reconstructed back in memory.

The compiler uses different strategies to access and manage values depending on
the classification of the type.  For example, trivial loadable types can be
freely copied, destroyed, and moved around in memory without running any
user-defined code. Structs imported from C are considered loadable in Swift. C
structs are only composed of C primitives, and therefore are considered trivial
-- can be initialized, assigned, and moved around with `memcpy`.

Resilient Swift types are on the complete opposite end of the spectrum.
Resilient types are types provided by a third-party library that does not want
to commit to a particular ABI for that type. Resilient types are opaque values
that must be manipulated through a value witness table -- a table of function
pointers that defines the following operations:

| Swift Value Witness Operation | C++ equivalent                                                           |
| ----------------------------- | ------------------------------------------------------------------------ |
| `initializeWithCopy`          | copy constructor                                                         |
| `assignWithCopy`              | copy assignment operator                                                 |
| `initializeWithTake`          | move constructor, followed by a call to destructor on the source         |
| `assignWithTake`              | move assignment operator, followed by a call to destructor on the source |
| `destroy`                     | destructor                                                               |
| `size`                        | `sizeof(T)` minus trailing padding                                       |
| `stride`                      | `sizeof(T)`                                                              |
| `flags`                       | among other information, contains alignment, i.e., `alignof(T)`          |

Value witness tables also contain composite operations that can be derived from
the operations above.

We can map an arbitrary copyable C++ class type to a Swift struct type whose
value witnesses call the corresponding special member function of the C++ class.

We can map certain C++ classes to a more optimizable representation in Swift.
For example, C++ classes that contain only primitives and have trivial special
member functions (i.e., POD types) can be mapped to trivial loadable Swift
structs, just like C structs are today.

Can we map more complex C++ classes to loadable Swift structs? Someone with a
more thorough knowledge of runtime and SIL should answer, but here's what the
author of the document could find.

From `swift/docs/SIL.rst`:


> Loadable types are types with a fully exposed concrete representation:
>
> * Reference types
> * Builtin value types
> * Fragile struct types in which all element types are loadable
> * Tuple types in which all element types are loadable
> * Class protocol types
> * Archetypes constrained by a class protocol

"Fully exposed concrete representation" looks like a definition of a loadable
type, however, other comments say slightly different things, and it is not clear
what "fully exposed" actually means.

From `swift/include/swift/SIL/TypeLowering.h`:

```c++
/// Is a lowered SIL type address-only?  That is, is the current context
/// required to keep the value in memory for some reason?
///
/// A type might be address-only because:
///
///   - it is not fixed-size (e.g. because it is a resilient type) and
///     therefore cannot be loaded into a statically-boundable set of
///     registers; or
///
///   - it is semantically bound to memory, either because its storage
///     address is used by the language runtime to implement its semantics
///     (as with a weak reference) or because its representation is somehow
///     address-dependent (as with something like a relative pointer).
///
/// An address-only type can be fixed-layout and/or trivial.
/// A non-fixed-layout type is always address-only.
enum IsAddressOnly_t : bool {
  IsNotAddressOnly = false,
  IsAddressOnly = true
};
```

C++ classes are fixed-size, so we don't care about the first bullet point. The
second bullet point is more interesting -- a type must be address-only if an
instance of that type cares about which address it is stored at.

From [Slava Pestov's blog post "How to talk to your kids about SIL type
use"](https://medium.com/@slavapestov/how-to-talk-to-your-kids-about-sil-type-use-6b45f7595f43):

> If you define a C++ class describing a smart pointer to a reference-counted
> object, the presence of a custom copy constructor and destructor force the
> value to be materialized in memory all of the time, because the compiler
> doesn't know what the hell you're doing inside the custom constructor; maybe
> you're taking the address of ‘this' and storing it somewhere.
>
> If C++ had loadable types, they would involve some kind of special annotation
> that told the compiler that the move constructor can just trivially do a
> memcpy() of the value, even if there is a custom copy constructor or
> destructor. At this point, your smart pointer could be loaded into a register
> and passed around without issues.

This example says that a C++ smart pointer, with a custom copy constructor, copy
assignment operator, and destructor, can be loadable, as long as all move
special member functions are trivial. This explanation aligns well with the
previous one.

A C++ class is loadable in Swift as long as moving it is trivial. If we ignore
C++ classes with inconsistent copy and move semantics, a trivial move implies
that copy constructor and copy assignment don't care about the specific address,
which matches Swift's requirements.

### Special member functions with incorrect semantics

C++ classes can define special member functions with incorrect or inconsistent
semantics. It can be done intentionally; for example, the copy constructor of
`auto_ptr` actually moves the value. It can also be done unintentionally: it is
common to define only the special member functions that the C++ code happens to
use right now -- for example, only define the copy constructor but not the copy
assignment.

Therefore, we need to decide whether the Swift/C++ interoperability layer should
trust special member functions of C++ classes to have expected semantics, or
whether some verification is necessary.

Non-user-provided special member functions have correct semantics by
construction if the C++ class is composed of well-behaved types. Given the
current state of the art in static analysis, it does not seem like the
interoperability layer even remotely has a chance of proving that user-provided
special member functions have correct semantics. There are two practical
options: either trust the user in this regard and allow them to adjust the
inference done by the interop layer with annotations, or don't make any
assumptions about the semantics and demand that the user annotates types as
value types, move-only, or non-movable.

### Special member functions that throw exceptions

If C++ classes are imported in Swift as structs, there seems to be no reasonable
way to map exceptions thrown from special member functions to an error that can
be handled in Swift.

While it is possible to [propagate C++ exceptions](#exceptions) thrown by normal
member functions to Swift code, special member functions are different as they
used to implement value witnesses, which are called by the compiler
implicitly. Therefore, either such exceptions have to be mapped to fatal errors
(as we do for other unhandled C++ exceptions), or calls to such special member
functions must be prevented statically.

Preventing such calls statically seems difficult. Also, in practice, special
member functions throw mostly due to out-of-memory conditions, which is
considered unrecoverable in Swift. Therefore, the practical solution is to
map exceptions from special member functions to fatal errors.

If the user must use a C++ class with throwing special member functions from
Swift, a reasonable workaround would be to write a wrapper that exposes these
operations as regular APIs. Wrappers can even be synthesized by the importer, if
such classes are found to be common.

```c++
// Can't be imported in Swift.
class MyThrowingType {
public:
  MyThrowingType() { if(...) throw ...; }
  ~MyThrowingType() { if(...) throw ...; }
  void method();
};

// Can be imported in Swift.
class MyThrowingTypeWrapper {
private:
  std::unique_ptr<MyThrowingType> value_;
public:
  MyThrowingTypeWrapper(): value_(nullptr) {}
  void init() /* can throw */ { value_ = std::make_unique<MyThrowingType>(); }
  void deinit() /* can throw */ { value_ = nullptr; }
  void method() { value_.method(); }
};
```

### Precise destruction semantics

C++ language specifies the exact point in program execution at which destructors
should run, while Swift does not. Some C++ APIs rely on these guarantees to work
properly (for example, RAII types like mutex locks).

```c++
// A pure C++ program.

class PickyCxxClass {
public:
  ~PickyCxxClass() { ... }
};

void test1() {
  PickyClass c;
  printf("Hello");
  // `c`'s destructor is guaranteed to be called exactly here.
}
```

```swift
// A pure Swift program, similar to the C++ program above.

struct SwiftStruct { ... }

func test1() {
  var s = SwiftStruct()
  // `s` can be deallocated here.
  print("Hello")
  // `s` can also be deallocated here.
}
```

But how commonly do C++ APIs rely on precise destruction? A gut feeling is that
it happens pretty often, but it is not always intentional and acknowledged by
the API vendor. *All* C++ types get a precise destruction point, and therefore,
it is very easy to start inadvertently relying on it in API design.

There are multiple ways to deal with this impedance mismatch.

**Ignore the differences, and apply Swift destruction semantics to C++
classes.** This approach will work for most C++ classes. However, C++ classes
that rely on C++ destruction semantics won't work well in Swift.

**Force the user to always pick a destruction point for values of C++ types.**
Too much burden on the user, and the code won't look like normal Swift.

**Allow the user to pick a destruction point, otherwise let the compiler pick.**
This approach will work, but it trusts the user to do the right thing every
time a certain C++ class is used. Often, whether precise destruction point is
required or not depends on the type.

**Define a destruction point for C++ classes.** This can't be done universally
in all Swift code, but it is feasible for local variables of concrete types.

An example where it is not possible to maintain precise destruction semantics
for C++ classes is in a generic Swift function that is called with a C++ class
as a type parameter. In this case, we must be able to compile one definition of
a Swift function, which must work regardless of the nature of the type (be it a
Swift type or a C++ class). This limitation does not seem too bad, because RAII
types are not often passed as type parameters to templates in C++, which creates
a reason to believe it will not be common in Swift either.

**Allow the API owner to annotate the C++ class as requiring a precise
destruction point.** An improvement upon the previous approach where unusual
semantics are only applied to C++ classes that need them, for example, RAII
types like mutex locks.

The pragmatic choice is to implement one of the last two options.

If a precise destruction point is defined for annotated C++ classes, here's an
example of behavior that we get:

```c++
// C++ header.

[[swift::requires_precise_destruction]]
class PickyCxxClass {
public:
  ~PickyClass() { ... }
};
```

```swift
// C++ header imported in Swift.

struct PickyCxxClass {
  // The destructor is not imported as a declaration into Swift, however,
  // it is mapped to a value witness function, and it is called when the
  // lifetime of the object ends, like in C++.
}
```

```swift
func testConcreteType() {
  var c = PickyCxxClass()
  print("Hello")
  // `c` will be deallocated here.
}

func testTypeParameter<T>(_ t: T.self) {
  var c = T()
  // `c` can be deallocated here, even if `c` is a `PickyCxxClass`.
  print("Hello")
  // `c` can also be deallocated here.
}

testTypeParameter(PickyCxxClass.self)
```

### Member functions that return inner pointers

When a member function in a C++ class returns a pointer (or a reference), most
commonly the lifetime of that pointer is limited to the lifetime of the object
itself. C++ code often relies on precise destruction semantics to ensure that
the object that owns the memory lives long enough. Another problem is that the
Swift compiler can move the object around in memory whenever it wants,
invalidating those outstanding inner pointers.

```c++
// C++ header.
class Employee {
private:
  std::string company_;
public:
  std::string *mutable_company() { return &company_; }
};
```

```swift
// C++ header imported in Swift.

struct Employee {
  func mutable_company() -> UnsafeMutablePointer<std.string>
}
```

```swift
func test() {
  var employee: Employee = ...
  var company = employee.mutable_company()

  // HAZARD: `employee` could have been moved to a different location in memory
  // by now, invalidating the `company` pointer.
  company.pointee = "A"

  print(employee)

  // HAZARD: `employee` can be deallocated here, however, `company` is still
  // accessible.
  company.pointee = "B"
}
```

To fix the problem of values being moved around in memory, we need to tell the
Swift compiler about the connection between pointers and objects that own the
memory.

```c++
// C++ header.

class Employee {
private:
  std::string company_;
public:
  [[swift::returns_inner_pointer]]
  std::string *mutable_company() const { return &_company; }
};
```

The `returns_inner_pointer` attribute can be added manually to the C++ headers,
or it can be safely inferred on all member functions that return a pointer or
reference, to reduce annotation burden.  Inferring this annotation on functions
that don't actually need it is harmless (does not change semantics, and does not
create unsafety), but may prevent some optimizations.

To fix the lifetime problem, the lifetime of a local variable can be extended
until the end of the scope if the current scope called a method that returns an
inner pointer.

```swift
func test() {
  var employee: Employee = ...
  var company = employee.mutable_company()

  // ... any amount of code...

  // `employee` is destroyed at the end of the scope because of the `mutable_company` call.
}
```

This technique will not work for temporaries (instead, they need to be extended
to the end of the full expression). It is also not very useful to call methods
that return inner pointers on temporaries.

### Differences in move semantics between C++ and Swift

Swift's "move" operation will leave the source value uninitialized (see
[ownership manifesto](OwnershipManifesto.md)); this operation is called a
"destructive move". C++ has "non-destructive moves" that leave the source value
initialized, but in an indeterminate state.

The following sections address various aspects of this impedance mismatch
between the two languages.

### Move-only C++ classes

For the purposes of this document, we will call C++ classes that can be moved
but don't have a public copy constructor and a public copy assignment operator
"move-only C++ classes".

Swift does not have move-only types at the time this document was written
(January 2020). There is a desire to add them, and a lot of design work has been
done (see the [Ownership Manifesto](OwnershipManifesto.md)), however, this
design has not been proposed yet.

Therefore, we will first discuss mapping move-only C++ classes to Swift before
move-only types are implemented. In this situation there's clearly no good
direct mapping. There are some non-ergonomic options though.

Second, we will discuss mapping move-only C++ classes to move-only types in
future Swift versions.

### Move-only C++ classes: mapping in Swift 5

**Import move-only C++ classes as Swift structs, and statically ensure that
copies are never needed.**

This seems doable, although the usability and predictability of the language
feature will depend on the compiler stage where the checks are done. It is easy
to perform such checks at the SIL level, however, the language might not behave
predictably. It is a more difficult to do such checks on the AST, but the
language will be more predictable from the user's point of view. Also, AST-based
checks might reject more programs than people expect.

Since value witness tables require a valid copy witness, it will be also
necessary to prohibit passing such pseudo-move-only types into generic code as
type parameters, or force full specialization of generic functions, and perform
the checks on fully-specialized SIL.

Here's a sketch of rules for move-only types that are reasonably simple to check
at compile-time and provide good diagnostics, at the expense of the resulting
code being non-ergonomic. Move-only C++ classes can be imported in Swift as
structs as usual, however, such structs can't be used as values. The compiler
would only allow `UnsafePointers` to them, and would allow calling methods on
`UnsafePointer.pointee`. When move-only types are used as C++ class members,
Swift can import them as opaque blobs, and expose a `withUnsafePointer`-style
API to get an `UnsafePointer` to the data member.

```c++
// C++ header.

// `File` is a move-only C++ class.
class File {
private:
  int file_descriptor_;
public:
  File(std::string_view filename);
  File(const File &) = delete;
  File(File &&) = default;
  ~File();

  File& operator=(const File &) = delete;
  File& operator=(File &&) = default;

  std::string ReadAll();
};

// `TwoFiles` is move-only because it is composed of move-only parts.
struct TwoFiles {
  File firstFile;
  File secondFile;
};
```

```swift
// C++ header imported in Swift.

struct File {
  public init(_ filename: std.string_view)
  public func ReadAll() -> std.string
}

struct TwoFiles {
  private var _firstFile: <unspecified-opaque-storage>
  private var _secondFile: <unspecified-opaque-storage>

  func withUnsafePointerToFirstFile<Result>(
    _ body: (UnsafePointer<File>)->Result
  ) -> Result {
    body(&_firstFile)
    _fixLifetime(self)
  }

  func withUnsafePointerToSecondFile<Result>(
    _ body: (UnsafePointer<File>)->Result
  ) -> Result {
    body(&_secondFile)
    _fixLifetime(self)
  }
}
```

```swift
// Usage example.

func useOneFile(_ f: UnsafeMutablePointer<File>) {
  // var f2 = f.pointee // compile-time error: can only call a method on 'pointee'.
  print(f.pointee.ReadAll()) // OK

  // Move `f` to a different memory location.
  var f2 = UnsafeMutablePointer<File>.allocate(capacity: 1)
  f2.moveInitialize(from: f, count: 1)
  // `f` is left uninitialized now.

  print(f2.pointee.ReadAll()) // OK
  f2.deallocate() // OK
  // The file is closed now.
}

func useTwoFiles(_ files: UnsafeMutablePointer<TwoFiles>) {
  // Like `print(files.first.ReadAll())`, if it was possible to compile it:
  files.pointee.withUnsafePointerToFirst { print($0.ReadAll()) }
}
```

If we add support for [marking APIs as returning inner
pointers](#member-functions-that-return-inner-pointers), we could make the
imported API nicer:

```swift
// C++ header imported in Swift.

struct TwoFiles {
  private var _firstFile: <unspecified-opaque-storage>
  private var _secondFile: <unspecified-opaque-storage>

  @_returnsInnerPointer
  var firstFile: UnsafePointer<File> { get }

  @_returnsInnerPointer
  var secondFile: UnsafePointer<File> { get }
}
```

### Move-only C++ classes: mapping to move-only Swift types (in future Swift versions)

This section is based on the design for move-only Swift types that has not been
officially proposed yet. See [ownership manifesto](OwnershipManifesto.md) for
the design for ownership and move only types that we assume in this section.

Move-only C++ classes correspond to `moveonly` structs in Swift. Semantic
analysis ensures that they are never copied.

Moves that destroy the source are spelled `move(x)` in Swift. Swift does not
have a concept of non-destructive move; a section below discusses possible
design options.

```c++
// C++ header.

class File {
private:
  int file_descriptor_;
public:
  File(std::string_view filename);
  File(const File &) = delete;
  File(File &&) = default;
  ~File();

  File& operator=(const File &) = delete;
  File& operator=(File &&) = default;

  std::string ReadAll();
};
```

```swift
// C++ header imported in Swift.

moveonly struct File {
  public init(_ filename: std.string_view)
  public deinit

  public func ReadAll() -> std.string
}

moveonly struct TwoFiles {
  var first: File
  var second: File
}
```

```swift
// Usage example.

func useOneFile(_ f: File) {
  print(f.ReadAll()) // OK

  // Move `f` to a different memory location.
  var f2 = move(f)

  // print(f.ReadAll()) // compile-time error: can't access `f`, its value was moved

  print(f2.ReadAll()) // OK
  endScope(f2) // OK
  // The file is closed now.
}

func useTwoFiles(_ files: TwoFiles) {
  print(files.first.ReadAll()) // OK
}
```

### Non-destructive moves

Generally, Swift code that uses values of C++ class types should use Swift's
destructive moves in most cases where C++ code would have used a non-destructive
move. However, certain C++ APIs are designed to be used with non-destructive
moves, therefore, non-destructive moves should be made available in Swift.
Adding non-destructive moves to Swift as a native language feature is a
non-starter.

Consider the following C++ code:

```c++
// Example of C++ API design that requires users to perform non-destructive
// moves.

class Example { /* move-only */ };

std::optional<Example> getExample();
void processExample(Example e);

void test() {
  std::optional<Example> e = getExample();
  processExample(std::move(e.value()));
}
```

Equivalent Swift code would look like this:

```swift
// Equivalent Swift code.

func test() {
  var e: cxx_std.optional<Example> = getExample();

  processExample(move(e.value()));
  // If we assume that the previous line compiled, we have a problem:
  // `cxx_std.optional` does not know that the value was destructively moved
  // and will try to delete it again.
}
```

Of course, one could argue that the interoperability layer could provide special
support for `std::optional`, and make it work with destructive moves better.
While that is true, the point still stands: there will be C++ APIs that expect
users to perform non-destructive moves, and should ensure that they are usable
from Swift without overlays or special compiler support.

**Option 1: Non-destructive moves in Swift are swaps with an arbitrary valid
value.**

It is easy to model a non-destructive move in Swift as a swap with a
default-initialized value.

```swift
// Swift standard library, C++ support module.

public protocol DefaultInitializable {
  init()
}

public moveonly func cxxMove<T: DefaultInitializable>(_ value: inout T) -> T {
  var result = T()
  swap(&value, &result)
  return result
}

public moveonly func cxxMove(_ value: inout T, replacingWith newValue: T) -> T {
  var result = newValue
  swap(&value, &result)
  return result
}
```

```swift
// Usage example.

// This function takes a `File` by value, consuming it.
func consumeFile(_ f: File) { ... }

func useArrayOfFiles() {
  var files: [File] = ...
  // consumeFile(files[0]) // compile-time error: can't copy a `File`

  // Swift's move does not help.
  // consumeFile(move(file[0]))
  // compile-time error: moving one element of an array will cause a
  // double-destruction of `File` when the array is destroyed.

  consumeFile(cxxMove(&file[0])) // OK, replaced `file[0]` with a `File()`.

  consumeFile(cxxMove(&file[1], replacingWith: File("/tmp/example.txt")))
  // OK, replaced `file[1]` with a newly-opened file.
}
```

The advantage of this approach is that we avoid creating "valid but
indeterminate" values, which can be hazardous. However, such values can be
passed from C++ to Swift at any time, even if Swift code can't create them
directly. It is also awkward to require the user to come up with a dummy valid
value when the type is not default-constructible.

**Option 2: Non-destructive moves in Swift invoke the C++ move constructor.**

So, we want to perform a real C++ move and leave a "valid but indeterminate"
value in the source. For that, we must enable the Swift to call the C++ move
constructor.

If `class File` has a move constructor in C++, the imported Swift struct defines
a corresponding initializer:

```c++
// C++ header imported in Swift.

public moveonly struct File {
  // File(File &&);
  public init(cxxMovingFrom: inout File)
}
```

```swift
// Usage example.

func useArrayOfFiles() {
  var files: [File] = ...
  consumeFile(File(cxxMovingFrom: &files[0]))
}
```

The move syntax, `File(cxxMovingFrom: &files[0])`, is quite verbose and requires
repeating the name of the type, whereas the corresponding C++ construct,
`std::move(x)`, does not. When type context is available, the expression can be
abbreviated to `.init(cxxMovingFrom: &files[0])`. We can make it more concise by
synthesizing a helper method in movable types:

```swift
// C++ header imported in Swift.

public moveonly struct File {
  // File(File &&);
  public init(cxxMovingFrom: inout File)

  public mutating func cxxMove() -> File {
    return File(cxxMovingFrom: &self)
  }
}
```

```swift
// Usage example.

func useArrayOfFiles() {
  var files: [File] = ...
  consumeFile(files[0].cxxMove())
}
```

Although methods are more in line with Swift API design than free functions,
injecting names into C++ types can backfire due to naming collisions.

Alternatively, we could model non-destructive moves with a free function,
imitating the C++ syntax. To do this we need a protocol for non-destructively
movable types, and a free function that calls the move constructor:

```swift
// Swift standard library, C++ support module.

public protocol NonDestructivelyMovable {
  public init(cxxMovingFrom: inout Self)
}

public moveonly func cxxMove<T: NonDestructivelyMovable>(_ value: inout T) -> T {
  return T(cxxMovingFrom: &value)
}
```

```swift
// C++ header imported in Swift.

public moveonly struct File: NonDestructivelyMovable {
  public init(cxxMovingFrom: inout File)
}
```

```swift
// Usage example.

func useArrayOfFiles() {
  var files: [File] = ...
  consumeFile(cxxMove(&files[0]))
}
```

It is also useful to expose the move assignment operation in Swift. Even though
move assignment is not necessary to implement `cxxMove()`, it can be used for
optimization.

```swift
// C++ header imported in Swift.

public moveonly struct File {
  // File(File &&);
  public init(cxxMovingFrom: inout File)

  // File& operator=(File &&);
  public func moveAssignFrom(_ value: inout File)
}
```

The compiler could perform a high-level optimization replacing `x = cxxMove(&y)`
(which creates a temporary, and calls the move constructor twice) with
`x.moveAssignFrom(&y)` (which does not create a temporary and calls move
assignment only once).

### Non-movable C++ classes

By non-movable C++ classes we mean C++ classes that don't have a copy
constructor or a move constructor.

Swift does not have any struct-like equivalent to non-movable C++ classes, and
there's nothing planned in that area. Therefore, we have to either creatively
reuse one of existing Swift's features, or add some new features to Swift.

**Option 1: Map non-movable C++ classes to Swift structs.**

If we want to map all C++ classes to structs in Swift, one approach to make
non-movable C++ classes work is only importing pointers to non-movable types;
this approach is described in detail in the section about [importing move-only
types in Swift 5](#move-only-c-classes-mapping-in-swift-5). Non-movable classes
in C++ are often used as polymorphic base classes. Allowing to only use pointers
to such types is not a bad limitation. The primary disadvantage of this approach
is ergonomics.

**Option 2: Map non-movable C++ classes to Swift classes.**

While Swift structs are a bad match for non-movable C++ classes, Swift classes
match semantics better. For example, instances of Swift classes, once allocated,
stay at the same address until `deinit`. Instances of Swift classes are always
worked with indirectly, eliminating the need to move them around in memory.

Although user-defined Swift classes have a certain memory layout determined by
the Swift compiler (for example, the memory block should start with an object
header that contains a metadata pointer and a refcount), that exact memory
layout is not necessary for a type to successfully masquerade as a Swift class.
For example, Swift already imports CoreFoundation types as "foreign classes";
from the user's point of view they look like ordinary classes.

The biggest semantic impedance mismatch between C++ classes and Swift classes is
that Swift classes are reference-counted. It is certainly possible to import a
C++ class as a Swift class if it is intrusively reference counted, or wrapped in
a `shared_ptr`.

But what about non-movable C++ classes that are not reference counted? This
issue could be worked around by making retain and release operations on C++
classes be a no-op, and introducing an explicit "delete" operation, effectively
making C++ class references in Swift equivalent to `UnsafeMutablePointer`.

```c++
// C++ header.

class NonMovable {
public:
  NonMovable(const NonMovable &) = delete;
  NonMovable(NonMovable &&) = delete;
  ~NonMovable();

  NonMovable &operator=(const NonMovable &) = delete;
  NonMovable &operator=(NonMovable &&) = delete;

  void debugPrint() const;
};
```

```swift
// C++ header imported in Swift.

class NonMovable {
  // Runs `delete this`.
  func delete()

  func debugPrint()
}
```

```swift
func useNonMovable(nm: NonMovable) {
  var nm2 = nm
  // `nm2` now points to the same object as `nm`. No reference-counting.

  nm.debugPrint() // OK
  nm2.debugPrint() // OK

  nm2.delete() // OK
  // The object is deallocated now. From this point, using `nm` or `nm2`
  // is undefined behavior.
}
```

Everything seems to work really well, except that we broke Swift's safety
guarantees about classes. Swift manages lifetime of regular user-defined classes
automatically; in safe Swift code it is not possible to get a dangling class
reference; it is also weird that users would have to manually deallocate class
instances. Therefore, classes imported from C++ would behave very differently
from user-defined Swift classes; most importantly, they are unsafe. This issue
seems incompatible with Swift's design and philosophy. Otherwise, importing C++
classes as Swift classes looks like a viable implementation strategy.

The unsafety issue could be mitigated by adding the word "unsafe" somewhere in
the source code. For example, importing a non-movable C++ class `Example` as a
Swift class `UnsafeExample`, or requiring the user to write the keyword "unsafe"
before the type name:

```swift
func useNonMovable(nm: unsafe NonMovable) { ... }
```

### Member functions

Member functions of C++ classes are most naturally mapped to methods in Swift
structs. C++ allows to add various qualifiers to member functions, which we
discuss in the following sections.

### Const-qualified member functions in C++ classes

Member functions of C++ classes can be marked with a `const` qualifier; however,
this qualifier does not provide any semantic guarantees. Const-qualified methods
can change the state of the object through a variety of mechanisms.

`const_cast` is the first language feature that comes to mind when one thinks
about modifying a const object. As long as an object was originally allocated as
non-const, its const-qualified methods can cast const away and mutate the
object. Detecting potential `const_cast`s is quite difficult, since it requires
examining everything that a const member function can call, transitively.
However, in practice, `const_cast`s are rare, and given the more pervasive
issues described below, `const_cast`s can be ignored.

```c++
class SneakyMutation {
private:
  int value = 0;
public:
  void mutateSneakily() const { opaqueMutator(this); }
  void setValue(int newValue) { value = newValue; }
};

// in a different file:
void opaqueMutator(const SneakyMutation* sm) {
  const_cast<SneakyMutation*>(sm)->setValue(42);
}
```

Another C++ feature that allows const-qualified member functions to mutate the
object is "mutable" data members. Mutable data members are a lot more common
than `const_cast`s, but fortunately they are trivial to detect statically.

```c++
class SneakyMutation {
private:
  mutable int value = 0;
public:
  void mutateSneakily() const { value = 42; }
};
```

Yet another C++ feature that allows const-qualified methods to mutate the object
is aliasing. A const member function can obtain a pointer to the same object
through some other means, and change the pointed-to data.

```c++
class SneakyMutation {
private:
  int value = 0;
public:
  void mutateSneakily(SneakyMutation *other) const {
    other->value = this->value + 1;
    // What if `other` happens to be equal to `this`? In that case, a const
    // member function has mutated `this`!
  }
};

void test() {
  SneakyMutation sm;

  // A const method mutates the object that it is invoked on:
  sm.mutateSneakily(&sm);
}
```

Note that `mutateSneakily()` can obtain the alternative `this` pointer through a
variety of ways, not necessarily as a function argument. The method can find
another non-const pointer equal to `this` in a global variable or in a data
structure accessible from `this` itself. It also need not mutate `other` so
obviously: it can pass `other` to another function which will mutate it. It is
difficult to estimate how common such mutation is, however, it is not an element
of a common design pattern.

Swift's replacement for C++ const member functions are non-`mutating` functions:

```swift
struct Example {
  private var value: Int = 0
  mutating func mutatingFunction() { value = 42 }
  func nonMutatingFunction() {
    // value = 42 // would not compile
    print(value) // OK
  }
}
```

The biggest difference from C++ is that non-`mutating` functions in Swift are
really not allowed to mutate `self`; there are no backdoors. Some equivalents of
C++'s mutation backdoors are disallowed statically, some are disallowed
dynamically, some are undefined behavior.

The backdoors are disallowed by the exclusivity rule (from [SE-0176 Enforce
Exclusive Access to
Memory](https://github.com/apple/swift-evolution/blob/main/proposals/0176-enforce-exclusive-access-to-memory.md)):

> two accesses to the same variable are not allowed to overlap unless both
> accesses are reads

If we map C++ classes to Swift structs, how do we map C++'s `const` qualifier on
member functions? There are a couple of options.

* Ignore `const`, and mark all Swift struct functions as `mutating`. Allow API
  owners to manually annotate functions as non-`mutating`. This is a
  conservative and correct-by-default approach, but it is not ergonomic.

* Map `const` to non-`mutating` in Swift. This approach is very desirable from
  the point of view of ergonomics, however it is not safe in the general case.
  Nevertheless, in many cases such inference will be correct.

How can we make the second, ergonomic, approach safer? First of all, we should
allow C++ API owners to override the inferred `mutating`/non-`mutating` with an
annotation. API owners must have control over what their APIs look like in
Swift.

In addition, the compiler could do a lightweight static analysis to recognize
common problematic patterns, like `mutable` members and obvious `const_cast`s.
If the compiler finds anything alarming, it should refuse to perform inference
and require the user to manually annotate methods in C++ as `mutating` or
non-`mutating`.

### Volatile-qualified member functions

Volatile-qualified member functions are so rare that there's not enough value in
spending non-trivial engineering effort for them in the interop layer ensuring
that they map nicely. There are two easy ways to handle them:

* don't import volatile-qualified member functions,

* map member functions as if the `volatile` qualifier was not present.

### Ref-qualified member functions

TODO

### Final functions

TODO

### Getters and setters

Getters and setters in C++ classes most directly correspond to properties in
Swift. While it is certainly possible to map getters and setters to regular
methods, properties would be more ergonomic.

First of all, we need to find getter/setter pairs in a C++ class. We would need
to use name-based heuristics for that, while allowing the API owner to override
the inference with annotations (specifically, with the `swift_name` attribute).
There are a variety of naming styles for getters and setters in C++, but we only
need to cover the most common ones.

Getters take no arguments, return a `T` or a `const T`. Typical naming patterns
are: `AaaBbb()`, `GetAaaBbb()`, `aaaBbb()`, `getAaaBbb()`, `aaa_bbb()`,
`get_aaa_bbb()`

Setters take a `T`, a `const T&`, or a `T&&`, and return `void`. Typical naming
patterns are: `SetAaaBbb()`, `setAaaBbb()`, `set_aaa_bbb()`

Mutable accessors take no arguments and return a `T&` or a `T*`. Typical naming
patterns are: `MutableAaaBbb()`, `mutableAaaBbb()`, `mutable_aaa_bbb()`.

The C++ importer can synthesize a Swift property from a getter, from a
getter/setter pair, or from a getter and a mutable accessor. Swift does not have
set-only properties, so unpaired setters and mutable accessors will be imported
as regular methods.

```c++
// C++ header.

class Employee {
public:
  const std::string &getName() const;
  void setName(std::string newName);
};
```

```swift
// C++ header imported in Swift.

struct Employee {
  public var name: std.string { get set }
}
```

```swift
// Implementation details of the imported API.

struct Employee {
  // const std::string &getName();
  private func _getName() -> UnsafePointer<std.string>

  // void setName(std::string newName);
  private mutating func _setName(_ newName: std.string)

  // Swifty API.
  public var name: std.string {
    _read {
      yield _getName().pointee
    }
    set {
      _setName(newValue)
    }
  }
}
```

Sometimes the type returned by the getter will not match the type taken by the
setter. For example, the getter can return a `std::string_view`, while a setter
takes a `std::string`. `std::string_view` is like a `const std::string&`, so it
makes sense from the API perspective in C++. Swift, however, requires the getter
and setter to use the same type exactly.

We could teach the C++ importer about the most widely used type pairs, and
insert the appropriate type conversions in the synthesized property accessors.
However, these type conversions will carry a performance penalty, and the
resulting Swift API will be less performant than the original C++ API. For
example, consider a C++ class where a getter returns a `std::string_view`, and
the setter takes a `std::string`. If we synthesize a `std::string_view` property
in Swift, its setter would always copy the character data, even though in C++
the setter would move the `std::string`. If we synthesize a `std::string`
property in Swift, its getter would have to materialize a `std::string` from a
`std::string_view`.

Therefore, it seems like the best approach is to teach the C++ importer about
handling such mismatched types, but only perform property synthesis on demand,
triggered by an annotation in C++ code.

```c++
// C++ header.

// New attribute.
#define SWIFT_PROPERTY(type, name) __attribute__((swift_property(#type, #name)))

class Manager {
public:
  std::string_view getName() const SWIFT_PROPERTY(std::string, name);
  void setName(std::string newName) SWIFT_PROPERTY(std::string, name);

  std::span<const Employee> getReports() const;
  void setReports(std::vector<Employee> newReports);
};
```

```swift
// C++ header imported in Swift.

struct Manager {
  // Property is synthesized as requested by the annotation.
  public var name: std.string { get set }

  // Property is not synthesized because getter and setter operate on
  // different types.
  public func getReports() -> std.span<const<Employee>>
  public func setReports(_ newReports: std.vector<Employee>)
};
```

### Pointers to members

Pointers to members are quite rare in C++, so not importing them at all, at
least initially, would not be a big loss. Nevertheless, importing them is
possible.

Pointers to data members best correspond to keypaths in Swift. (TODO: need an
example.)

Pointers to member functions could be ergonomically mapped to curried functions,
just like struct and class methods in Swift can be converted to curried
functions.

```swift
// Inspiration from Swift: methods can be converted to curried functions.

// A normal user-defined struct.
struct Point {
  var x: Double
  var y: Double

  func distanceTo(_ line: Line) -> Double { ... }
}

var distanceToFunc: (Point) -> (Line) -> Double = Point.distanceTo
```

The only difference is that C++ member function pointers use a different memory
layout than Swift closures. Therefore, they would need to be imported with a
special calling convention, let's call it `@convention(cxx_method)`. Here's an
example:

```c++
// C++ header.

class Point {
public:
  double distanceTo(Line line) const;
};

void CallMemberFunctionPointer(Point p, double (Point::*ptr)(Line));
```

```swift
// C++ header imported in Swift.

public struct Point {
  public func distanceTo(_ line: Line) -> Double { ... }
}

func CallMemberFunctionPointer(
  _ p: Point,
  _ ptr: @convention(cxx_method) (Point) -> (Line) -> Double
)
```

### Virtual member functions

If we map C++ classes to Swift structs, it makes the most sense to map virtual
member functions to struct methods in Swift. However, Swift structs don't
support inheritance. So, while we can map virtual functions to methods and
execute C++ dynamic dispatch correctly, we can't express the fact that the
struct is subclassable, and that the method is overridable in Swift.

TODO: design how to map inheritance.

### Inherited APIs

Swift structs don't allow inheritance. If we map C++ classes as Swift structs,
we could replicate APIs from all base classes in every derived class.

```c++
// C++ header.

class Base {
public:
  void doBaseStuff();
};

class Derived : public Base {
public:
  void doDerivedStuff();
};
```

```swift
// C++ header imported in Swift.

public struct Base {
  public func doBaseStuff()
}

public struct Derived {
  public func doBaseStuff()
  public func doDerivedStuff()
}
```

### Conversions between derived and base classes

Swift structs don't allow inheritance, so it is not possible to directly express
the is-a relationship between derived classes and base classes. The is-a
relationship is not very important for non-polymorphic C++ classes, where
inheritance is typically used as an implementation technique, rather than an
intentional part of the API. In polymorphic classes the is-a relationship is
quite important and is an intentional part of the API.

So how to represent conversions between derived and base classes? There are two
cases to consider: converting values and converting pointers.

Converting values of derived type to values of base type is known as "object
slicing" in C++. It is well-known to be error-prone, but since some C++ APIs
might rely on it, we should try to expose it in Swift.

Object slicing is possible without any language extensions:

```swift
var derived: Derived = ...
var base: Base = UnsafeRawPointer(&derived).load(as: Base.self)
```

It is not very ergonomic, but not too bad for an operation that is known to be
error-prone. APIs that intentionally rely on object slicing could add helper
methods to types that intentionally participate in slicing:

```swift
// Manually written overlay for a C++ API.

extension Base {
  public init(_ other: Derived) {
    self = UnsafeRawPointer(&other).load(as: Base.self)
  }
  public init(_ other: UnsafePointer<Derived>) {
    self =  UnsafeRawPointer(other).load(as: Base.self)
  }
}
```

Now let's talk about conversions between pointers to derived type and pointers
to base type. These operations need to be ergonomic only for polymorphic
classes.

First of all, let's reject extending Swift's type casting operators `as` and
`as?` to handle casts between pointers to C++ objects. We need to convert
between `UnsafePointer<Base>` and `UnsafePointer<Derived>`, which are not
connected with a subtyping relationship in Swift. Implementing a conversion in
type casting operators (`as` and `as?`) that does not reflect a subtyping
relationship is not a good idea. Swift already has a couple of such conversions,
and they cause a lot of complexity in the compiler and the runtime. Moreover,
sometimes such casting behavior can be unexpected by users. Therefore, we are
going to explore API-based approaches to express upcasts and downcasts for C++
objects.

It is important to realize that interleaved accesses to an `UnsafePointer<Base>`
that aliases an `UnsafePointer<Derived>` violate Swift's type-based aliasing
rules. These rules could be relaxed for types imported from C++.

To prevent the user from accidentally violating type-based aliasing rules, Swift
intentionally does not provide an easy way to freely convert between pointers of
unrelated types. Swift allows to temporarily create an aliasing pointer;
however, that pointer has a scoped lifetime, and during that scope accessing the
original pointer is not allowed.

```swift
// Pointer conversion example in existing Swift language.

var basePtr: UnsafePointer<Base> = ...
basePtr.withMemoryRebound(to: Derived.self) {
  // In this closure, `$0` has type `UnsafePointer<Derived>` and
  // aliases `basePtr`.
  $0.doBaseStuff()
  $0.doDerivedStuff()
}
```

Type conversions are usually expressed as initializers in Swift. However, adding
an initializer to `UnsafePointer` for base/derived C++ class pair is going to
create a big overload set, which will negatively impact compilation performance.
Therefore, we should try to distribute the conversion APIs among the imported
types themselves. The importer could synthesize conversion APIs on base and
derived classes:

```swift
// C++ header imported in Swift.

public struct Derived {
  @returnsInnerPointer
  public var asBase: UnsafePointer<Base> { get }

  public static func downcast(from basePointer: UnsafePointer<Base>) -> UnsafePointer<Derived>?
}

public struct Base {
  public static func upcast(from basePointer: UnsafePointer<Derived>) -> UnsafePointer<Base>
}
```

```swift
// Usage example.

func useBasePtr(_ basePtr: UnsafePointer<Base>) { ... }
func useDerivedPtr(_ derivedPtr: UnsafePointer<Derived>) { ... }

func testDowncast() {
  var d = Derived()
  useBasePtr(d.asBase)

  // or:
  useBasePtr(Base.upcast(from: &d))
}

func testUpcast(_ basePtr: UnsafePointer<Base>) {
  if let derivedPtr: UnsafePointer<Derived> = Derived.downcast(from: basePtr) {
    useDerivedPtr(derivedPtr)
  }
}
```

The `asBase` property operates on a value, so it will need a way to pin the
original value in memory while the aliasing pointer is live. If we ignore that
API, the "type-upcast-from-value" and "type-downcast-from-value" syntax in other
APIs doesn't read well, because the order looks reversed.

Let's see what an API based on free functions would look like. We have to
separate the upcast and downcast APIs because they must return different types:
upcasts can't fail, while downcasts can.

```swift
// C++ support module in the Swift standard library.

public func cxxUpcast<Source, Destination>(
  _ source: UnsafePointer<Source>,
  to type: Destination.Type
) -> UnsafePointer<Destination>

public func cxxDowncast<Source, Destination>(
  _ source: UnsafePointer<Source>,
  to type: Destination.Type
) -> UnsafePointer<Destination>

public func cxxDynamicDowncast<Source, Destination>(
  _ source: UnsafePointer<Source>,
  to type: Destination.Type
) -> UnsafePointer<Destination>?
```

The Swift type checker would have special knowledge about these functions, and
only allow calling them when `Source` and `Destination` are fully concrete types
that belong to the same class hierarchy in C++.

These functions will know the concrete source and destination types, so they
will be able to perform any necessary pointer adjustments, therefore multiple
inheritance and virtual base classes wouldn't be a problem.

### Subclassing C++ classes in Swift

TODO

### Making C++ classes conform to Swift protocols

TODO

## Enums

In Swift 5, C enums that are not annotated (with either of `enum_extensibility`,
`NS_ENUM`, or `NS_OPTIONS`) are imported into Swift as structs, and enumerators
are imported as computed global variables. This might have been the right call
for importing Objective-C code, where enums not declared with `NS_ENUM` are
highly likely to have a "non-enum nature": they are either a bitfield, or just
a bag of constants. C++ has more ways, and more flexible ways to declare
constants, so using enums in C++ to declare constants is not very idiomatic.
Bitfield enums are used in C++ though, however, compared to overall enum usage,
bitfield enums are still rare. Therefore, current strategy of importing
non-annotated enums as Swift structs is the wrong default for C++.

There are multiple strategies we could take to import C++ enums into Swift.

**(1) Adopt the strategy used for C enums in C++**: unannotated C++ enums are
imported as Swift structs, C++ enums annotated as open/closed are imported as
Swift enums.

Pros:

* Conservatively correct. This strategy does not trust enums to have the "enum
  nature" unless they are annotated otherwise.

* Simpler design: identical rules across C, Objective-C, and C++.

Cons:

* Non-ergonomic. In idiomatic C++ codebases most enums have enum nature, so
  users would need to add lots of annotations.

**(2) Assume non-annotated C++ enums have "enum nature" and import them
as non-frozen Swift enums**; (optionally) implement an annotation for C++ enums
with "non-enum nature" and import such enums as Swift structs.

Pros:

* Correct default. In an idiomatic C++ codebase, the vast majority of enums do
  have enum nature.

* Maintaining source compatibility by not changing how C enums are imported.

Cons:

* Non-annotated enums of non-enum nature would be imported incorrectly from the
  API point of view (however, there is no undefined behavior hazard).

* No clear strategy to tell apart C and C++ enums. In an ideal world, `extern
  "C"` should allow to detect C declarations in C++, but not all C code is
  wrapped in `extern "C"`. For example, most Objective-C headers are not wrapped
  in `extern "C"` because most Objective-C constructs have a compatible ABI
  between Objective-C and Objective-C++.

**(3) Apply strategy #2 in C, Objective-C, and C++.** Doing so will change the
mapping strategy for non-annotated enums coming from Objective-C code, breaking
source stability to some extent.

Pros:

* Correct default in C++.

* Likely correct default in C.

* Simpler design: same rules in C and C++.

* Obvious how to implement, because there is no need to distinguish between
  different header kinds.

Cons:

* Likely not correct default in Objective-C. In idiomatic Objective-C code enums
  with "enum nature" are declared with `NS_ENUM`, and bitfields are declared
  with `NS_OPTIONS`, which leaves plain enums to cover the unusual cases.

* Breaking source compatibility by changing how C enums are imported. There are
  ways to mitigate this issue, for example, continue importing enumerators as
  computed global variables, marking them deprecated.

Strategy #3 is best for C++ code, but it is unclear if consequences for
Objective-C would be acceptable. We should gather data about usage of plain
enums in idiomatic C++ code and in Apple's SDKs and evaluate the absolute amount
of source breakage.

## Templates

From 10,000 feet, C++ templates are similar to Swift generics. However, there
are multiple semantic gaps between them.

C++ templates perform a syntactic substitution. Any type that supports the
syntax invoked in the template is a valid template argument. However, we don't
know exactly what syntax a type is required to support until we try to
substitute that type into a template. Generics in Swift are constraint-based and
require modular type checking.

C++ templates require instantiation at compile time. It is not possible to
compile a template without substituting concrete types in. It is not specified
whether Swift generics are instantiated or not, the compiler can make either
choice and the user can't tell the difference.

C++ templates support specialization. Swift generics don't allow specialization;
they provide a different mechanism (protocol requirements) to make one generic
function behave differently for different types.

C++ class templates support specialization, which allows defining completely
different APIs across specializations of the same class. All instantiations of a
generic type in Swift have the API described in the generic declaration (with
type parameters substituted), plus applicable conditional extensions.

C++ templates support non-type template parameters, template
parameters, and parameter packs (variadic generics), all of which are not
supported in Swift.

### Function templates

Since C++ uses an instantiation-based model for templates, the most obvious way
to import C++ function templates in Swift is to only import full specializations
as regular functions. However, it would be most ergonomic to import function
templates as Swift generic functions. Let's explore both options and see how far
we can go.

### Function templates: import as Swift generic functions

Let's take explicit specializations out of the picture for the purposes of
presenting the API in Swift. Since overload resolution in C++ ignores
specializations of function templates, we can ignore them, too, when importing a
function template into Swift.

```c++
// C++ header.

template<typename T>
void functionTemplate(T t) { ... }

// Any number of explicit specializations may follow.
template<>
void functionTemplate(int x) { ... }
```

```swift
// C++ header imported in Swift.

func functionTemplate<T>(_ t: T)

// No need to import explicit specializations as separate APIs.
```

Of course, when Swift code calls `functionTemplate` with an `Int32`, it should
call the correct explicit specialization, `functionTemplate<int>`, even though
it is not shown in the imported Swift API.

### Function templates: allow to specify template arguments

Calls to Swift generic functions always deduce generic arguments from the call.
C++ allows the caller to either deduce the arguments, or specify them
explicitly. Sometimes it is important to invoke C++ function templates with
specific template arguments, so it would make sense to expose this capability in
Swift.

We suggest to allow Swift code to use the angle bracket syntax to explicitly
specify function template arguments at the callsite. If template arguments are
not specified, we should run template argument deduction. (TODO: explain in more
detail how template argument deduction will work starting from Swift types.)

```swift
// Usage example in Swift.

functionTemplate<Int>(42)
```

How to specify C++ types that map ambiguously into Swift, for example, `int &`
or `int *`, both of which map to `UnsafePointer<Int>`? The C++ support module in
the Swift standard library could provide Swift typealiases that would map
unambiguously to C++.

```swift
// C++ support module in the Swift standard library.

typealias CxxPointer<T> = UnsafeMutablePointer<T>      // T*
typealias CxxConstPointer<T> = UnsafePointer<T>        // const T*

typealias CxxRef<T> = UnsafeMutablePointer<T>          // T&
typealias CxxConstRef<T> = UnsafePointer<T>            // const T&

typealias CxxRvalueRef<T> = UnsafeMutablePointer<T>    // T&&
typealias CxxConstRvalueRef<T> = UnsafePointer<T>      // const T&&
```

```swift
// Usage example in Swift.

var x = 42

// Calls `functionTemplate<int>`.
functionTemplate<Int>(x)

// Calls `functionTemplate<const int *>`.
functionTemplate<CxxConstPointer<Int>>(&x)

// Calls `functionTemplate<int &>`.
functionTemplate<CxxRef<Int>>(&x)
```

Although it is desirable to map rvalue references to Swift's `inout`, it is not
possible to do so when importing a C++ function template as a C++ generic
function; "inout"-ness of an argument can't change across instantiations of a
generic function in Swift.

### Function templates: calls to specific specializations

From an implementation point of view, it is easy to compile Swift code that
calls C++ function templates if template arguments are concrete types that are
obvious at the callsite (either deduced or specified explicitly). In other
words, it is easy to compile the call if Swift compiler can easily deduce which
specialization of the C++ function template to call. The imported API could
still look like a Swift generic function:

```swift
// C++ header imported in Swift.

func functionTemplate<T>(_ t: T)

// No need to import explicit specializations as separate APIs.
```

```swift
// Usage example in Swift, works.

func callFunctionTemplate() {
  functionTemplate(0) // OK: calls the `functionTemplate<int>` specialization.
}
```

If we stop here, `functionTemplate` would look like a generic function in Swift,
but it would not be callable from generic code. This option might be good enough
for the most basic mapping of function templates in Swift. But can we allow
calling C++ function templates from Swift generics?

### Function templates: calls with generic type parameters

The primary implementation difficulty in allowing generic Swift code to call C++
function templates is that the C++ compiler can only compile full
specializations, but Swift generics can run unspecialized.

```swift
// Usage example in Swift.

func myGenericFunction<T>(_ t: T) {
  functionTemplate(0) // OK: calls the `functionTemplate<int>` specialization.

  functionTemplate(t) // compilation error: can't call a C++ function template, because we don't know what `T` is, and therefore, can't select which specialization to call.
}
```

We could force Swift generics to be instantiated if they use a C++ template.
Fully generic entry points will be still emitted to fulfill ABI expectations,
but they would trap.

```swift
// C++ header imported in Swift.

@_must_specialize
func functionTemplate<T>(_ t: T)
```

```swift
// Usage example in Swift.

@_must_specialize
func genericFunction<T>(_ t: T) {
  functionTemplate<T>(t) // OK!
}

struct GenericStruct<T> {
  init GenericStruct(_ t: T) { self.t = t }
  var t: T

  @_must_specialize
  func callGenericFunction() {
    genericFunction(t) // OK!
  }
}

func example() {
  GenericStruct(42).callGenericFunction()
}
```

We introduce a `@_must_specialize` attribute for generic functions that must be
instantiated in order to be called. The importer marks all Swift generic
functions that are backed by a C++ template as `@_must_specialize`, and from
there the Swift compiler infers the attribute for all users.

This analysis relies on over-approximating the dynamic callgraph with the static
callgraph. The static callgraph is feasible to compute in most cases, since
Swift has very limited ways to abstract over an unspecialized generic function.
Specifically, Swift does not have generic closures. Swift does allow protocols
to have requirements for generic functions though.

### Function templates: importing as real generic functions

If we know the complete set of allowed type arguments to a C++ function
template, we could import it as an actual Swift generic function that performs
dynamic dispatch.

```c++
// C++ header.

template<typename T>
void functionTemplate(T t) { ... }

// Any number of explicit specializations may follow.
template<>
void functionTemplate(int x) { ... }
```

Let's say it is known that `functionTemplate` can only take `Int` and `UInt`.

```swift
// C++ header imported in Swift.

func _cxx_functionTemplate<T>(_ t: T) // Imported as explained before.

func functionTemplate<T>(_ t: T) {
  if T == Int.self {
    return _cxx_functionTemplate(t as! Int)
  }
  if T == UInt.self {
    return _cxx_functionTemplate(t as! UInt)
  }
  fatalError()
}
```

The user can write this code themselves (in an overlay, for example), or if we
can communicate the allowed list of types to the importer, it can synthesize the
function for us. Either way, the result is that we get a true generic Swift
function.

### Class templates

Class templates pose the same challenges as function templates regarding
separate compilation. In addition to that, we can't ignore explicit
specializations of class templates when importing the API to Swift.
We could ignore explicit specializations of function templates, because they
don't affect the API. Explicit specializations of class templates can
dramatically change the API of the type.

### Class templates: Importing full class template instantiations

A class template instantiation could be imported as a struct named
`__CxxTemplateInst` plus Itanium mangled type of the instantiation (see the
`type` production in the Itanium specification). Note that Itanium mangling is
used on all platforms, regardless of the ABI of the C++ toolchain, to ensure
that the mangled name is a valid Swift type name (this is not the case for MSVC
mangled names). A prefix with a double underscore (to ensure we have a reserved
C++ identifier) is added to limit the possibility for conflicts with names of
user-defined structs. The struct is notionally defined in the `__C` module,
similarly to regular C and C++ structs and classes. Consider the following C++
module:

```c++
// C++ header.

template<class T>
struct MagicWrapper {
  T t;
};
struct MagicNumber {};

typedef MagicWrapper<MagicNumber> WrappedMagicNumber;
```

`WrappedMagicNumber` will be imported as a typealias for a struct
`__CxxTemplateInst12MagicWrapperI11MagicNumberE`. Interface of the imported
module will look as follows:

```swift
// C++ header imported to Swift.

struct __CxxTemplateInst12MagicWrapperI11MagicNumberE {
    var t: MagicNumber
}
struct MagicNumber {}
typealias WrappedMagicNumber = __CxxTemplateInst12MagicWrapperI11MagicNumberE
```

### Class templates: importing specific specializations

Just like with calls to C++ function templates, it is easy to compile a use of a
C++ class templates if the usage in Swift code unambiguously specifies which
specialization should be used.

```c++
// C++ header.

template<typename T>
class ClassTemplate {};
```

```swift
// C++ header imported to Swift.

struct ClassTemplate<T> {}
```

```swift
// Usage example.

func useClassTemplate() {
  var x = ClassTemplate<Int32>() // OK, uses `ClassTemplate<int>`.
}
```

If the class template provides specializations with completely different APIs,
we don't have an issue, because we only need to import specific
specializations into Swift.

```c++
// C++ header.

template<typename T>
class ClassTemplate {
  void func1();
};

template<>
class ClassTemplate<int> {
  void func2();
};

template<typename T>
class ClassTemplate<std::vector<T>> {
  void func3();
};
```

```swift
// C++ header imported to Swift.

// A shell of a generic struct only used for name lookup.
struct ClassTemplate<T> {}
```

```swift
// Usage example.

func useClassTemplate() {
  var x1 = ClassTemplate<Int8>() // OK
  var x2 = ClassTemplate<Int32>() // OK
  var x3 = ClassTemplate<cxx_std.vector<Int32>> // OK
}
```

When the Swift compiler sees `ClassTemplate<Int8>`, it translates the type to
C++, that is, `ClassTemplate<char>`. Then Swift compiler asks the Clang importer
to import that specialization. Clang importer instantiates the primary template
with `T=char` and imports the resulting `ClassTemplate<char>`. Same for all
other rereferences to `ClassTemplate`. At the end, we get:

```c++
// C++ header imported to Swift, as needed for the program above.

// A shell of a generic struct only used for name lookup.
struct ClassTemplate<T> {}

struct ClassTemplate<Int8> {
  func func1()
}

struct ClassTemplate<Int32> {
  func func2()
}

struct ClassTemplate<cxx_std.vector<Int32>> {
  func func3()
}
```

Effectively, `ClassTemplate<Int8>`, `ClassTemplate<Int32>`, and
`ClassTemplate<cxx_std.vector<Int32>>` are completely unrelated types; they just
have angle brackets in their name. (By the way, the same is the case in C++.)

Advantages of this approach:

* Relatively straightforward to implement.

* Simple model, few or no corner cases.

Disadvantages of this approach:

* Users can only use complete specializations. In other words, users can't use a
  C++ template from Swift generic and pass a generic type parameter to the C++
  template.

### Class templates: using with generic type parameters

Many class templates don't define specializations that dramatically change the
API, or use features like non-type template parameters that don't exist in Swift
generics. It is desirable to import such templates as Swift generics directly.
With a lightweight static analysis, or with annotations in the C++ header, the
compiler would recognize such a type and import the API shared by all
instantiations into Swift.

Similarly to our treatment of function templates described above, we can
annotate the transitive closure of generic Swift code that uses C++ class
templates with `@_must_specialize`.

### Class templates: using in generic code through a synthesized protocol

Class templates that have a uniform API across all specializations could be made
to conform to a Swift protocol, which would facilitate passing them to generic
code.

```c++
// C++ header.

template<typename T>
class MyClassTemplate {
  void func1(T t);
};
```

```swift
// C++ header imported in Swift.

protocol MyClassTemplateProtocol {
  associatedtype T
  func func1(_ t: T)
}

struct MyClassTemplate<T> : MyClassTemplateProtocol {}
```

In this model, the Swift compiler can still import only specific specializations
of `MyClassTemplate`. The new part is that the Swift compiler will synthesize a
protocol, `MyClassTemplateProtocol`, that contains APIs shared by all
specializations. The Swift compiler will also make every imported specialization
of `MyClassTemplate` conform to `MyClassTemplateProtocol`.

This way, we solved the issue of specializations being unrelated types: now they
all conform to a common protocol, and therefore, generic code can operate
transparently on any specialization.

```swift
// Usage example.

// Use a C++ class template from a Swift generic function without naming a
// specific specialization.
func useGeneric<SomeSpecialization>(_ classTemplate: SomeSpecialization, _ t: SomeSpecialization.T)
  where SomeSpecialization: MyClassTemplateProtocol
{
  classTemplate.func1(t)
}

func useConcrete() {
  var classTemplate = MyClassTemplate<Int32>()
  classTemplate.func1(0)
  useGeneric(classTemplate, 0)
}
```

### Class templates: importing as real generic structs

If we know the complete set of allowed type arguments to a C++ struct
template, we could import it as an actual Swift generic struct. Every method of
that struct will perform dynamic dispatch based on type parameters. See
the section about function templates for more details.

### Mapping SFINAE

We can map SFINAE to generic constraints and to conditional extensions.

TODO

### Variadic templates

TODO

### Non-type template parameters

TODO

### Template template parameters

TODO

## Overloaded operators

TODO: Mapping C++'s operators to Equatable, Comparable, Hashable.


## <a name="operator-star-operator-arrow"></a> `operator*`, `operator->`

TODO

## <a name="operator-square-brackets"></a> `operator[]`

`operator[]` semantically maps well to Swift's `subscript`.

```c++
// C++ header.

class MyCxxContainer {
public:
  const double& operator[](int i) const;
  double& operator[](int i);
};
```

```swift
// C++ header imported in Swift.

struct MyCxxContainer {
  public subscript(_ i: Int) -> Double { get set }
}
```

The synthesized `subscript` uses the `_read` and `_modify` generalized accessors
to forward the memory address to the caller.

```swift
// Implementation details of the imported API.

struct MyCxxCollection {
  // const double& operator[](int i) const;
  private func _operatorBracketsConst(_ i: Int) -> UnsafePointer<Double>

  // double& operator[](int i);
  private func _operatorBrackets(_: Int) -> UnsafeMutablePointer<Double>

  // Swifty API.
  public subscript(_ i: Int) -> Double {
    _read {
      yield _operatorBracketsConst(i).pointee
    }
    _modify {
      yield &_operatorBrackets(i).pointee
    }
  }
}
```

## <a name="operator-parentheses"></a> `operator()`

Swift has an equivalent for C++'s `operator()`: `callAsFunction` (introduced in
[SE-0253: Callable values of user-defined nominal
types](https://github.com/apple/swift-evolution/blob/main/proposals/0253-callable.md)).

```c++
// C++ header.

class MultiplyIntDouble {
public:
  double operator()(int x, double y);
};
```

```c++
// C++ header imported in Swift.

struct MultiplyIntDouble {
  public func callAsFunction(_ x: Int, _ y: Double) -> Double { ... }
}
```

This mapping rule would handle the call operator of `std::function`,
`function_ref` and similar types.

## Literal operators

TODO

## Exceptions

### Background

C++ unfortunately has the opposite default to Swift where exception throwing is
concerned. Any C++ function that is not explicitly marked `noexcept` must be
assumed to be potentially throwing, even though many such functions don't throw
in practice.

If we imported all of these functions into Swift as `throws` functions, the code
calling them would be littered with `try!`s. Requiring all imported functions (and
everything they call transitively) to be marked `noexcept` also seems excessively
burdensome and is not idiomatic C++.

### Baseline functionality: Import functions as non-throwing, terminate on uncaught C++ exceptions

In the first iteration of C++ interop, we will import all C++ functions as
non-throwing Swift functions. If a C++ function called from Swift throws an
exception that is not caught within the C++ code, the program will terminate.

This approach is similar to that taken by the [Python interop
library](https://github.com/pvieito/PythonKit/blob/master/PythonKit/Python.swift),
which also terminates the program by default if a Python exception is raised and
not caught within the Python code.

If exceptions thrown in C++ need to be handled in Swift, this can be done by
writing a C++ wrapper that catches the exception and returns a corresponding
error object.

### Extended functionality: Optionally propagate exceptions to Swift

If we find that developers routinely need to handle C++ exceptions in Swift,
writing C++ wrappers as described above will obviously not be a satisfactory
solution. In this case, we will add an option to propagate C++ exceptions as
Swift exceptions; this will be backward compatible with the baseline approach
described above.

We again take inspiration from Python interop. There, appending `.throwing` to
the function name calls a variant of the function that propagates the Python
exception to Swift.

It isn't really practical to do something exactly analogous in C++ interop. We
could import each function twice and identify the throwing version by a name
suffix or a dummy parameter. However, this solution would bloat the interface of
imported classes, and it would not be universal: Name suffixes can't be used
with constructors or operators; a dummy parameter could be used with most
constructors, but still doesn't work for default constructors or operators.

Instead, we propose extending Swift with a `throws!` marker. A function marked
with `throws!` can potentially throw exceptions, but the function does not need
to be called with `try`. If the function _is_ called with `try`, exceptions are
handled as they would be for a normal throwing function. If the function is not
called with `try` and the function raises an exception, the program is
terminated. These semantics are close to C++ exception handling semantics.

All C++ functions that are not marked `noexcept` would be imported as `throws!`
functions; `noexcept` functions would be imported as non-throwing functions.

This brief sketch obviously leaves many questions unanswered on the detailed
semantics that a `throws!` feature would have, for example whether user-written
Swift code should be allowed to use `throws!` -- see also [this forum
discussion](https://forums.swift.org/t/handling-c-exceptions/34823). Before we
take any steps towards implementing C++ exception propagation, we will submit a
formal Swift Evolution proposal for the `throws!` feature.

The other question to answer is how we would map the C++ exception to a
corresponding Swift object implementing `Error`. In theory, C++ allows
objects of any copy-initializable type to be thrown. In practice, most
user-defined C++ exceptions derive from `std::exception`, so it would be natural
to propagate C++ exceptions as the Swift-imported equivalent of
`std::exception` and make that type implement `Error`. We could add a separate
fallback error type (e.g. `CxxUnknownException`) for the case where the
exception does not derive from `std::exception`.

As `std::exception` is a polymorphic type, the details of how `std::exception`
will be represented in Swift will need to wait until we have finalized how
polymorphism is handled (see also the section on [virtual member
functions](#virtual-member-functions)).

### Implementation

Many common C++ ABIs allow the default behavior (terminate the program if a
C++ exception is thrown) to be implemented at zero cost. In particular, it is not
necessary to wrap every C++ function in a synthesized try-catch block.

For example, the Itanium C++ ABI defines a so-called personality routine that is
called for each stack frame as the stack is being unwound. The idea is that
different languages can have different personality routines, so that different
languages can co-exist on the stack and can each define their own stack frame
cleanup logic.

The stack unwinding infrastructure finds the correct personality routine by
consulting a so-called unwind table, which maps program counter ranges to
personality routines.

We would define unwind table entries covering all Swift code that does not
attempt to handle C++ exceptions and have these entries map to a personality
routine that simply terminates the program.

If exception support is turned off in the C++ compiler by passing `-Xcc
-fno-exceptions` to `swiftc`, we assume that the C++ code never throws
exceptions and will not emit any unwind table entries for Swift code.

## Atomics

TODO

## Importing non-const pointer as extra return values

TODO

# Enhancing C++ API mapping into Swift with bridging

## Bridging data types with different memory layout

When we import a C++ `T` into Swift as a type `U`, in the general case we must
ensure that `T` and `U` have identical memory layout. For example, Swift's `Int8`
and C++'s `int8_t` have identical memory layout, and therefore, we can import
`int8_t` as `Int8` everywhere.

If `T` and `U` have even slightly different memory layouts, we must invoke a
bridging function at the interop boundary. Further sections in this document
provide many examples of such type pairs, but to give an example, consider
`std::vector<T>` in C++, which is semantically similar to `Array<T>` in Swift,
but has a completely different memory layout. If we want to map them to one
another, but must keep the memory layout of both types unchanged, we must
convert the `std::vector<T>` value into an `Array<T>` value when the program
execution crosses the language boundary.

For example:

```c++
// C++ header.

std::vector<int> IncrementVectorValues(std::vector<int> v);
```

```swift
// C++ header imported in Swift.

// Note: no C++ vectors!
func IncrementVectorValues(_ v: [CInt]) -> [CInt]
```

```swift
// Using the imported C++ API in Swift.

func callIncrementVectorValues() -> CInt {
  var xs: [CInt] = IncrementVectorValues([10, 20, 30])
  return xs[0] // = 11.
}
```

## Bridging: behind the scenes

Here's a simplified description of how Swift implements bridging. Behind the
scenes, the function `IncrementVectorValues` is imported as is, with C++ data
types:

```c++
// C header imported in Swift, behind the scenes:

func _cxx_IncrementVectorValues(std.vector<CInt> v) -> std.vector<CInt>
```

C++ bridging support code provides a function that converts a `std::vector` to a
Swift `Array` and vice versa:

```swift
// Swift standard library, C++ support module.

func StdVectorToArray<T>(_ vector: std.vector<T>) -> [T]
func ArrayToStdVector<T>(_ array: [T]) -> std.vector<T>
```

Each caller is transformed to call the bridging function:

```
// Using the imported C++ API in Swift: code written by the user.

func callIncrementVectorValues() -> CInt {
  var xs: [CInt] = IncrementVectorValues([10, 20, 30])
  return xs[0] // = 11.
}
```

```swift
// Using the imported C++ API in Swift: code rewritten by the type checker.

func callGetVector() -> CInt {
  var xs: [CInt] =
    StdVectorToArray(_cxx_IncrementVectorValues(ArrayToStdVector([10, 20, 30])))
  return xs[0] // = 11.
}
```

A naive implementation of `StdVectorToArray` and `ArrayToStdVector` would have
to copy the container's elements.  However, with enough cooperation between the
C++ standard library and the Swift standard library, Swift `Array` could take
ownership of `std::vector`'s storage and vice versa in O(1), avoiding making a
copy.  Such cooperation would likely require changing the ABI of at least one of
the types, so it would not be feasible to implement in all environments.

## Bridging does not work in every context

Bridging between types with different memory layouts does not work universally.
For example, just because a C++ type `T` can be bridged to a Swift type `U`, it
does not follow that we can bridge a `T*` to an `UnsafeMutablePointer<U>`.

```c++
// C++ header.

const std::vector<int> *GetPtrToVector();
```

```swift
// C++ header imported in Swift.

// We can't bridge types like in the example below, it is not implementable.
// The underlying C++ function returns a vector with unclear ownership semantics,
// but we need to return a pointer to a Swift Array.
// If the bridging code allocates the Swift Array on the heap, what would own it?
// If the bridging code does not allocate a new Array, where does it get the
// storage from?
func GetPtrToVector() -> UnsafePointer<[CInt]>

// OK.
func GetPtrToVector() -> UnsafePointer<std.vector<CInt>>
```

Therefore, we can perform non-trivial bridging only in a limited number of
contexts. In all remaining places C++ types must be imported according to the
general rules.

As a consequence, every non-trivial bridging solution needs a fallback that does
not require adjusting the memory layout.

## <a name="bridging-std-function"></a> Bridging `std::function`

`std::function` in C++ is similar to closures in Swift. The primary difference
is that `std::function` has an empty state, similarly to function pointers,
while Swift closures don't.

Due to allowing an empty state, `std::function` must be mapped to an optional
Swift closure, unless annotated as non-nullable.

To convert a non-empty `std::function` value to a Swift closure, we need to
define a thunk and allocate a closure context on the heap. The new closure
context will point to a copy of the `std::function` value. The thunk will use a
Swift calling convention, and it will forward the arguments to
`std::function::operator()()` using the C++ calling convention.

A thunk like this will not cost much in terms of code size. The primary cost of
the thunk will come from dynamic dispatch. We will have double dynamic dispatch:
first one at the callsite that calls the Swift closure and ends up calling the
thunk, and second one from the thunk to the C++ code wrapped in `std::function`.
Another issue is branch predictor pollution: there will be a single thunk
backing all closures with the same signature. Indirect branches from thunk will
be difficult to predict for the branch predictor.

There is additional cost contributed by reference counting: closures in Swift
are reference counted, while `std::function` isn't.

Finally, allocating a new closure context on the heap is a cost to be paid on
every conversion from a C++ `std::function` to a Swift closure.

## <a name="bridging-std-string"></a> Bridging `std::string`

Ergonomically, the best mapping of C++'s `std::string` is Swift's `String`. Both
types support nul bytes (the conversion has to take them into account and cannot
assume nul-terminated strings). However, there's a semantic gap: Swift strings
require text to be valid UTF-8.

We have a couple of options to address the UTF-8 issue:

* Trust C++ code to only store UTF-8 text in strings, and map them to Swift's
  `String` where possible. Perform a runtime check for UTF-8 validity during the
  conversion. Allow to annotate `std::string`s that store binary data, and map
  those as either Swift's `Array` or `std::string`.

* Assume `std::string`s store binary data, and map them to according to the
  regular interop rules to `cxx_std.string`. Allow users to annotate UTF-8
  strings as such, and map them to Swift's `String`.

The annotations could be inferred with a dynamic analysis tool that would track
which `std::string`s contain binary data.

Here's an example of API mapping if we decide to trust `std::string`s to store
UTF-8 data.

```c++
// C++ header.

class Employee {
public:
  std::string DebugDescription() const;
  [[swift::import_as_std_string]] std::string SerializedAsProtobuf() const;
};
```

```swift
// C++ header imported in Swift.

struct Employee {
  func DebugDescription() -> String
  func SerializedAsProtobuf() -> std.string
}
```

To avoid copying data unnecessarily, we need the C++ and Swift standard
libraries to cooperate, so that Swift's `String` can take ownership of
`std::string`'s heap allocation, and vice versa.

Character data in `Swift.String` is stored in a reference-counted object.
`Swift.String` can take ownership of `std::string` by transferring ownership of
`std::string` to a newly-allocated reference-counted object. Swift/Objective-C
bridging of `NSString` already works exactly this way.

On non-Objective-C platforms, `Swift.String` assumes that the character data is
tail-allocated in the reference-counted object; this assumption will have to be
replaced with a branch. Therefore, adding this sort of bridging on
non-Objective-C platforms will create a certain (small) performance penalty. It
is important to note that this performance penalty has been always affecting
Objective-C platforms and it is considered acceptable.

We could eliminate the branch on non-Objective-C platforms by changing
`Swift.String` there to always use a reference-counted object with an
`std::string` in it as the backing storage. The disadvantage of such memory
layout is that `Swift.String` would need to dereference two levels of
indirection to access to character data, instead of one like we have today.

`std::string` can't take ownership of `Swift.String`'s reference-counted object,
because `std::string` has no branches in its code that retrieves the pointer to
the character data and in its deallocation code. Adding branches there is
certainly possible, but will likely lead to regressions for many C++
applications, including ones that don't use Swift. Therefore, this approach
looks like a non-starter.

Therefore, the only viable approach for O(1) bidirectional bridging is having
`Swift.String` use `std::string` as its backing storage, and taking the penalty
of a double-indirection to access character data.

If one-way C++-to-Swift bridging is sufficient, it can be implemented with a
branch in the `Swift.String` code that retrieves a pointer to character data.

We can implement one-way O(1) Swift-to-C++ bridging by embedding a fake
`std::string` in the `Swift.String` buffer. Such a `std::string` instance would
not be full-fledged, and would be only good for reading from it; its destructor
can never be called.

## <a name="bridging-std-vector"></a> Bridging `std::vector`

Ergonomically, the best mapping of C++'s `std::vector` is Swift's `Array`.

Except for the case of `std::vector<bool>`, the constraints for `Swift.Array`
taking ownership of `std::vector`'s element buffer and vice versa are identical
to string bridging.

## <a name="bridging-std-set-std-map"></a> Bridging `std::set`, `std::map`

Swift standard library does not provide collections with semantics similar to
`std::set` and `std::map`, so they can't be meaningfully bridged to any Swift
vocabulary type. Therefore, they will be imported as `std.set` and `std.map`.

It would be useful to provide ergonomic ways to convert `std.set` and `std.map`
to `Swift.Set` and `Swift.Dictionary`, since `std::set` and `std::map` are
sometimes used in C++ APIs (especially older ones) when the element order
doesn't matter.

## <a name="bridging-std-unordered-set-std-unordered-map"></a> Bridging `std::unordered_set`, `std::unordered_map`

The most ergonomic mapping of `std::unordered_set` and `std::unordered_map` are
`Swift.Set` and `Swift.Dictionary`.

The constraints for these Swift types taking ownership of C++'s storage buffers
and vice versa are quite similar to string bridging. An interesting new point to
highlight is that the `Swift.Set` and `Swift.Dictionary` types would need to use
the hash function defined in C++ for C++ types. It should be possible to expose
the C++ hash function in Swift as a conformance to the `Hashable` protocol, or
as a conformance to a new C++-specific protocol for hashing.

## <a name="bridging-std-tuple-std-pair"></a> Bridging `std::tuple`, `std::pair`

Ergonomically, the best mapping of C++'s `std::tuple` and `std::pair` are
Swift's tuples.

Tuple and pair elements have to be copied to implement non-trivial bridging. It
is unreasonable to introduce a dual representation and require a branch to
access tuple elements either in C++ or Swift.

However, there are only so many different ways to lay out a `std::pair` in
memory. In fact, it is almost certainly a struct with exactly two data members,
`first` and `second`, in that order. When `std::pair<T, U>` and Swift's tuple
`(T, U)` happen to use the same layout, we could bridge them trivially, without
copying the data.

```c++
// C++ header.

std::pair<int, int> *GetPairPtr();
```

```swift
// C++ header imported in Swift.

UnsafeMutablePointer<(Int, Int)> GetPairPtr()
```

`std::tuple` is more complex and has more viable implementation options compared
to `std::pair`. For example, `std::tuple` is laid out in forward order by
libc++, and in backward order by libstdc++. Therefore, if libc++ is used,
there's a good chance that the memory layout of `std::tuple` matches the memory
layout of the corresponding Swift tuple, and we could bridge them trivially.

The disadvantage of the techniques described above is that they depend on
implementation details of the standard library, and as those change (or if the
user switches to a different standard library altogether), the API in Swift
might change as well.

## <a name="bridging-std-span"></a> Bridging `std::span`

The difficulty with `std::span<T>` is that it has a different API in Swift
depending on whether `T` is `const` or not.

```c++
// C++ standard library.

template<typename T>
class span {
public:
  constexpr T& front() const noexcept;
};
```

```c++
// C++ standard library imported in Swift.

// When T is non-const.
struct span<T> {
  public func front() -> UnsafeMutablePointer<T>
}

// When T is const.
struct span<T> {
  public func front() -> UnsafePointer<T>
}

// Need to choose one way to import, can't have both!
```

The easiest way to deal with this is to only import `std::span<T>` as full
specialization (the fallback way to import templates). However, that would not
be very ergonomic, and would prevent other templates that use `std::span` from
being imported as generics in Swift.

A more ergonomic way would be to import `std::span` as two generic structs in
Swift, selecting the appropriate one depending on constness.

```swift
// C++ standard library imported in Swift.

struct mutable_span<T> {
  public func front() -> UnsafeMutablePointer<T>
}

struct const_span<T> {
  public func front() -> UnsafePointer<T>
}
```

```c++
// C++ header.

std::span<int> GetMutableIntSpan();
std::span<const int> GetConstIntSpan();
```

```swift
// C++ header imported in Swift.

func GetMutableIntSpan() -> std.mutable_span<Int>
func GetConstIntSpan() -> std.const_span<Int>
```

## Standard C++ containers in general

It seems appropriate to provide an overlay that adds `Swift.Collection`
conformances to C++ container types.

## Custom C++ containers

The importer could try to recognize custom C++ containers and synthesize
`Swift.Collection` conformances, however, that seems fragile: custom containers
often don't implement the complete container API as required by the standard, or
deviate from it in subtle ways.

It seems best to add `Swift.Collection` conformances in overlays.

## <a name="bridging-absl-hash-set-map"></a> Bridging `absl::flat_hash_{set,map}`, `absl::node_hash_{set,map}`

Projects that use Abseil often use Abseil hash tables a lot more than standard
containers. However the same is also true about other libraries, like Boost or
Qt. Therefore, privileging a third-party library in C++/Swift interop seems
inappropriate. Abseil, Boost, and Qt should be treated just like user-written
code. Library vendors can provide annotations and Swift overlays to improve the
API in Swift.

# Enhancing C++ API mapping into Swift with annotations

## Annotation workflow

Annotations in C headers are employed by the Swift / C interop today (for
example, nullability annotations). However, these annotations must be added to
headers manually. How could tools infer annotations?

**Online inference at compile-time.** The Swift compiler could infer annotations
from information available in the headers. For example:

```c++
// example.h

class Example {
public:
  int *get_mutable_value() { return &value; }
  // The Swift compiler infers that the return type is `int * _Nonnull` because
  // the function never returns nullptr.
};
```

The problem with this approach is that it is making API decisions based on API
implementation details, without letting the API owner to intervene. It is going
to be fragile in the long run: no-op changes to implementation details of C++
APIs can tip annotation inference one way or the other, and unintentionally
change the Swift API. Imagine that the example above is refactored to:

```c++
// example.h

class Example {
public:
  int *get_mutable_value() { return get_mutable_value_impl(); }
private:
  int *get_mutable_value_impl(); // defined in example.cc
};

// The Swift compiler does not know whether `get_mutable_value_impl()`
// can return nullptr or not, therefore its return type is
// `int * _Null_unspecified`. Therefore, the return type of
// `get_mutable_value()` is now changed to `int * _Null_unspecified` as well.
```

API declarations should be the source of truth for API information; this also
aligns with expectations of C++ API owners.

**Offline inference.** The concerns about inspecting implementation details for
inference would be alleviated if inference tooling produced a source code patch
that would be reviewed by a human and adjusted if necessary before being
committed.

The ideal option is to add annotations directly to the header, to make the API
contract obvious to all readers and API owners. However, sometimes API owners
don't want to change the header, or can't be reached. In those cases,
annotations can be added to a sidecar file, removing the need to change the
header.

A sidecar annotation file allows to add arbitrary attributes to declarations
parsed from a header file. You can find examples of such files in the [apinotes
directory](../apinotes). APINotes files
are handled by the [APINotes library in
Clang](https://github.com/apple/llvm-project/tree/apple/main/clang/lib/APINotes).
Clang reads an APINotes file alongside the header file; Clang injects attributes
specified by APINotes into the AST parsed from the header.

## Tooling to infer nullability annotations

Nullability annotations in C++ headers are useful not only for Swift / C++
interop; they also document the intended API contract to C++ API users.
Nullability annotations can be validated by static and dynamic analysis tooling
in C++ (e.g., UBSan can be extended to detect assignments of `nullptr` to
`_Nonnull` pointers).

To infer nullability annotations we can use a combination of static and dynamic
analysis. Static analysis could infer nullability in more obvious cases -- along
with some confidence score, while dynamic analysis could provide insight into
arbitrarily complex APIs and data structures, with the usual caveat that the
inference results are only as good as the test cases.

There is a lot of existing research about detecting nullability issues in C and
C++ with static analysis, so we are not discussing the design of potential
static analysis tooling here. However, we are not aware of existing dynamic
analysis tooling that infers nullability.

Nullability inference based on dynamic analysis will use compile-time
instrumentation that is similar to UBSan for references, but instead of
producing a fatal error upon a nullptr store, we will record this fact and
continue. For each source-level pointer variable and class member declaration,
the compiler will allocate a global boolean flag that tracks nullability, and a
usage counter, which will be used to gauge confidence. The nullability flags are
initialized to "false" at program startup, usage counters are initialized to
zero. Each store into the pointer variables is instrumented, and when a nullptr
is stored, the corresponding flag is set to "true". Either way, the usage
counter is incremented. At program shutdown (or when signalled somehow), the
inferred nullability flags and usage counters are saved to disk.

## APIs that take a pointer and count

Many C and C++ APIs take a pointer and count. It would be nice if we could
import them as a buffer pointer in Swift, given appropriate annotations:

```c++
// C++ header.

void example(int *xs, int count);
// TODO: figure out what annotations might look like.
```

```swift
// C++ header imported in Swift.

func example(_ xs: UnsafeMutableBufferPointer<CInt>)
```

# Current state of art: importing Swift code into C

The Swift compiler generates a header that C code can use.

TODO: add details.

# Importing Swift APIs into C++

TODO

## Resilient types

The semantic gap here is related to resilient types -- their size is unknown at
compile time. `std::vector<T>` needs to know `sizeof(T)` at compile time. This
is a common problem in Swift-to-C++ bridging in general, and it would be solved
with boxing. Boxes for resilient Swift types would have a fixed size.

# Forum discussions

The topic of Swift/C++ interoperability has been discussed on Swift forums
before:

* [C++ Interop](https://forums.swift.org/t/c-interop/25567)
* [C++ / Objective-C++ Interop](https://forums.swift.org/t/c-objective-c-interop/9989)
* [C++ support in Swift](https://forums.swift.org/t/c-support-in-swift/13313)