Skip to content

Commit 57a5e58

Browse files
committed
Proposal #6: more API diffs
1 parent 0a24dca commit 57a5e58

File tree

1 file changed

+253
-13
lines changed

1 file changed

+253
-13
lines changed

proposals/0006-apply-api-guidelines-to-the-standard-library.md

Lines changed: 253 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,20 @@ On high level, the changes can be summarized as follows.
7171

7272
* `enumerate()` => `enumerated()`.
7373

74+
* `partition()` API was simplified. It composes better with collection slicing
75+
now.
76+
7477
* `SequenceType.minElement()` => `.min()`, `.maxElement()` => `.max()`.
7578

7679
* Some initializers for sequence and collection adapters were removed. We
7780
suggest calling the corresponding algorithm function or method instead.
7881

7982
* Some functions were changed into properties and vice versa.
8083

84+
* `Unmanaged` was renamed to `UnsafeReference` and redesigned.
85+
86+
* `precondition` was renamed to `require`.
87+
8188
**More changes will be summarized here as they are implemented.**
8289

8390
## API diffs
@@ -89,7 +96,9 @@ added to this section as they are being implemented on the
8996
For repetitive changes that affect many types, only one representative instance
9097
is shown in the diff. For example, `generate()` was renamed to `iterator()`.
9198
We only show the diff for the protocol requirement, and all other renames of
92-
this method are implied.
99+
this method are implied. If a type was renamed, we show only the diff for the
100+
type declaration, all other effects on the API where the name is used are
101+
implied.
93102

94103
* Strip `Type` suffix from protocol names.
95104

@@ -166,6 +175,8 @@ this method are implied.
166175
-public protocol UnicodeCodecType { ... }
167176
+public protocol UnicodeCodec { ... }
168177

178+
-public protocol CVarArgType { ... }
179+
+public protocol CVarArg { ... }
169180
```
170181

171182
* The concept of `generator` is renamed to `iterator` across all APIs.
@@ -175,8 +186,8 @@ this method are implied.
175186
+public protocol IteratorProtocol { ... }
176187

177188
public protocol Collection : ... {
178-
- typealias Generator : GeneratorType = IndexingGenerator<Self>
179-
+ typealias Iterator : IteratorProtocol = IndexingIterator<Self>
189+
- associatedtype Generator : GeneratorType = IndexingGenerator<Self>
190+
+ associatedtype Iterator : IteratorProtocol = IndexingIterator<Self>
180191

181192
- func generate() -> Generator
182193
+ func iterator() -> Iterator
@@ -221,7 +232,8 @@ this method are implied.
221232
-public struct StrideThroughGenerator<Element : Strideable> : ... { ... }
222233
+public struct StrideThroughIterator<Element : Strideable> : ... { ... }
223234

224-
235+
-public struct UnsafeBufferPointerGenerator<Element> : ... { ... }
236+
+public struct UnsafeBufferPointerIterator<Element> : ... { ... }
225237
```
226238

227239
* The type `Bit`, which was only used as the index for `CollectionOfOne`, was
@@ -256,24 +268,22 @@ this method are implied.
256268
recommend using the `nil` literal instead.
257269

258270
```diff
259-
public struct AutoreleasingUnsafeMutablePointer<
271+
// The same changes applied to `UnsafePointer`, `UnsafeMutablePointer` and
272+
// `AutoreleasingUnsafeMutablePointer`.
273+
public struct UnsafePointer<
260274
- Memory
261275
+ Pointee
262276
> ... : {
263-
264277
- public var memory: Memory { get set }
265278
+ public var pointee: Pointee { get set }
266279

267280
// Use `nil` instead.
268281
- public init()
269282
}
270283

271-
-public struct COpaquePointer : ... {
272-
+public struct OpaquePointer : ... {
273-
284+
public struct OpaquePointer : ... {
274285
// Use `nil` instead.
275286
- public init()
276-
277287
}
278288
```
279289

@@ -376,6 +386,25 @@ this method are implied.
376386
+public struct EnumeratedIterator<Base : IteratorProtocol> : ... { ... }
377387
```
378388

389+
* `partition()` API was simplified. It composes better with collection slicing
390+
now.
391+
392+
```diff
393+
extension MutableCollection where Index : RandomAccessIndex {
394+
public mutating func partition(
395+
- range: Range<Index>,
396+
isOrderedBefore: (Iterator.Element, Iterator.Element) -> Bool
397+
) -> Index
398+
}
399+
400+
extension MutableCollection
401+
where Index : RandomAccessIndex, Iterator.Element : Comparable {
402+
403+
- public mutating func partition(range: Range<Index>) -> Index
404+
+ public mutating func partition() -> Index
405+
}
406+
```
407+
379408
* `SequenceType.minElement()` => `.min()`, `.maxElement()` => `.max()`.
380409

381410
```diff
@@ -415,6 +444,14 @@ this method are implied.
415444
- public init(_ base: Base, transform: (Base.Generator.Element) -> Element)
416445
}
417446

447+
public struct LazyFilterIterator<Base : IteratorProtocol> : ... {
448+
// Call `.lazy.filter` on the sequence instead.
449+
- public init(
450+
- _ base: Base,
451+
- whereElementsSatisfy predicate: (Base.Element) -> Bool
452+
- )
453+
}
454+
418455
public struct RangeIterator<Element : ForwardIndex> : ... {
419456
// Use the 'generate()' method on the collection instead.
420457
- public init(_ bounds: Range<Element>)
@@ -442,6 +479,16 @@ this method are implied.
442479
// Use the slicing syntax.
443480
- public init(base: Base, bounds: Range<Index>)
444481
}
482+
483+
public struct EnumeratedIterator<Base : IteratorProtocol> : ... {
484+
// Use the 'enumerated()' method.
485+
public init(_ base: Base)
486+
}
487+
488+
public struct EnumeratedSequence<Base : IteratorProtocol> : ... {
489+
// Use the 'enumerated()' method.
490+
public init(_ base: Base)
491+
}
445492
```
446493

447494
* Some functions were changed into properties and vice versa.
@@ -487,6 +534,170 @@ this method are implied.
487534

488535
```
489536

