// 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 { return startIndex.. Self { return self } } // CHECK: 4 print(["a", "b", "c", "d"].clone().myCount) extension Sequence { public func myEnumerated() -> EnumeratedSequence { 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( _ 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: S) -> Zip2Sequence { 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( _ 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")