;;; SPDX-License-Identifier: LGPL-3.0-or-later ;;; SPDX-FileCopyrightText: Copyright © 2010-2021 Tony Garnock-Jones #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)))