Created
March 30, 2015 22:13
-
-
Save JadenGeller/d368dde68e1df0d5a675 to your computer and use it in GitHub Desktop.
Swift Set of "Any" Type
This file contains 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
// Examples | |
var set = AnySet() | |
set.insert(3) | |
set.insert("hello") | |
set.insert("hi") | |
set.insert(2.3) | |
set.contains(6) // -> false | |
set.contains(3) // -> true | |
set.remove(3) | |
set.insert(4) | |
set.contains(3) // -> false | |
set.contains(4) // -> true | |
set.isSupersetOf(["hello", "hi"]) // -> true | |
set.isSubsetOf(["hello", "hi"]) // -> false | |
// Implementation | |
struct AnyHashable : Hashable, Printable { | |
private let backing: Any | |
private let hashValueClosure: () -> Int | |
private let equalityClosure: (Any) -> Bool | |
init<T: Hashable>(_ value: T) { | |
self.backing = value | |
self.hashValueClosure = { value.hashValue } | |
self.equalityClosure = { | |
if let other = $0 as? T { return value == other } | |
else { return false } | |
} | |
} | |
var hashValue: Int { | |
get { | |
return hashValueClosure() | |
} | |
} | |
private func isEqual(other: AnyHashable) -> Bool { | |
return equalityClosure(other.backing) | |
} | |
var description: String { | |
get { | |
return "\(backing)" | |
} | |
} | |
} | |
func ==(lhs: AnyHashable, rhs: AnyHashable) -> Bool { | |
return lhs.isEqual(rhs) | |
} | |
struct AnySet : Hashable, Printable, DebugPrintable, SequenceType { | |
private var backing: Set<AnyHashable> | |
init() { | |
backing = Set<AnyHashable>() | |
} | |
init<T: Hashable>(_ set: Set<T>) { | |
self.init(LazySequence(set).array) | |
} | |
init<T: Hashable>(_ array: [T]) { | |
self.backing = Set(map(array, { member in AnyHashable(member) })) | |
} | |
private init(_ backing: Set<AnyHashable>) { | |
self.backing = backing | |
} | |
mutating func insert<T: Hashable>(member: T) { | |
backing.insert(AnyHashable(member)) | |
} | |
func contains<T: Hashable>(member: T) -> Bool { | |
return backing.contains(AnyHashable(member)) | |
} | |
mutating func remove<T: Hashable>(member: T) { | |
backing.remove(AnyHashable(member)) | |
} | |
mutating func removeAll(keepCapacity: Bool = false) { | |
backing.removeAll(keepCapacity: keepCapacity) | |
} | |
func isSubsetOf<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> Bool { | |
return backing.isSubsetOf(map(sequence, { member in AnyHashable(member) })) | |
} | |
func isStrictSubsetOf<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> Bool { | |
return backing.isStrictSubsetOf(map(sequence, { member in AnyHashable(member) })) | |
} | |
func isSupersetOf<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> Bool { | |
return backing.isSupersetOf(map(sequence, { member in AnyHashable(member) })) | |
} | |
func isStrictSupersetOf<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> Bool { | |
return backing.isStrictSupersetOf(map(sequence, { member in AnyHashable(member) })) | |
} | |
func isDisjointWith<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> Bool { | |
return backing.isDisjointWith(map(sequence, { member in AnyHashable(member) })) | |
} | |
func union<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> AnySet { | |
return AnySet(backing.union(map(sequence, { member in AnyHashable(member) }))) | |
} | |
mutating func unionInPlace<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) { | |
backing.unionInPlace(map(sequence, { member in AnyHashable(member) })) | |
} | |
func subtract<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> AnySet { | |
return AnySet(backing.subtract(map(sequence, { member in AnyHashable(member) }))) | |
} | |
mutating func subtractInPlace<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) { | |
backing.subtractInPlace(map(sequence, { member in AnyHashable(member) })) | |
} | |
func intersect<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> AnySet { | |
return AnySet(backing.intersect(map(sequence, { member in AnyHashable(member) }))) | |
} | |
mutating func intersectInPlace<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) { | |
backing.intersectInPlace(map(sequence, { member in AnyHashable(member) })) | |
} | |
func exclusiveOr<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) -> AnySet { | |
return AnySet(backing.exclusiveOr(map(sequence, { member in AnyHashable(member) }))) | |
} | |
mutating func exclusiveOrInPlace<S : SequenceType where S.Generator.Element : Hashable>(sequence: S) { | |
backing.exclusiveOrInPlace(map(sequence, { member in AnyHashable(member) })) | |
} | |
var count: Int { | |
get { | |
return backing.count | |
} | |
} | |
var isEmpty: Bool { | |
get { | |
return backing.isEmpty | |
} | |
} | |
var hashValue: Int { | |
get { | |
return backing.hashValue | |
} | |
} | |
var description: String { | |
get { | |
return backing.description | |
} | |
} | |
var debugDescription: String { | |
get { | |
return backing.debugDescription | |
} | |
} | |
private func isEqual(other: AnySet) -> Bool { | |
return backing == other.backing | |
} | |
func generate() -> SetGenerator<AnyHashable> { | |
return backing.generate() | |
} | |
} | |
func ==(lhs: AnySet, rhs: AnySet) -> Bool { | |
return lhs.isEqual(rhs) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment