diff options
-rw-r--r-- | gtwiwtg.lisp | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/gtwiwtg.lisp b/gtwiwtg.lisp index 413fce0..059c1b0 100644 --- a/gtwiwtg.lisp +++ b/gtwiwtg.lisp @@ -126,6 +126,32 @@ (defmethod stop :after ((g stream-backed-generator!)) (close (slot-value g 'stream))) + + +(defclass filtered-generator (generator!) + ((on-deck :initform (list)) + (source-generator :initform (error "filtered generator must have a source") + :initarg :source) + (predicate :initform (error "filtered generator must have a predicate") + :initarg :predicate))) + +(defmethod next ((gen filtered-generator)) + (pop (slot-value gen 'on-deck))) + +(defmethod has-next-p ((gen filtered-generator)) + (with-slots (source-generator predicate on-deck) gen + (or on-deck + (loop :while (has-next-p source-generator) + :for candidate = (next source-generator) + :when (funcall predicate candidate) + :do (push candidate on-deck) + (return t) + :finally (return nil))))) + +(defmethod stop :after ((gen filtered-generator)) + (stop (slot-value gen 'source-generator))) + + ;;; CONSTRUCTORS (defun range (&key (from 0) to (by 1) inclusive) @@ -363,28 +389,6 @@ Error Conditions: (lambda () (dolist (g all-gens) (stop g)))))) -(defclass filtered-generator (generator!) - ((on-deck :initform (list)) - (source-generator :initform (error "filtered generator must have a source") - :initarg :source) - (predicate :initform (error "filtered generator must have a predicate") - :initarg :predicate))) - -(defmethod next ((gen filtered-generator)) - (pop (slot-value gen 'on-deck))) - -(defmethod has-next-p ((gen filtered-generator)) - (with-slots (source-generator predicate on-deck) gen - (or on-deck - (loop :while (has-next-p source-generator) - :for candidate = (next source-generator) - :when (funcall predicate candidate) - :do (push candidate on-deck) - (return t) - :finally (return nil))))) - -(defmethod stop :after ((gen filtered-generator)) - (stop (slot-value gen 'source-generator))) (defun filter! (pred gen) |