update packages
This commit is contained in:
80
lisp/ht.el
80
lisp/ht.el
@@ -4,8 +4,8 @@
|
||||
|
||||
;; Author: Wilfred Hughes <me@wilfred.me.uk>
|
||||
;; Version: 2.3
|
||||
;; Package-Version: 20200217.2331
|
||||
;; Package-Commit: fff8c43f0e03d5b98deb9f988522b839ce2ca253
|
||||
;; Package-Version: 20201119.518
|
||||
;; Package-Commit: 2850301d19176b8d3bb6cc8d95af6ab7e529bd56
|
||||
;; Keywords: hash table, hash map, hash
|
||||
;; Package-Requires: ((dash "2.12.0"))
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
|
||||
(require 'dash)
|
||||
(require 'gv)
|
||||
(eval-when-compile
|
||||
(require 'inline))
|
||||
|
||||
(defmacro ht (&rest pairs)
|
||||
"Create a hash table with the key-value pairs given.
|
||||
@@ -47,20 +49,22 @@ Keys are compared with `equal'.
|
||||
,@assignments
|
||||
,table-symbol)))
|
||||
|
||||
(defsubst ht-set! (table key value)
|
||||
(define-inline ht-set! (table key value)
|
||||
"Associate KEY in TABLE with VALUE."
|
||||
(puthash key value table)
|
||||
nil)
|
||||
(inline-quote
|
||||
(prog1 nil
|
||||
(puthash ,key ,value ,table))))
|
||||
|
||||
(defalias 'ht-set 'ht-set!)
|
||||
|
||||
(defsubst ht-create (&optional test)
|
||||
(define-inline ht-create (&optional test)
|
||||
"Create an empty hash table.
|
||||
|
||||
TEST indicates the function used to compare the hash
|
||||
keys. Default is `equal'. It can be `eq', `eql', `equal' or a
|
||||
user-supplied test created via `define-hash-table-test'."
|
||||
(make-hash-table :test (or test 'equal)))
|
||||
(declare (side-effect-free t))
|
||||
(inline-quote (make-hash-table :test (or ,test 'equal))))
|
||||
|
||||
(defun ht<-alist (alist &optional test)
|
||||
"Create a hash table with initial values according to ALIST.
|
||||
@@ -68,6 +72,7 @@ user-supplied test created via `define-hash-table-test'."
|
||||
TEST indicates the function used to compare the hash
|
||||
keys. Default is `equal'. It can be `eq', `eql', `equal' or a
|
||||
user-supplied test created via `define-hash-table-test'."
|
||||
(declare (side-effect-free t))
|
||||
(let ((h (ht-create test)))
|
||||
;; the first key-value pair in an alist gets precedence, so we
|
||||
;; start from the end of the list:
|
||||
@@ -84,6 +89,7 @@ user-supplied test created via `define-hash-table-test'."
|
||||
TEST indicates the function used to compare the hash
|
||||
keys. Default is `equal'. It can be `eq', `eql', `equal' or a
|
||||
user-supplied test created via `define-hash-table-test'."
|
||||
(declare (side-effect-free t))
|
||||
(let ((h (ht-create test)))
|
||||
(dolist (pair (nreverse (-partition 2 plist)) h)
|
||||
(let ((key (car pair))
|
||||
@@ -92,22 +98,27 @@ user-supplied test created via `define-hash-table-test'."
|
||||
|
||||
(defalias 'ht-from-plist 'ht<-plist)
|
||||
|
||||
(defsubst ht-get (table key &optional default)
|
||||
(define-inline ht-get (table key &optional default)
|
||||
"Look up KEY in TABLE, and return the matching value.
|
||||
If KEY isn't present, return DEFAULT (nil if not specified)."
|
||||
(gethash key table default))
|
||||
(declare (side-effect-free t))
|
||||
(inline-quote
|
||||
(gethash ,key ,table ,default)))
|
||||
|
||||
;; Don't use `ht-set!' here, gv setter was assumed to return the value
|
||||
;; to be set.
|
||||
(gv-define-setter ht-get (value table key) `(puthash ,key ,value ,table))
|
||||
|
||||
(defun ht-get* (table &rest keys)
|
||||
(define-inline ht-get* (table &rest keys)
|
||||
"Look up KEYS in nested hash tables, starting with TABLE.
|
||||
The lookup for each key should return another hash table, except
|
||||
for the final key, which may return any value."
|
||||
(while keys
|
||||
(setf table (ht-get table (pop keys))))
|
||||
table)
|
||||
(declare (side-effect-free t))
|
||||
(inline-letevals (table keys)
|
||||
(inline-quote
|
||||
(prog1 ,table
|
||||
(while ,keys
|
||||
(setf ,table (ht-get table (pop ,keys))))))))
|
||||
|
||||
(put 'ht-get* 'compiler-macro
|
||||
(lambda (_ table &rest keys)
|
||||
@@ -130,16 +141,17 @@ table is used."
|
||||
(mapc (lambda (table) (ht-update! merged table)) tables)
|
||||
merged))
|
||||
|
||||
(defsubst ht-remove! (table key)
|
||||
(define-inline ht-remove! (table key)
|
||||
"Remove KEY from TABLE."
|
||||
(remhash key table))
|
||||
(inline-quote (remhash ,key ,table)))
|
||||
|
||||
(defalias 'ht-remove 'ht-remove!)
|
||||
|
||||
(defsubst ht-clear! (table)
|
||||
(define-inline ht-clear! (table)
|
||||
"Remove all keys from TABLE."
|
||||
(clrhash table)
|
||||
nil)
|
||||
(inline-quote
|
||||
(prog1 nil
|
||||
(clrhash ,table))))
|
||||
|
||||
(defalias 'ht-clear 'ht-clear!)
|
||||
|
||||
@@ -162,14 +174,17 @@ these variables, then use `ht-map' to avoid warnings."
|
||||
|
||||
(defun ht-keys (table)
|
||||
"Return a list of all the keys in TABLE."
|
||||
(declare (side-effect-free t))
|
||||
(ht-map (lambda (key _value) key) table))
|
||||
|
||||
(defun ht-values (table)
|
||||
"Return a list of all the values in TABLE."
|
||||
(declare (side-effect-free t))
|
||||
(ht-map (lambda (_key value) value) table))
|
||||
|
||||
(defun ht-items (table)
|
||||
"Return a list of two-element lists '(key value) from TABLE."
|
||||
(declare (side-effect-free t))
|
||||
(ht-amap (list key value) table))
|
||||
|
||||
(defalias 'ht-each 'maphash
|
||||
@@ -184,6 +199,7 @@ variables key and value bound."
|
||||
|
||||
(defun ht-select-keys (table keys)
|
||||
"Return a copy of TABLE with only the specified KEYS."
|
||||
(declare (side-effect-free t))
|
||||
(let (result)
|
||||
(setq result (make-hash-table :test (hash-table-test table)))
|
||||
(dolist (key keys result)
|
||||
@@ -199,13 +215,15 @@ inverse of `ht<-plist'. The following is not guaranteed:
|
||||
\(let ((data '(a b c d)))
|
||||
(equalp data
|
||||
(ht->plist (ht<-plist data))))"
|
||||
(declare (side-effect-free t))
|
||||
(apply 'append (ht-items table)))
|
||||
|
||||
(defalias 'ht-to-plist 'ht->plist)
|
||||
|
||||
(defsubst ht-copy (table)
|
||||
(define-inline ht-copy (table)
|
||||
"Return a shallow copy of TABLE (keys and values are shared)."
|
||||
(copy-hash-table table))
|
||||
(declare (side-effect-free t))
|
||||
(inline-quote (copy-hash-table ,table)))
|
||||
|
||||
(defun ht->alist (table)
|
||||
"Return a list of two-element lists '(key . value) from TABLE.
|
||||
@@ -216,6 +234,7 @@ inverse of `ht<-alist'. The following is not guaranteed:
|
||||
\(let ((data '((a . b) (c . d))))
|
||||
(equalp data
|
||||
(ht->alist (ht<-alist data))))"
|
||||
(declare (side-effect-free t))
|
||||
(ht-amap (cons key value) table))
|
||||
|
||||
(defalias 'ht-to-alist 'ht->alist)
|
||||
@@ -224,20 +243,26 @@ inverse of `ht<-alist'. The following is not guaranteed:
|
||||
|
||||
(defalias 'ht-p 'hash-table-p)
|
||||
|
||||
(defun ht-contains? (table key)
|
||||
(define-inline ht-contains? (table key)
|
||||
"Return 't if TABLE contains KEY."
|
||||
(let ((not-found-symbol (make-symbol "ht--not-found")))
|
||||
(not (eq (ht-get table key not-found-symbol) not-found-symbol))))
|
||||
(declare (side-effect-free t))
|
||||
(inline-quote
|
||||
(let ((not-found-symbol (make-symbol "ht--not-found")))
|
||||
(not (eq (ht-get ,table ,key not-found-symbol) not-found-symbol)))))
|
||||
|
||||
(defalias 'ht-contains-p 'ht-contains?)
|
||||
|
||||
(defsubst ht-size (table)
|
||||
(define-inline ht-size (table)
|
||||
"Return the actual number of entries in TABLE."
|
||||
(hash-table-count table))
|
||||
(declare (side-effect-free t))
|
||||
(inline-quote
|
||||
(hash-table-count ,table)))
|
||||
|
||||
(defsubst ht-empty? (table)
|
||||
(define-inline ht-empty? (table)
|
||||
"Return true if the actual number of entries in TABLE is zero."
|
||||
(zerop (ht-size table)))
|
||||
(declare (side-effect-free t))
|
||||
(inline-quote
|
||||
(zerop (ht-size ,table))))
|
||||
|
||||
(defalias 'ht-empty-p 'ht-empty?)
|
||||
|
||||
@@ -295,6 +320,7 @@ FUNCTION is called with two arguments, KEY and VALUE."
|
||||
(defun ht-equal? (table1 table2)
|
||||
"Return t if TABLE1 and TABLE2 have the same keys and values.
|
||||
Does not compare equality predicates."
|
||||
(declare (side-effect-free t))
|
||||
(let ((keys1 (ht-keys table1))
|
||||
(keys2 (ht-keys table2))
|
||||
(sentinel (make-symbol "ht-sentinel")))
|
||||
|
||||
Reference in New Issue
Block a user