util/iter: allow stopping an iterator by setting its stop slot to t

This commit is contained in:
Helmut Merz 2024-09-09 19:52:19 +02:00
parent 18bfcd8224
commit 60cee40051

View file

@ -5,36 +5,38 @@
(defpackage :scopes/util/iter
(:use :common-lisp)
(:export #:next #:value #:next-value #:process
(:export #:stop #:next #:value #:next-value #:process
#:list-iterator))
(in-package :scopes/util/iter)
;;;; iterators
(defclass abstract-iterator () ())
(defclass iterator ()
((stop :accessor stop :initform nil)))
(defgeneric next (it))
(defgeneric value (it))
(defgeneric next-value (it)
(:method ((it abstract-iterator))
(:method ((it iterator))
(next it)
(value it)))
(defgeneric process (it fn &optional stop)
(:method ((it abstract-iterator) fn &optional (stop (constantly nil)))
(defgeneric process (it fn)
(:method ((it iterator) fn)
(do ((eoi (next it) (next it)))
((or eoi (funcall stop)))
(funcall fn (value it)))))
((or eoi (stop it)))
(funcall fn (value it)))
(setf (stop it) nil)))
;;;; list iterator implementation
(defclass list-iterator (abstract-iterator)
(defclass list-iterator (iterator)
((data :reader data :initarg :data :initform nil)
(cur :accessor cur)))
(defmethod initialize-instance :after ((it list-iterator) &key &allow-other-keys)
(defmethod initialize-instance :after ((it list-iterator) &key)
(setf (cur it) (cons nil (data it))))
(defmethod next ((it list-iterator))