-
Notifications
You must be signed in to change notification settings - Fork 23
Description
Consider the existence of types like the following:
type ComplexObject = ref object
id: UniqueId
# many other fields that are expensive to setupInstances of such types are often added to sets (or they can be used as keys in tables). To achieve this, you just need to implement hashing and equality comparison in the following way:
proc hash*(o: ComplexObject): int = hash(o.id)
proc `==`(lhs, rhs: ComplexObject): bool = lhs.id == rhs.idBut this leaves one problem. When you search the set or the table for an existing key, you must allocate and construct a full instance of ComplexObject which may be expensive or non-trivial. It would be nice if one is able to search the set directly for an object with a specific id without allocating any memory.
A possible solution:
1. Add a new mixed-in proc called keyOf that would be implemented as identity by default, but would allow the user to provide the following override:
template keyOf*(o: ComplexObject): UniqueId = o.idThe implementation in tables.nim and sets.nim will then use this call prior to hashing and checking the equality of the elements in the hash table.
2. Change the signature of procs such as get, containts, etc, to the following:
proc contains[T](s: HashSet[T], key: T or type(keyOf(default(T)))): bool =.. or just provide alternative names for the lookups using the alternative key type.