45 lines
1.4 KiB
Racket
45 lines
1.4 KiB
Racket
;;; SPDX-License-Identifier: LGPL-3.0-or-later
|
|
;;; SPDX-FileCopyrightText: Copyright © 2016-2021 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
|
|
|
#lang racket/base
|
|
;; Hash-table utilities that are not (yet) part of Racket
|
|
|
|
(provide hash-set/remove
|
|
hashset-member?
|
|
hashset-add
|
|
hashset-remove
|
|
in-hashset-values)
|
|
|
|
(require (only-in racket/set set seteq seteqv))
|
|
|
|
(define (hash-set/remove ht key val [default-val #f] #:compare [compare equal?])
|
|
(if (compare val default-val)
|
|
(hash-remove ht key)
|
|
(hash-set ht key val)))
|
|
|
|
(define (hashset-member? ht key val)
|
|
(define s (hash-ref ht key #f))
|
|
(and s (hash-has-key? s val)))
|
|
|
|
(define (make-hash-from-set-ctor ctor)
|
|
(cond [(eq? ctor set) (hash)]
|
|
[(eq? ctor seteq) (hasheq)]
|
|
[(eq? ctor seteqv) (hasheqv)]
|
|
[else (error 'hash-ctor-for-set-ctor "Cannot use hashset with set constructor ~v" ctor)]))
|
|
|
|
(define (hashset-add ht key val #:set [set-ctor set])
|
|
(define old-set (hash-ref ht key (lambda () (make-hash-from-set-ctor set-ctor))))
|
|
(hash-set ht key (hash-set old-set val #t)))
|
|
|
|
(define (hashset-remove ht k v)
|
|
(define old (hash-ref ht k #f))
|
|
(if old
|
|
(let ((new (hash-remove old v)))
|
|
(if (hash-empty? new)
|
|
(hash-remove ht k)
|
|
(hash-set ht k new)))
|
|
ht))
|
|
|
|
(define-syntax-rule (in-hashset-values ht key)
|
|
(in-hash-keys (hash-ref ht key hash)))
|