Skip to content

Commit f1adf99

Browse files
authored
Merge pull request #72012 from apple/egorzhdan/std-chrono
[cxx-interop] Add conversions between `std::chrono::duration` and `Swift.Duration`
2 parents e7e5be1 + 53fb653 commit f1adf99

File tree

4 files changed

+205
-0
lines changed

4 files changed

+205
-0
lines changed

stdlib/public/Cxx/cxxshim/libcxxstdlibshim.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <chrono>
12
#include <functional>
23
#include <string>
34

@@ -9,3 +10,19 @@ typedef std::hash<std::u16string> __swift_interopHashOfU16String;
910

1011
/// Used for std::u32string conformance to Swift.Hashable
1112
typedef std::hash<std::u32string> __swift_interopHashOfU32String;
13+
14+
inline std::chrono::seconds __swift_interopMakeChronoSeconds(int64_t seconds) {
15+
return std::chrono::seconds(seconds);
16+
}
17+
18+
inline std::chrono::milliseconds __swift_interopMakeChronoMilliseconds(int64_t milliseconds) {
19+
return std::chrono::milliseconds(milliseconds);
20+
}
21+
22+
inline std::chrono::microseconds __swift_interopMakeChronoMicroseconds(int64_t microseconds) {
23+
return std::chrono::microseconds(microseconds);
24+
}
25+
26+
inline std::chrono::nanoseconds __swift_interopMakeChronoNanoseconds(int64_t nanoseconds) {
27+
return std::chrono::nanoseconds(nanoseconds);
28+
}

stdlib/public/Cxx/std/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ endif()
3535
# as it's not ABI stable.
3636
add_swift_target_library(swiftCxxStdlib STATIC NO_LINK_NAME IS_STDLIB IS_SWIFT_ONLY IS_FRAGILE
3737
std.swift
38+
Chrono.swift
3839
String.swift
3940

4041
SWIFT_MODULE_DEPENDS Cxx

stdlib/public/Cxx/std/Chrono.swift

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import CxxStdlibShim
14+
15+
extension std.chrono.seconds {
16+
@available(SwiftStdlib 5.7, *)
17+
public init(_ duration: Duration) {
18+
let (seconds, _) = duration.components
19+
self = __swift_interopMakeChronoSeconds(seconds)
20+
}
21+
}
22+
23+
extension std.chrono.milliseconds {
24+
@available(SwiftStdlib 5.7, *)
25+
public init(_ duration: Duration) {
26+
let (seconds, attoseconds) = duration.components
27+
self = __swift_interopMakeChronoMilliseconds(
28+
seconds * 1_000 +
29+
attoseconds / 1_000_000_000_000_000)
30+
}
31+
}
32+
33+
extension std.chrono.microseconds {
34+
@available(SwiftStdlib 5.7, *)
35+
public init(_ duration: Duration) {
36+
let (seconds, attoseconds) = duration.components
37+
self = __swift_interopMakeChronoMicroseconds(
38+
seconds * 1_000_000 +
39+
attoseconds / 1_000_000_000_000)
40+
}
41+
}
42+
43+
extension std.chrono.nanoseconds {
44+
@available(SwiftStdlib 5.7, *)
45+
public init(_ duration: Duration) {
46+
let (seconds, attoseconds) = duration.components
47+
self = __swift_interopMakeChronoNanoseconds(
48+
seconds * 1_000_000_000 +
49+
attoseconds / 1_000_000_000)
50+
}
51+
}
52+
53+
@available(SwiftStdlib 5.7, *)
54+
extension Duration {
55+
public init(_ seconds: std.chrono.seconds) {
56+
self = Duration.seconds(seconds.count())
57+
}
58+
59+
public init(_ milliseconds: std.chrono.milliseconds) {
60+
self = Duration.milliseconds(milliseconds.count())
61+
}
62+
63+
public init(_ microseconds: std.chrono.microseconds) {
64+
self = Duration.microseconds(microseconds.count())
65+
}
66+
67+
public init(_ nanoseconds: std.chrono.nanoseconds) {
68+
self = Duration.nanoseconds(nanoseconds.count())
69+
}
70+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// RUN: %target-run-simple-swift(-I %S/Inputs -cxx-interoperability-mode=swift-6)
2+
// RUN: %target-run-simple-swift(-I %S/Inputs -cxx-interoperability-mode=upcoming-swift)
3+
4+
// REQUIRES: executable_test
5+
6+
import StdlibUnittest
7+
import CxxStdlib
8+
9+
var StdUniquePtrTestSuite = TestSuite("StdChrono")
10+
11+
if #available(SwiftStdlib 5.7, *) {
12+
StdUniquePtrTestSuite.test("std::chrono::seconds <=> Duration") {
13+
let d1 = Duration.seconds(123)
14+
let c1 = std.chrono.seconds(d1)
15+
expectEqual(123, c1.count())
16+
expectEqual(d1, Duration(c1))
17+
18+
let d2 = Duration.milliseconds(1)
19+
let c2 = std.chrono.seconds(d2)
20+
expectEqual(0, c2.count())
21+
22+
let d3 = Duration.milliseconds(5000)
23+
let c3 = std.chrono.seconds(d3)
24+
expectEqual(5, c3.count())
25+
expectEqual(d3, Duration(c3))
26+
27+
let d4 = Duration.seconds(-123)
28+
let c4 = std.chrono.seconds(d4)
29+
expectEqual(-123, c4.count())
30+
expectEqual(d4, Duration(c4))
31+
32+
let d5 = Duration.milliseconds(-5000)
33+
let c5 = std.chrono.seconds(d5)
34+
expectEqual(-5, c5.count())
35+
expectEqual(d5, Duration(c5))
36+
}
37+
38+
StdUniquePtrTestSuite.test("std::chrono::milliseconds <=> Duration") {
39+
let d1 = Duration.milliseconds(321)
40+
let c1 = std.chrono.milliseconds(d1)
41+
expectEqual(321, c1.count())
42+
expectEqual(d1, Duration(c1))
43+
44+
let d2 = Duration.microseconds(1)
45+
let c2 = std.chrono.milliseconds(d2)
46+
expectEqual(0, c2.count())
47+
48+
let d3 = Duration.microseconds(2000)
49+
let c3 = std.chrono.milliseconds(d3)
50+
expectEqual(2, c3.count())
51+
expectEqual(d3, Duration(c3))
52+
53+
let d4 = Duration.seconds(25)
54+
let c4 = std.chrono.milliseconds(d4)
55+
expectEqual(25000, c4.count())
56+
expectEqual(d4, Duration(c4))
57+
58+
let d5 = Duration.microseconds(-5000)
59+
let c5 = std.chrono.milliseconds(d5)
60+
expectEqual(-5, c5.count())
61+
expectEqual(d5, Duration(c5))
62+
}
63+
64+
StdUniquePtrTestSuite.test("std::chrono::microseconds from Duration") {
65+
let d1 = Duration.microseconds(456)
66+
let c1 = std.chrono.microseconds(d1)
67+
expectEqual(456, c1.count())
68+
expectEqual(d1, Duration(c1))
69+
70+
let d2 = Duration.nanoseconds(1)
71+
let c2 = std.chrono.milliseconds(d2)
72+
expectEqual(0, c2.count())
73+
74+
let d3 = Duration.seconds(5)
75+
let c3 = std.chrono.microseconds(d3)
76+
expectEqual(5000000, c3.count())
77+
expectEqual(d3, Duration(c3))
78+
79+
let d4 = Duration.milliseconds(5)
80+
let c4 = std.chrono.microseconds(d4)
81+
expectEqual(5000, c4.count())
82+
expectEqual(d4, Duration(c4))
83+
84+
let d5 = Duration.microseconds(-654)
85+
let c5 = std.chrono.microseconds(d5)
86+
expectEqual(-654, c5.count())
87+
expectEqual(d5, Duration(c5))
88+
}
89+
90+
StdUniquePtrTestSuite.test("std::chrono::nanoseconds from Duration") {
91+
let d1 = Duration.nanoseconds(789)
92+
let c1 = std.chrono.nanoseconds(d1)
93+
expectEqual(789, c1.count())
94+
expectEqual(d1, Duration(c1))
95+
96+
let d2 = Duration.nanoseconds(1) / 1000
97+
let c2 = std.chrono.nanoseconds(d2)
98+
expectEqual(0, c2.count())
99+
100+
let d3 = Duration.seconds(5)
101+
let c3 = std.chrono.nanoseconds(d3)
102+
expectEqual(5000000000, c3.count())
103+
expectEqual(d3, Duration(c3))
104+
105+
let d4 = Duration.milliseconds(2)
106+
let c4 = std.chrono.nanoseconds(d4)
107+
expectEqual(2000000, c4.count())
108+
expectEqual(d4, Duration(c4))
109+
110+
let d5 = Duration.nanoseconds(-654)
111+
let c5 = std.chrono.nanoseconds(d5)
112+
expectEqual(-654, c5.count())
113+
expectEqual(d5, Duration(c5))
114+
}
115+
}
116+
117+
runAllTests()

0 commit comments

Comments
 (0)