mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
268 lines
4.8 KiB
Swift
268 lines
4.8 KiB
Swift
// RUN: %target-run-simple-swift | %FileCheck %s
|
|
// REQUIRES: executable_test
|
|
|
|
// Extend a protocol with a property.
|
|
extension Sequence {
|
|
var myCount: Int {
|
|
var result = 0
|
|
for _ in self {
|
|
result += 1
|
|
}
|
|
return result
|
|
}
|
|
}
|
|
|
|
// CHECK: 4
|
|
print(["a", "b", "c", "d"].myCount)
|
|
|
|
// Extend a protocol with a function.
|
|
extension Collection {
|
|
var myIndices: Range<Index> {
|
|
return startIndex..<endIndex
|
|
}
|
|
|
|
func clone() -> Self {
|
|
return self
|
|
}
|
|
}
|
|
|
|
// CHECK: 4
|
|
print(["a", "b", "c", "d"].clone().myCount)
|
|
|
|
extension Sequence {
|
|
public func myEnumerated() -> EnumeratedSequence<Self> {
|
|
return self.enumerated()
|
|
}
|
|
}
|
|
|
|
// CHECK: (0, a)
|
|
// CHECK-NEXT: (1, b)
|
|
// CHECK-NEXT: (2, c)
|
|
for (index, element) in ["a", "b", "c"].myEnumerated() {
|
|
print("(\(index), \(element))")
|
|
}
|
|
|
|
extension Sequence {
|
|
public func myReduce<T>(
|
|
_ initial: T, combine: (T, Self.Iterator.Element) -> T
|
|
) -> T {
|
|
var result = initial
|
|
for value in self {
|
|
result = combine(result, value)
|
|
}
|
|
return result
|
|
}
|
|
}
|
|
|
|
// CHECK: 15
|
|
print([1, 2, 3, 4, 5].myReduce(0, combine: { $0 + $1 }))
|
|
|
|
|
|
extension Sequence {
|
|
public func myZip<S : Sequence>(_ s: S) -> Zip2Sequence<Self, S> {
|
|
return Zip2Sequence(_sequence1: self, _sequence2: s)
|
|
}
|
|
}
|
|
|
|
// CHECK: (1, a)
|
|
// CHECK-NEXT: (2, b)
|
|
// CHECK-NEXT: (3, c)
|
|
for (a, b) in [1, 2, 3].myZip(["a", "b", "c"]) {
|
|
print("(\(a), \(b))")
|
|
}
|
|
|
|
// Mutating algorithms.
|
|
extension MutableCollection
|
|
where Self: RandomAccessCollection, Self.Iterator.Element : Comparable {
|
|
|
|
public mutating func myPartition() -> Index {
|
|
let first = self.first
|
|
return self.partition(by: { $0 >= first! })
|
|
}
|
|
}
|
|
|
|
extension RangeReplaceableCollection {
|
|
public func myJoin<S : Sequence>(
|
|
_ elements: S
|
|
) -> Self where S.Iterator.Element == Self {
|
|
var result = Self()
|
|
var iter = elements.makeIterator()
|
|
if let first = iter.next() {
|
|
result.append(contentsOf: first)
|
|
while let next = iter.next() {
|
|
result.append(contentsOf: self)
|
|
result.append(contentsOf: next)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
}
|
|
|
|
// CHECK: a,b,c
|
|
print(
|
|
String(
|
|
",".characters.myJoin(["a".characters, "b".characters, "c".characters])
|
|
)
|
|
)
|
|
|
|
// Constrained extensions for specific types.
|
|
extension Collection where Self.Iterator.Element == String {
|
|
var myCommaSeparatedList: String {
|
|
if startIndex == endIndex { return "" }
|
|
|
|
var result = ""
|
|
var first = true
|
|
for x in self {
|
|
if first { first = false }
|
|
else { result += ", " }
|
|
result += x
|
|
}
|
|
return result
|
|
}
|
|
}
|
|
|
|
// CHECK: x, y, z
|
|
print(["x", "y", "z"].myCommaSeparatedList)
|
|
|
|
// CHECK: {{[tuv], [tuv], [tuv]}}
|
|
print((["t", "u", "v"] as Set).myCommaSeparatedList)
|
|
|
|
// Existentials
|
|
protocol ExistP1 {
|
|
func existP1()
|
|
}
|
|
|
|
extension ExistP1 {
|
|
func runExistP1() {
|
|
print("runExistP1")
|
|
self.existP1()
|
|
}
|
|
}
|
|
|
|
struct ExistP1_Struct : ExistP1 {
|
|
func existP1() {
|
|
print(" - ExistP1_Struct")
|
|
}
|
|
}
|
|
|
|
class ExistP1_Class : ExistP1 {
|
|
func existP1() {
|
|
print(" - ExistP1_Class")
|
|
}
|
|
}
|
|
|
|
// CHECK: runExistP1
|
|
// CHECK-NEXT: - ExistP1_Struct
|
|
var existP1: ExistP1 = ExistP1_Struct()
|
|
existP1.runExistP1()
|
|
|
|
// CHECK: runExistP1
|
|
// CHECK-NEXT: - ExistP1_Class
|
|
existP1 = ExistP1_Class()
|
|
existP1.runExistP1()
|
|
|
|
protocol P {
|
|
mutating func setValue(_ b: Bool)
|
|
func getValue() -> Bool
|
|
}
|
|
|
|
extension P {
|
|
var extValue: Bool {
|
|
get { return getValue() }
|
|
set(newValue) { setValue(newValue) }
|
|
}
|
|
}
|
|
|
|
extension Bool : P {
|
|
mutating func setValue(_ b: Bool) { self = b }
|
|
func getValue() -> Bool { return self }
|
|
}
|
|
|
|
class C : P {
|
|
var theValue: Bool = false
|
|
func setValue(_ b: Bool) { theValue = b }
|
|
func getValue() -> Bool { return theValue }
|
|
}
|
|
|
|
func toggle(_ value: inout Bool) {
|
|
value = !value
|
|
}
|
|
|
|
var p: P = true
|
|
// CHECK: Bool
|
|
print("Bool")
|
|
|
|
// CHECK: true
|
|
p.extValue = true
|
|
print(p.extValue)
|
|
|
|
// CHECK: false
|
|
p.extValue = false
|
|
print(p.extValue)
|
|
|
|
// CHECK: true
|
|
toggle(&p.extValue)
|
|
print(p.extValue)
|
|
|
|
// CHECK: C
|
|
print("C")
|
|
p = C()
|
|
|
|
// CHECK: true
|
|
p.extValue = true
|
|
print(p.extValue)
|
|
|
|
// CHECK: false
|
|
p.extValue = false
|
|
print(p.extValue)
|
|
|
|
// CHECK: true
|
|
toggle(&p.extValue)
|
|
print(p.extValue)
|
|
|
|
// Logical lvalues of existential type.
|
|
struct HasP {
|
|
var _p: P
|
|
var p: P {
|
|
get { return _p }
|
|
set { _p = newValue }
|
|
}
|
|
}
|
|
|
|
var hasP = HasP(_p: false)
|
|
|
|
// CHECK: true
|
|
hasP.p.extValue = true
|
|
print(hasP.p.extValue)
|
|
|
|
// CHECK: false
|
|
toggle(&hasP.p.extValue)
|
|
print(hasP.p.extValue)
|
|
|
|
// rdar://problem/20739719
|
|
class Super: Init {
|
|
required init(x: Int) { print("\(x) \(type(of: self))") }
|
|
}
|
|
|
|
class Sub: Super {}
|
|
|
|
protocol Init { init(x: Int) }
|
|
extension Init { init() { self.init(x: 17) } }
|
|
|
|
// CHECK: 17 Super
|
|
_ = Super()
|
|
|
|
// CHECK: 17 Sub
|
|
_ = Sub()
|
|
|
|
// CHECK: 17 Super
|
|
var sup: Super.Type = Super.self
|
|
_ = sup.init()
|
|
|
|
// CHECK: 17 Sub
|
|
sup = Sub.self
|
|
_ = sup.init()
|
|
|
|
// CHECK: DONE
|
|
print("DONE")
|