537+
* `Unmanaged` was renamed to `UnsafeReference` and redesigned.
538+
539+
```diff
540+
-public struct Unmanaged<Instance : AnyObject> {
541+
// New API: `UnsafeReference(bitPattern:)`.
542+
- public static func fromOpaque(value: COpaquePointer) -> Unmanaged
543+
544+
// New API: `OpaquePointer(bitPattern:)`.
545+
- public func toOpaque() -> COpaquePointer
546+
547+
// New API: `UnsafeReference(retaining:)`.
548+
- public static func passRetained(value: Instance) -> Unmanaged
549+
550+
// New API: `UnsafeReference(withoutRetaining:)`.
551+
- public static func passUnretained(value: Instance) -> Unmanaged
552+
553+
// New API: `UnsafeReference.object`.
554+
- public func takeUnretainedValue() -> Instance
555+
556+
// New API: `UnsafeReference.release()`.
557+
- public func takeRetainedValue() -> Instance
558+
559+
// New API: none.
560+
- public func retain() -> Unmanaged
561+
- public func release()
562+
- public func autorelease() -> Unmanaged
563+
-}
564+
565+
+/// Holds an instance of `Object`, carrying ownership semantics that
566+
+/// are not known to the type system and not represented in memory.
567+
+///
568+
+/// `UnsafeReference<T>` appears as a return type or "out" parameter
569+
+/// in [Core
570+
+/// Foundation](https://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CoreFoundation_Collection/)
571+
+/// APIs that have not been
572+
+/// [annotated](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html#//apple_ref/doc/uid/TP40014216-CH6-ID79)
573+
+/// with information that allows clients to receive a safe `T`
574+
+/// directly.
575+
+///
576+
+/// An `UnsafeReference` instance `u` can be in one of three
577+
+/// "ownership states":
578+
+///
579+
+/// 1. **Unretained**, where `u.object` yields a valid `T` and will
580+
+/// do so through any number of accesses to the `.object`
581+
+/// properties of `UnsafeReference` instances. The behavior of
582+
+/// `u.release()` is undefined, and any other operations may cause
583+
+/// `u` to transition to the *released* state.
584+
+///
585+
+/// 2. **Retained**, where `u.release()` yields a valid `T` and will
586+
+/// do so exactly once. Calling `.release()` transitions `u` and
587+
+/// all its copies to the *released* state.
588+
+///
589+
+/// 3. **Released**, where the behavior of both `u.object` and
590+
+/// `u.release()` is undefined. A released `UnsafeReference`
591+
+/// can't be used for anything.
592+
+///
593+
+/// The ownership state of an `UnsafeReference` is not
594+
+/// programmatically detectable, so careful documentation is
595+
+/// essential. When an `UnsafeReference` is returned in the
596+
+/// *retained* state, it is usual to document that "the caller is
597+
+/// responsible for releasing the object"" or that the API "follows
598+
+/// the [create
599+
+/// rule](https://developer.apple.com/library/ios/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/writerid/cfCreateRule)."
600+
+/// Other `UnsafeReferences` are assumed to be in the *unretained*
601+
+/// state. No API should pass or return a *released*
602+
+/// `UnsafeReference`
603+
+///
604+
+/// The safest way to deal with an instance of `UnsafeReference<T>` is
605+
+/// to immediately extract a safe `T` from it exactly once (via
606+
+/// `.object` or `.release()` according to its state), and let it go
607+
+/// out of scope.
608+
+///
609+
+/// In the common case where the `UnsafeReference` is a return value,
610+
+/// it's best to do the extraction as part of the call, e.g.:
611+
+/// ~~~~
612+
+/// let names: CFArray = CFHostGetNames(host).object
613+
+/// let url: CFURL = CFHTTPMessageCopyRequestURL(message).release()
614+
+/// ~~~
615+
+///
616+
+/// When the `UnsafeReference` is an "out" parameter, you can limit
617+
+/// its scope by creating and unwrapping it in a closure:
618+
+/// ~~~~
619+
+/// var properties: CFPropertyList = try {
620+
+/// var properties: UnsafeReference<CFPropertyList>?
621+
+/// let error = MIDIObjectGetProperties(midiClient, &properties, true)
622+
+/// if error != noErr {
623+
+/// throw NSError(domain: "midi", code: Int(error), userInfo: nil)
624+
+/// }
625+
+/// return properties!.object
626+
+/// }()
627+
+/// ~~~~
628+
+public struct UnsafeReference<Object : AnyObject> {
629+
+
630+
+ /// Relinquishes ownership of the `Object` and returns it as a safe
631+
+ /// reference.
632+
+ ///
633+
+ /// - Requires: `self` is in the *retained* state.
634+
+ ///
635+
+ /// - Postcondition: `self` and all its copies are in the *released* state.
636+
+ ///
637+
+ /// - Warning: Calling `.release()` on an *unretained* or *released*
638+
+ /// `UnsafeReference` is a severe programming error yielding
639+
+ /// undefined behavior.
640+
+ ///
641+
+ /// - Warning: After this method is invoked once, invoking any
642+
+ /// methods on the same instance, or a copy thereof, is a severe
643+
+ /// programming error yielding undefined behavior.
644+
+ public func release() -> Object
645+
+
646+
+ /// A safe reference to the `Object` instance.
647+
+ ///
648+
+ /// - Warning: if `self`` is in the *retained* state, you must
649+
+ /// eventually call `.release()`, or the resulting object will be
650+
+ /// leaked. It's better to just capture the result of invoking
651+
+ /// `.release()` in that case.
652+
+ public var object: Object
653+
654+
+ /// Creates an unsafe holder of `safeObject` in the *unretained*
655+
+ /// state; the held object can be accessed via the `.object` property.
656+
+ public init(withoutRetaining safeObject: Object)
657+
+
658+
+ /// Creates an unsafe holder of `safeObject` in the *retained*
659+
+ /// state; the held object can be accessed via the `release()`
660+
+ /// method.
661+
+ public init(retaining safeObject: Object)
662+
+
663+
+ /// Creates an unsafe holder of an object having the given
664+
+ /// `bitPattern`.
665+
+ public init(bitPattern: OpaquePointer)
666+
+
667+
+ internal unowned(unsafe) var _storage: Object
668+
+}
669+
+
670+
+extension OpaquePointer {
671+
+ /// Unsafely convert an unmanaged class reference to an opaque
672+
+ /// C pointer.
673+
+ ///
674+
+ /// This operation does not change reference counts.
675+
+ ///
676+
+ /// let str0: CFString = "boxcar"
677+
+ /// let bits = OpaquePointer(bitPattern: UnsafeReference(withoutRetaining: str0))
678+
+ /// let str1 = UnsafeReference<CFString>(bitPattern: bits).object
679+
+ public init<T>(bitPattern bits: UnsafeReference<T>)
680+
+}
681+
```
682+
683+
* `precondition` was renamed to `require`.
684+
685+
```diff
686+
-public func precondition(
687+
+public func require(
688+
@autoclosure condition: () -> Bool,
689+
@autoclosure _ message: () -> String = String(),
690+
file: StaticString = __FILE__, line: UInt = __LINE__
691+
)
692+
693+
@noreturn
694+
-public func preconditionFailure(
695+
+public func requirementFailure(
696+
@autoclosure message: () -> String = String(),
697+
file: StaticString = __FILE__, line: UInt = __LINE__
698+
)
699+
```
700+
490701
* Miscellaneous changes.
491702

492703
```diff
@@ -587,10 +798,10 @@ this method are implied.
587798
+ mutating func removeAll(keepingCapacity keepingCapacity: Bool = false)
588799

589800
- public init(count: Int, repeatedValue c: Character)
590-
+ public init(repeating repeatedValue: Character, length: Int)
801+
+ public init(repeating repeatedValue: Character, count: Int)
591802

592803
- public init(count: Int, repeatedValue c: UnicodeScalar)
593-
+ public init(repeating repeatedValue: UnicodeScalar, length: Int)
804+
+ public init(repeating repeatedValue: UnicodeScalar, count: Int)
594805
}
595806

596807
public enum UnicodeDecodingResult {
@@ -633,7 +844,7 @@ this method are implied.
633844

634845
public struct StaticString : ... {
635846
- public var byteSize: Int { get }
636-
+ public var lengthInBytes: Int { get } // FIXME: byteCount? utf8Count? don't touch?
847+
+ public var utf8CodeUnitCount: Int { get }
637848

638849
// Use the 'String(_:)' initializer.
639850
- public var stringValue: String { get }
@@ -660,6 +871,35 @@ this method are implied.
660871
+ stoppingOnError: Bool
661872
) -> Bool
662873

874+
extension UnsafeMutablePointer {
875+
- public static func alloc(num: Int) -> UnsafeMutablePointer<Pointee>
876+
+ public init(allocatingCapacity count: Int)
877+
878+
- public func dealloc(num: Int)
879+
+ public func deallocateCapacity(count: Int)
880+
881+
- public func initialize(newvalue: Memory)
882+
+ public func initializePointee(newValue: Pointee, count: Int = 1)
883+
884+
- public func move() -> Memory
885+
+ public func take() -> Memory
886+
887+
- public func destroy()
888+
- public func destroy(count: Int)
889+
+ public func deinitializePointee(count count: Int = 1)
890+
}
891+
892+
-public struct COpaquePointer : ... { ... }
893+
+public struct OpaquePointer : ... { ... }
894+
895+
-public struct RawByte {}
896+
897+
-final public class VaListBuilder {}
898+
899+
-public func withVaList<R>(
900+
- builder: VaListBuilder,
901+
- @noescape _ f: CVaListPointer -> R)
902+
--> R
663903
```
664904

665905
## Impact on existing code

0 commit comments

Comments
 (0)