hashes: support object default hash (#17175)
This commit is contained in:
parent
4a31088ac2
commit
63f1c38f4e
3 changed files with 62 additions and 18 deletions
|
|
@ -173,14 +173,16 @@ provided by the operating system.
|
||||||
dumping (on select signals) and notifying the parent process about the cause
|
dumping (on select signals) and notifying the parent process about the cause
|
||||||
of termination.
|
of termination.
|
||||||
|
|
||||||
- Added `strip` and `setSlice` to `std/strbasics`.
|
- `hashes.hash` now supports `object`, but can be overloaded.
|
||||||
|
|
||||||
|
- Added `strip` and `setSlice` to `std/strbasics`.
|
||||||
|
|
||||||
- Added to `wrapnils` an option-like API via `??.`, `isSome`, `get`.
|
- Added to `wrapnils` an option-like API via `??.`, `isSome`, `get`.
|
||||||
|
|
||||||
- `std/options` changed `$some(3)` to `"some(3)"` instead of `"Some(3)"`
|
- `std/options` changed `$some(3)` to `"some(3)"` instead of `"Some(3)"`
|
||||||
and `$none(int)` to `"none(int)"` instead of `"None[int]"`.
|
and `$none(int)` to `"none(int)"` instead of `"None[int]"`.
|
||||||
|
|
||||||
|
|
||||||
## Language changes
|
## Language changes
|
||||||
|
|
||||||
- `nimscript` now handles `except Exception as e`.
|
- `nimscript` now handles `except Exception as e`.
|
||||||
|
|
|
||||||
|
|
@ -54,20 +54,6 @@ runnableExamples:
|
||||||
## **Note:** If the type has a `==` operator, the following must hold:
|
## **Note:** If the type has a `==` operator, the following must hold:
|
||||||
## If two values compare equal, their hashes must also be equal.
|
## If two values compare equal, their hashes must also be equal.
|
||||||
##
|
##
|
||||||
## You can hash an object by all of its fields with the `fields` iterator:
|
|
||||||
runnableExamples:
|
|
||||||
proc hash(x: object): Hash =
|
|
||||||
for f in fields(x):
|
|
||||||
result = result !& hash(f)
|
|
||||||
result = !$result
|
|
||||||
|
|
||||||
type
|
|
||||||
Obj = object
|
|
||||||
x: int
|
|
||||||
y: string
|
|
||||||
|
|
||||||
doAssert hash(Obj(x: 520, y: "Nim")) != hash(Obj(x: 520, y: "Nim2"))
|
|
||||||
|
|
||||||
## See also
|
## See also
|
||||||
## ========
|
## ========
|
||||||
## * `md5 module <md5.html>`_ for the MD5 checksum algorithm
|
## * `md5 module <md5.html>`_ for the MD5 checksum algorithm
|
||||||
|
|
@ -499,14 +485,24 @@ proc hashIgnoreCase*(sBuf: string, sPos, ePos: int): Hash =
|
||||||
result = !$h
|
result = !$h
|
||||||
|
|
||||||
|
|
||||||
proc hash*[T: tuple](x: T): Hash =
|
proc hash*[T: tuple | object](x: T): Hash =
|
||||||
## Efficient hashing of tuples.
|
## Efficient hashing of tuples and objects.
|
||||||
## There must be a `hash` proc defined for each of the field types.
|
## There must be a `hash` proc defined for each of the field types.
|
||||||
|
runnableExamples:
|
||||||
|
type Obj = object
|
||||||
|
x: int
|
||||||
|
y: string
|
||||||
|
type Obj2[T] = object
|
||||||
|
x: int
|
||||||
|
y: string
|
||||||
|
assert hash(Obj(x: 520, y: "Nim")) != hash(Obj(x: 520, y: "Nim2"))
|
||||||
|
# you can define custom hashes for objects (even if they're generic):
|
||||||
|
proc hash(a: Obj2): Hash = hash((a.x))
|
||||||
|
assert hash(Obj2[float](x: 520, y: "Nim")) == hash(Obj2[float](x: 520, y: "Nim2"))
|
||||||
for f in fields(x):
|
for f in fields(x):
|
||||||
result = result !& hash(f)
|
result = result !& hash(f)
|
||||||
result = !$result
|
result = !$result
|
||||||
|
|
||||||
|
|
||||||
proc hash*[A](x: openArray[A]): Hash =
|
proc hash*[A](x: openArray[A]): Hash =
|
||||||
## Efficient hashing of arrays and sequences.
|
## Efficient hashing of arrays and sequences.
|
||||||
## There must be a `hash` proc defined for the element type `A`.
|
## There must be a `hash` proc defined for the element type `A`.
|
||||||
|
|
|
||||||
|
|
@ -130,5 +130,51 @@ proc main() =
|
||||||
# run at CT, expecting c semantics.
|
# run at CT, expecting c semantics.
|
||||||
discard
|
discard
|
||||||
|
|
||||||
|
block: # hash(object)
|
||||||
|
type
|
||||||
|
Obj = object
|
||||||
|
x: int
|
||||||
|
y: string
|
||||||
|
Obj2[T] = object
|
||||||
|
x: int
|
||||||
|
y: string
|
||||||
|
Obj3 = object
|
||||||
|
x: int
|
||||||
|
y: string
|
||||||
|
Obj4 = object
|
||||||
|
case t: bool
|
||||||
|
of false:
|
||||||
|
x: int
|
||||||
|
of true:
|
||||||
|
y: int
|
||||||
|
z: int
|
||||||
|
Obj5 = object
|
||||||
|
case t: bool
|
||||||
|
of false:
|
||||||
|
x: int
|
||||||
|
of true:
|
||||||
|
y: int
|
||||||
|
z: int
|
||||||
|
|
||||||
|
proc hash(a: Obj2): Hash = hash(a.x)
|
||||||
|
proc hash(a: Obj3): Hash = hash((a.x,))
|
||||||
|
proc hash(a: Obj5): Hash =
|
||||||
|
case a.t
|
||||||
|
of false: hash(a.x)
|
||||||
|
of true: hash(a.y)
|
||||||
|
|
||||||
|
doAssert hash(Obj(x: 520, y: "Nim")) != hash(Obj(x: 520, y: "Nim2"))
|
||||||
|
doAssert hash(Obj2[float](x: 520, y: "Nim")) == hash(Obj2[float](x: 520, y: "Nim2"))
|
||||||
|
doAssert hash(Obj2[float](x: 520, y: "Nim")) != hash(Obj2[float](x: 521, y: "Nim2"))
|
||||||
|
doAssert hash(Obj3(x: 520, y: "Nim")) == hash(Obj3(x: 520, y: "Nim2"))
|
||||||
|
|
||||||
|
doAssert hash(Obj4(t: false, x: 1)) == hash(Obj4(t: false, x: 1))
|
||||||
|
doAssert hash(Obj4(t: false, x: 1)) != hash(Obj4(t: false, x: 2))
|
||||||
|
doAssert hash(Obj4(t: false, x: 1)) != hash(Obj4(t: true, y: 1))
|
||||||
|
|
||||||
|
doAssert hash(Obj5(t: false, x: 1)) != hash(Obj5(t: false, x: 2))
|
||||||
|
doAssert hash(Obj5(t: false, x: 1)) == hash(Obj5(t: true, y: 1))
|
||||||
|
doAssert hash(Obj5(t: false, x: 1)) != hash(Obj5(t: true, y: 2))
|
||||||
|
|
||||||
static: main()
|
static: main()
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue