;;;; util.lisp -- some utilities (in-package :oneliners.api) (defun plist-find (indicator plist &key (test 'eq) (key 'identity)) (loop for (ind val . more) on plist by #'cddr when (funcall test indicator (funcall key ind)) return val)) (defmacro with-plist ((&rest keys) plist &rest body) (let ((the-plist (gensym))) `(let ((,the-plist ,plist)) (let ,(loop for key in keys collect `(,key (plist-find (symbol-name ',key) ,the-plist :test #'string-equal :key #'symbol-name))) ,@body)))) (defclass queue-buffer () ((front :initform (list)) (back :initform (list)) (size :initform 0) (capacity :initarg capacity))) (defun make-qb (capacity) (make-instance 'queue-buffer :capacity capacity)) (defun qb-empty-p (q) (zerop (slot-value q 'size))) (defun qb-full-p (q) (= (slot-value q 'size) (slot-value q 'capacity))) (defun enqueue-qb (q x) (when (qb-full-p q) (dequeue-qb q)) (with-slots (size back) q (push x back) (incf size))) (defun dequeue-qb (q &optional default) (with-slots (front back size) q (cond ((plusp size) (when (null front) (setf front (nreverse back) back nil)) (decf size) (pop front)) (t default)))) (defun qb-look (q) "get a list of the queue, but don't remove items from it" (with-slots (front back) q (nconc (copy-seq front) (reverse back))))