38 lines
932 B
Nim
38 lines
932 B
Nim
# SPDX-License-Identifier: ISC
|
|
|
|
## An unordered association of items to counts.
|
|
## An item count may be negative, unlike CountTable.
|
|
|
|
import tables
|
|
|
|
type
|
|
ChangeDescription* = enum
|
|
cdPresentToAbsent,
|
|
cdAbsentToAbsent,
|
|
cdAbsentToPresent,
|
|
cdPresentToPresent
|
|
|
|
Bag*[T] = Table[T, int]
|
|
|
|
proc change(count: var int; delta: int; clamp: bool): ChangeDescription =
|
|
var
|
|
oldCount = count
|
|
newCount = oldCount + delta
|
|
if clamp:
|
|
newCount = max(0, newCount)
|
|
if newCount == 0:
|
|
result =
|
|
if oldCount == 0: cdAbsentToAbsent
|
|
else: cdPresentToAbsent
|
|
else:
|
|
result =
|
|
if oldCount == 0: cdAbsentToPresent
|
|
else: cdPresentToPresent
|
|
count = newCount
|
|
|
|
proc change*[T](bag: var Bag[T]; key: T; delta: int; clamp = false): ChangeDescription =
|
|
assert(delta != 0)
|
|
result = change(bag.mGetOrPut(key, 0), delta, clamp)
|
|
if result in {cdAbsentToAbsent, cdPresentToAbsent}:
|
|
bag.del(key)
|