Skip to content

Instantly share code, notes, and snippets.

@omochi
Last active October 6, 2017 09:55
Show Gist options
  • Save omochi/a6dde71489ab118727eeed8c717d2c90 to your computer and use it in GitHub Desktop.
Save omochi/a6dde71489ab118727eeed8c717d2c90 to your computer and use it in GitHub Desktop.
protocol CastProtocol {
func cast<T>(to: T.Type) -> T?
}
protocol CatProtocol : CastProtocol {
associatedtype Food
var name: String { get set }
func nya() -> String
mutating func sleep()
func findFood() -> Food?
func eat(food: Food) -> Void
func clone() -> Self
func cast<T>(to: T.Type) -> T?
func difficult1<T>(to: T.Type, food: Food)
}
class Cat : CatProtocol {
required init() {}
var name: String = "tama"
func nya() -> String { return "nyaaaa" }
func sleep() { print("zzz...") }
func findFood() -> Int? {
return 3
}
func eat(food: Int) { print("yummy \(food)") }
func clone() -> Self {
return type(of: self).init()
}
func cast<T>(to: T.Type) -> T? {
return self as? T
}
func difficult1<T>(to: T.Type, food: Food) {
}
}
struct AnyCat1<FD> : CatProtocol {
init<X>(_ x: X) where X: CatProtocol, X.Food == FD {
var x = x
_getName = { x.name }
_setName = { x.name = $0 }
_nya = { x.nya() }
_sleep = { x.sleep() }
_findFood = { x.findFood() }
_eat = { x.eat(food: $0) }
_clone = { AnyCat1(x.clone()) }
_cast = x
}
var name: String {
get { return _getName() }
set { _setName(newValue) }
}
func nya() -> String {
return _nya()
}
func sleep() { _sleep() }
func findFood() -> FD? {
return _findFood()
}
func eat(food: FD) -> Void {
_eat(food)
}
func clone() -> AnyCat1 {
return _clone()
}
func cast<T>(to: T.Type) -> T? {
return _cast.cast(to: to)
}
var _getName: () -> String
var _setName: (String) -> Void
var _nya: () -> String
var _sleep: () -> Void
var _findFood: () -> FD?
var _eat: (FD) -> Void
var _clone: () -> AnyCat1
var _cast: CastProtocol
}
@omochi
Copy link
Author

omochi commented Oct 6, 2017

@omochi
Copy link
Author

omochi commented Oct 6, 2017

stdlibのAnySequenceもrintaroさんパターン

class _AnySequenceBox<Element> {
  internal func _makeIterator() -> AnyIterator<Element> { _abstract() }
}

final class _SequenceBox<S> : _AnySequenceBox<S.Iterator.Element> {
  internal override func _makeIterator() -> AnyIterator<Element> {
    return AnyIterator(_base.makeIterator())
  }
}

struct AnySequence<Element> : Sequence {
  public init<S : Sequence>(_ base: S)
    where S.Element == Element 
  {
    self._box = _SequenceBox(_base: base)
  }
  internal let _box: _AnySequenceBox<Element>
}

https://github.com/apple/swift/blob/master/stdlib/public/core/ExistentialCollection.swift.gyb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment