Skip to content

Instantly share code, notes, and snippets.

@DevAndArtist
Last active May 25, 2021 11:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DevAndArtist/a8bcd5390a363bb0aa08f1851d569c9e to your computer and use it in GitHub Desktop.
Save DevAndArtist/a8bcd5390a363bb0aa08f1851d569c9e to your computer and use it in GitHub Desktop.
public protocol MapKey {
associatedtype Value
static var defaultValue: Value { get }
}
public struct Map<Base> {
typealias _Key = ObjectIdentifier
var _values: [_Key: Any]
public init() {
_values = [:]
}
public subscript <Key>(key: Key.Type) -> Key.Value where Key: MapKey {
get {
_values[_Key(key)] as? Key.Value ?? Key.defaultValue
}
set {
_values[_Key(key)] = newValue
}
}
}
// example
protocol P {
var store: Map<Self> { get set }
}
extension Map where Base: P {
enum K: MapKey {
static var defaultValue: Int { 42 }
}
var num: Int {
get {
self[K.self]
}
set {
self[K.self] = newValue
}
}
}
struct FirstP: P {
var store = Map<Self>()
}
struct SecondP: P {
var store = Map<Self>()
}
// every concrete type which conforms to `P`
// would have `store.num`
// but we can have distinct branches
extension Map where Base == FirstP {
enum OtherK: MapKey {
static var defaultValue: String { "swift" }
}
var string: String {
get {
self[OtherK.self]
}
set {
self[OtherK.self] = newValue
}
}
}
let f = FirstP()
let s = SecondP()
f.store.num == s.store.num
f.store.string
// no `string` property in `s.store`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment