Skip to content

Commit e5110d7

Browse files
authored
Merge pull request swiftlang#30146 from benrimmington/static-string-documentation
2 parents 45c0727 + f5fe8e3 commit e5110d7

File tree

2 files changed

+76
-36
lines changed

2 files changed

+76
-36
lines changed

stdlib/public/core/StaticString.swift

Lines changed: 73 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -19,11 +19,53 @@
1919

2020
/// A string type designed to represent text that is known at compile time.
2121
///
22-
/// Instances of the `StaticString` type are immutable. `StaticString` provides
23-
/// limited, pointer-based access to its contents, unlike Swift's more
24-
/// commonly used `String` type. A static string can store its value as a
25-
/// pointer to an ASCII code unit sequence, as a pointer to a UTF-8 code unit
26-
/// sequence, or as a single Unicode scalar value.
22+
/// Instances of the `StaticString` type are immutable.
23+
///
24+
/// `StaticString` provides only low-level access to its contents, unlike
25+
/// Swift's more commonly used `String` type. A static string can use
26+
/// either of the following as its storage:
27+
///
28+
/// * a pointer to a null-terminated sequence of UTF-8 code units:
29+
///
30+
/// let emoji: StaticString = "\u{1F600}"
31+
/// emoji.hasPointerRepresentation //-> true
32+
/// emoji.isASCII //-> false
33+
/// emoji.unicodeScalar //-> Fatal error!
34+
/// emoji.utf8CodeUnitCount //-> 4
35+
/// emoji.utf8Start[0] //-> 0xF0
36+
/// emoji.utf8Start[1] //-> 0x9F
37+
/// emoji.utf8Start[2] //-> 0x98
38+
/// emoji.utf8Start[3] //-> 0x80
39+
/// emoji.utf8Start[4] //-> 0x00
40+
///
41+
/// * a single Unicode scalar value, under very limited circumstances:
42+
///
43+
/// struct MyStaticScalar: ExpressibleByUnicodeScalarLiteral {
44+
/// typealias UnicodeScalarLiteralType = StaticString
45+
/// let value: StaticString
46+
/// init(unicodeScalarLiteral value: StaticString) {
47+
/// self.value = value
48+
/// }
49+
/// }
50+
///
51+
/// let emoji: StaticString = MyStaticScalar("\u{1F600}").value
52+
/// emoji.hasPointerRepresentation //-> false
53+
/// emoji.isASCII //-> false
54+
/// emoji.unicodeScalar.value //-> 0x1F600
55+
/// emoji.utf8CodeUnitCount //-> Fatal error!
56+
/// emoji.utf8Start //-> Fatal error!
57+
///
58+
/// You can use the `withUTF8Buffer(_:)` method to access a static string's
59+
/// contents, regardless of which representation the static string uses.
60+
///
61+
/// emoji.withUTF8Buffer { utf8 in
62+
/// utf8.count //-> 4
63+
/// utf8[0] //-> 0xF0
64+
/// utf8[1] //-> 0x9F
65+
/// utf8[2] //-> 0x98
66+
/// utf8[3] //-> 0x80
67+
/// utf8[4] //-> Fatal error!
68+
/// }
2769
@frozen
2870
public struct StaticString
2971
: _ExpressibleByBuiltinUnicodeScalarLiteral,
@@ -42,7 +84,7 @@ public struct StaticString
4284
internal var _startPtrOrData: Builtin.Word
4385

4486
/// If `_startPtrOrData` is a pointer, contains the length of the UTF-8 data
45-
/// in bytes.
87+
/// in bytes (excluding the null terminator).
4688
@usableFromInline
4789
internal var _utf8CodeUnitCount: Builtin.Word
4890

@@ -51,16 +93,15 @@ public struct StaticString
5193
/// - bit 0: set to 0 if `_startPtrOrData` is a pointer, or to 1 if it is a
5294
/// Unicode scalar.
5395
///
54-
/// - bit 1: set to 1 if `_startPtrOrData` is a pointer and string data is
55-
/// ASCII.
96+
/// - bit 1: set to 1 if `_startPtrOrData` either points to an ASCII code unit
97+
/// sequence, or stores an ASCII scalar value.
5698
@usableFromInline
5799
internal var _flags: Builtin.Int8
58100

59-
/// A pointer to the beginning of the string's UTF-8 encoded representation.
101+
/// A pointer to a null-terminated sequence of UTF-8 code units.
60102
///
61-
/// The static string must store a pointer to either ASCII or UTF-8 code
62-
/// units. Accessing this property when `hasPointerRepresentation` is
63-
/// `false` triggers a runtime error.
103+
/// - Important: Accessing this property when `hasPointerRepresentation` is
104+
/// `false` triggers a runtime error.
64105
@_transparent
65106
public var utf8Start: UnsafePointer<UInt8> {
66107
_precondition(
@@ -69,11 +110,10 @@ public struct StaticString
69110
return UnsafePointer(bitPattern: UInt(_startPtrOrData))!
70111
}
71112

72-
/// The stored Unicode scalar value.
113+
/// A single Unicode scalar value.
73114
///
74-
/// The static string must store a single Unicode scalar value. Accessing
75-
/// this property when `hasPointerRepresentation` is `true` triggers a
76-
/// runtime error.
115+
/// - Important: Accessing this property when `hasPointerRepresentation` is
116+
/// `true` triggers a runtime error.
77117
@_transparent
78118
public var unicodeScalar: Unicode.Scalar {
79119
_precondition(
@@ -82,10 +122,10 @@ public struct StaticString
82122
return Unicode.Scalar(UInt32(UInt(_startPtrOrData)))!
83123
}
84124

85-
/// The length in bytes of the static string's ASCII or UTF-8 representation.
125+
/// The number of UTF-8 code units (excluding the null terminator).
86126
///
87-
/// - Warning: If the static string stores a single Unicode scalar value, the
88-
/// value of `utf8CodeUnitCount` is unspecified.
127+
/// - Important: Accessing this property when `hasPointerRepresentation` is
128+
/// `false` triggers a runtime error.
89129
@_transparent
90130
public var utf8CodeUnitCount: Int {
91131
_precondition(
@@ -99,29 +139,25 @@ public struct StaticString
99139
return Builtin.inttoptr_Word(_startPtrOrData)
100140
}
101141

102-
/// A Boolean value indicating whether the static string stores a pointer to
103-
/// ASCII or UTF-8 code units.
142+
/// A Boolean value that indicates whether the static string stores a
143+
/// pointer to a null-terminated sequence of UTF-8 code units.
144+
///
145+
/// If `hasPointerRepresentation` is `false`, the static string stores a
146+
/// single Unicode scalar value.
104147
@_transparent
105148
public var hasPointerRepresentation: Bool {
106149
return (UInt8(_flags) & 0x1) == 0
107150
}
108151

109-
/// A Boolean value that is `true` if the static string stores a pointer to
110-
/// ASCII code units.
111-
///
112-
/// Use this property in conjunction with `hasPointerRepresentation` to
113-
/// determine whether a static string with pointer representation stores an
114-
/// ASCII or UTF-8 code unit sequence.
115-
///
116-
/// - Warning: If the static string stores a single Unicode scalar value, the
117-
/// value of `isASCII` is unspecified.
152+
/// A Boolean value that indicates whether the static string represents only
153+
/// ASCII code units (or an ASCII scalar value).
118154
@_transparent
119155
public var isASCII: Bool {
120156
return (UInt8(_flags) & 0x2) != 0
121157
}
122158

123159
/// Invokes the given closure with a buffer containing the static string's
124-
/// UTF-8 code unit sequence.
160+
/// UTF-8 code unit sequence (excluding the null terminator).
125161
///
126162
/// This method works regardless of whether the static string stores a
127163
/// pointer or a single Unicode scalar value.
@@ -132,12 +168,13 @@ public struct StaticString
132168
/// - Parameter body: A closure that takes a buffer pointer to the static
133169
/// string's UTF-8 code unit sequence as its sole argument. If the closure
134170
/// has a return value, that value is also used as the return value of the
135-
/// `withUTF8Buffer(invoke:)` method. The pointer argument is valid only
136-
/// for the duration of the method's execution.
171+
/// `withUTF8Buffer(_:)` method. The pointer argument is valid only for the
172+
/// duration of the method's execution.
137173
/// - Returns: The return value, if any, of the `body` closure.
138174
@_transparent
139175
public func withUTF8Buffer<R>(
140-
_ body: (UnsafeBufferPointer<UInt8>) -> R) -> R {
176+
_ body: (UnsafeBufferPointer<UInt8>) -> R
177+
) -> R {
141178
if hasPointerRepresentation {
142179
return body(UnsafeBufferPointer(
143180
start: utf8Start, count: utf8CodeUnitCount))
@@ -256,7 +293,7 @@ public struct StaticString
256293
self = value
257294
}
258295

259-
/// A string representation of the static string.
296+
/// A textual representation of the static string.
260297
public var description: String {
261298
return withUTF8Buffer { String._uncheckedFromUTF8($0) }
262299
}

test/stdlib/StaticString.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ var StaticStringTestSuite = TestSuite("StaticString")
88

99
StaticStringTestSuite.test("PointerRepresentation/ASCII/Empty") {
1010
let str = StaticString()
11+
expectEqual(0x00, str.utf8Start[0])
1112
expectEqual(0, str.utf8CodeUnitCount)
1213
expectTrue(str.hasPointerRepresentation)
1314
expectTrue(str.isASCII)
@@ -26,6 +27,7 @@ StaticStringTestSuite.test("PointerRepresentation/ASCII") {
2627
expectEqual(0x61, str.utf8Start[0])
2728
expectEqual(0x62, str.utf8Start[1])
2829
expectEqual(0x63, str.utf8Start[2])
30+
expectEqual(0x00, str.utf8Start[3])
2931
expectEqual(3, str.utf8CodeUnitCount)
3032
expectTrue(str.hasPointerRepresentation)
3133
expectTrue(str.isASCII)
@@ -50,6 +52,7 @@ StaticStringTestSuite.test("PointerRepresentation/NonASCII") {
5052
expectEqual(0xb1, str.utf8Start[3])
5153
expectEqual(0xd0, str.utf8Start[4])
5254
expectEqual(0xb2, str.utf8Start[5])
55+
expectEqual(0x00, str.utf8Start[6])
5356
expectEqual(6, str.utf8CodeUnitCount)
5457
expectTrue(str.hasPointerRepresentation)
5558
expectFalse(str.isASCII)

0 commit comments

Comments
 (0)