;;; -*- mode: Lisp; Syntax: Common-Lisp; -*- ;;; ;;; Copyright (c) 2009 by the authors. ;;; ;;; See LICENCE for details. (in-package :hu.dwim.wui) ;; from arnesi (def macro dolist* ((iterator list &optional return-value) &body body) "Like DOLIST but destructuring-binds the elements of LIST. If ITERATOR is a symbol then dolist* is just like dolist EXCEPT that it creates a fresh binding." (if (listp iterator) (let ((i (gensym "DOLIST*-I-"))) `(dolist (,i ,list ,return-value) (destructuring-bind ,iterator ,i ,@body))) `(dolist (,iterator ,list ,return-value) (let ((,iterator ,iterator)) ,@body)))) (def function map-subclasses (class fn &key proper?) "Applies fn to each subclass of class. If proper? is true, then the class itself is not included in the mapping. Proper? defaults to nil." (let ((mapped (make-hash-table :test #'eq))) (labels ((mapped-p (class) (gethash class mapped)) (do-it (class root) (unless (mapped-p class) (setf (gethash class mapped) t) (unless (and proper? root) (funcall fn class)) (mapc (lambda (class) (do-it class nil)) (class-direct-subclasses class))))) (do-it (etypecase class (symbol (find-class class)) (class class)) t)))) (def function subclasses (class &key (proper? t)) "Returns all of the subclasses of the class including the class itself." (let ((result nil)) (map-subclasses class (lambda (class) (push class result)) :proper? proper?) (nreverse result)))