fix `hash-clear!' on impersonated hash tables
Closes PR 13977
This commit is contained in:
parent
5f0c06956a
commit
e02e04ff2a
|
@ -845,7 +845,10 @@
|
|||
(hash-set! ht add1 sub1)
|
||||
(test 9 (hash-ref ht add1) 10)
|
||||
(test '(10) 'for-hash (for/list ([(k v) (in-hash ht)])
|
||||
(k (v 10)))))))
|
||||
(test v hash-ref ht k)
|
||||
(k (v 10))))
|
||||
(test (void) hash-clear! ht)
|
||||
(test 0 hash-count ht))))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
|
@ -866,8 +869,7 @@
|
|||
(test #f hash-ref h 1 #f)
|
||||
(err/rt-test (hash-iterate-value h (hash-iterate-first h)))
|
||||
(err/rt-test (hash-map h void))
|
||||
(err/rt-test (hash-for-each h void))
|
||||
(err/rt-test (hash-clear! h))))])
|
||||
(err/rt-test (hash-for-each h void))))])
|
||||
(check (make-hash))
|
||||
(check (make-hasheq))
|
||||
(check (make-weak-hash))
|
||||
|
|
|
@ -2424,25 +2424,31 @@ static Scheme_Object *hash_table_remove(int argc, Scheme_Object *argv[])
|
|||
|
||||
static Scheme_Object *hash_table_clear_bang(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
Scheme_Object *v;
|
||||
Scheme_Object *v, *v2;
|
||||
|
||||
v = argv[0];
|
||||
|
||||
if (!(SCHEME_HASHTP(v) && SCHEME_MUTABLEP(v)) && !SCHEME_BUCKTP(v))
|
||||
v2 = (SCHEME_NP_CHAPERONEP(v) ? SCHEME_CHAPERONE_VAL(v) : v);
|
||||
|
||||
if (!(SCHEME_HASHTP(v2) && SCHEME_MUTABLEP(v2)) && !SCHEME_BUCKTP(v2))
|
||||
scheme_wrong_contract("hash-clear!", "(and/c hash? (not/c immutable?))", 0, argc, argv);
|
||||
|
||||
if (SCHEME_NP_CHAPERONEP(v) && (SCHEME_HASHTP(SCHEME_CHAPERONE_VAL(v))
|
||||
|| SCHEME_BUCKTP(SCHEME_CHAPERONE_VAL(v)))) {
|
||||
/* Implement `(hash-clear! ht)' as `(hash-for-each ht hash-set!)'
|
||||
/* Implement `(hash-clear! ht)' as `(hash-for-each ht (lambda (k) (hash-remove! ht k)))'
|
||||
to allow chaperones to interpose. */
|
||||
Scheme_Object *i, *a[2];
|
||||
Scheme_Object *i, *a[2], *key;
|
||||
a[0] = v;
|
||||
while (1) {
|
||||
i = scheme_hash_table_iterate_start(1, a);
|
||||
if (SCHEME_FALSEP(i))
|
||||
break;
|
||||
a[2] = i;
|
||||
hash_table_remove_bang(1, a);
|
||||
|
||||
a[1] = i;
|
||||
key = scheme_hash_table_iterate_key(2, a);
|
||||
a[1] = key;
|
||||
|
||||
hash_table_remove_bang(2, a);
|
||||
}
|
||||
} else if (SCHEME_BUCKTP(v)) {
|
||||
scheme_clear_bucket_table((Scheme_Bucket_Table *)v);
|
||||
|
|
Loading…
Reference in New Issue
Block a user