-
-
Save rintaro/c240100472967973de3f42e16080dfa1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protocol CatProtocol { | |
associatedtype Food | |
func difficult<T>(to: T.Type, food: Food, me: Self) -> Self | |
} | |
class Cat : CatProtocol { | |
typealias Food = String | |
required init() {} | |
func difficult<T>(to: T.Type, food: String, me: Cat) -> Self { | |
fatalError() | |
} | |
} | |
class AnyCatBase<Food> { | |
func difficult<T>(to: T.Type, food: Food, me: AnyCatBase<Food>) -> Self { fatalError() } | |
} | |
final class AnyCatBox<Base: CatProtocol> : AnyCatBase<Base.Food> { | |
typealias Food = Base.Food | |
var _base: Base | |
init(_ base: Base) { _base = base } | |
override func difficult<T>(to: T.Type, food: Base.Food, me: AnyCatBase<Base.Food>) -> Self { | |
return type(of: self).init(_base.difficult(to: to, food: food, me: _base)) | |
} | |
} | |
struct AnyCat<F> : CatProtocol { | |
typealias Food = F | |
var _box: AnyCatBase<Food> | |
init<Base: CatProtocol>(_ base: Base) where F == Base.Food { | |
_box = AnyCatBox(base) | |
} | |
private init(_ box: AnyCatBase<Food>) { | |
_box = box | |
} | |
func difficult<T>(to: T.Type, food: Food, me: AnyCat<Food>) -> AnyCat<Food> { | |
return AnyCat(_box.difficult(to: to, food: food, me: me._box)) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment