Skip to content

Commit 672330e

Browse files
author
Dave Abrahams
authored
Merge pull request #9664 from apple/character-unicodescalars
[stdlib] Add Character.unicodeScalars
2 parents e7d2596 + ef5d37c commit 672330e

File tree

5 files changed

+107
-4
lines changed

5 files changed

+107
-4
lines changed

stdlib/public/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ set(SWIFTLIB_ESSENTIAL
3535
Builtin.swift
3636
BuiltinMath.swift.gyb
3737
Character.swift
38+
CharacterUnicodeScalars.swift
3839
CocoaArray.swift
3940
Codable.swift
4041
Collection.swift

stdlib/public/core/Character.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,4 +449,3 @@ extension Character : Comparable {
449449
}
450450
}
451451
}
452-
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//===--- CharacterUnicodeScalars.swift ------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 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+
extension Character {
13+
public struct UnicodeScalarView {
14+
internal let _base: String.UnicodeScalarView
15+
}
16+
17+
public var unicodeScalars : UnicodeScalarView {
18+
return UnicodeScalarView(_base: String(self).unicodeScalars)
19+
}
20+
}
21+
22+
extension Character.UnicodeScalarView {
23+
public struct Iterator {
24+
internal var _base: String.UnicodeScalarView.Iterator
25+
}
26+
}
27+
28+
extension Character.UnicodeScalarView.Iterator : IteratorProtocol {
29+
public mutating func next() -> UnicodeScalar? {
30+
return _base.next()
31+
}
32+
}
33+
34+
extension Character.UnicodeScalarView : Sequence {
35+
public func makeIterator() -> Iterator {
36+
return Iterator(_base: _base.makeIterator())
37+
}
38+
}
39+
40+
extension Character.UnicodeScalarView {
41+
public struct Index {
42+
internal let _base: String.UnicodeScalarView.Index
43+
}
44+
}
45+
46+
extension Character.UnicodeScalarView.Index : Equatable {
47+
public static func == (
48+
lhs: Character.UnicodeScalarView.Index,
49+
rhs: Character.UnicodeScalarView.Index
50+
) -> Bool {
51+
return lhs._base == rhs._base
52+
}
53+
}
54+
55+
extension Character.UnicodeScalarView.Index : Comparable {
56+
public static func < (
57+
lhs: Character.UnicodeScalarView.Index,
58+
rhs: Character.UnicodeScalarView.Index
59+
) -> Bool {
60+
return lhs._base < rhs._base
61+
}
62+
}
63+
64+
extension Character.UnicodeScalarView : Collection {
65+
public var startIndex: Index {
66+
return Index(_base: _base.startIndex)
67+
}
68+
public var endIndex: Index {
69+
return Index(_base: _base.endIndex)
70+
}
71+
public func index(after i: Index) -> Index {
72+
return Index(_base: _base.index(after: i._base))
73+
}
74+
public subscript(_ i: Index) -> UnicodeScalar {
75+
return _base[i._base]
76+
}
77+
}
78+
79+
extension Character.UnicodeScalarView : BidirectionalCollection {
80+
public func index(before i: Index) -> Index {
81+
return Index(_base: _base.index(before: i._base))
82+
}
83+
}

stdlib/public/core/GroupInfo.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"ASCII.swift",
88
"CString.swift",
99
"Character.swift",
10+
"CharacterUnicodeScalars.swift",
1011
"StaticString.swift",
1112
"String.swift",
1213
"StringBridge.swift",

test/stdlib/Character.swift

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,22 @@ func isSmallRepresentation(_ s: String) -> Bool {
219219
}
220220
}
221221

222+
func checkUnicodeScalars(_ s: String) {
223+
let c = s.first!
224+
expectEqualSequence(s.unicodeScalars, c.unicodeScalars)
225+
226+
expectEqualSequence(
227+
s.unicodeScalars, c.unicodeScalars.indices.map { c.unicodeScalars[$0] })
228+
229+
expectEqualSequence(
230+
s.unicodeScalars.reversed(), c.unicodeScalars.reversed())
231+
232+
expectEqualSequence(
233+
s.unicodeScalars.reversed(), c.unicodeScalars.indices.reversed().map {
234+
c.unicodeScalars[$0]
235+
})
236+
}
237+
222238
func checkRepresentation(_ s: String) {
223239
let expectSmall = s.utf8.count <= 8
224240
let isSmall = isSmallRepresentation(s)
@@ -231,13 +247,15 @@ func checkRepresentation(_ s: String) {
231247

232248
CharacterTests.test("RoundTripping") {
233249
// Single Unicode Scalar Value tests
234-
for s in baseScalars {
235-
checkRepresentation(String(s))
236-
checkRoundTripThroughCharacter(String(s))
250+
for s in baseScalars.lazy.map(String.init) {
251+
checkUnicodeScalars(s)
252+
checkRepresentation(s)
253+
checkRoundTripThroughCharacter(s)
237254
}
238255

239256
// Edge case tests
240257
for s in testCharacters {
258+
checkUnicodeScalars(s)
241259
checkRepresentation(s)
242260
checkRoundTripThroughCharacter(s)
243261
}
@@ -249,6 +267,7 @@ CharacterTests.test("RoundTripping/Random") {
249267
// Character's small representation variant has 63 bits. Making
250268
// the maximum length 9 scalars tests both sides of the limit.
251269
var s = randomGraphemeCluster(1, 9)
270+
checkUnicodeScalars(s)
252271
checkRepresentation(s)
253272
checkRoundTripThroughCharacter(s)
254273
}

0 commit comments

Comments
 (0)