Add initial support for SEQUENCE integration. sequence
authorOlof-Joachim Frahm <olof@macrolet.net>
Thu, 11 Jul 2013 21:02:22 +0000 (23:02 +0200)
committerOlof-Joachim Frahm <olof@macrolet.net>
Thu, 11 Jul 2013 21:02:22 +0000 (23:02 +0200)
Also simplification of the existing MAKE-ITERATOR.

iterator.lisp
sequence.lisp [new file with mode: 0644]
trees.asd
types.lisp

index 3cdaa1c..e8c7ea9 100644 (file)
@@ -1,7 +1,7 @@
 (in-package :trees)
 
 (in-package :trees)
 
-(defun extreme-node-with-path (root direction &optional path)
-  (do ((node root (funcall direction node))
+(defun extreme-node-with-path (root leftp &optional path)
+  (do ((node root (if leftp (left node) (right node)))
        (parent nil node))
       ((null node) (values parent path))
     (push node path)))
        (parent nil node))
       ((null node) (values parent path))
     (push node path)))
                        (stack nil stackp))
   (declare (type binary-tree tree))
   (let ((modcount (modcount tree)))
                        (stack nil stackp))
   (declare (type binary-tree tree))
   (let ((modcount (modcount tree)))
-    (multiple-value-bind (extremum examine)
-                  (if forwardp
-                      (values #'left #'right)
-                      (values #'right #'left))
-      (multiple-value-bind (current stack)
-          (if (and currentp stackp)
-              (values current stack)
-              (extreme-node-with-path (root tree) extremum))
-        #'(lambda ()
-            (cond
-              ((/= modcount (modcount tree))
-               (error "~A modified during iteration" tree))
-              ((null current)
-               (values nil nil))
-              (t
-               (let* ((next current)
-                      (top (pop stack))
-                      (node (funcall examine top)))
-                 (cond
-                   ((null node)
-                    (setf current (first stack)))
-                   (t
-                    (setf (values current stack)
-                          (extreme-node-with-path node extremum stack))))
-                 (values next t)))))))))
+    (multiple-value-bind (current stack)
+        (if (and currentp stackp)
+            (values current stack)
+            (extreme-node-with-path (root tree) forwardp))
+      (lambda ()
+        (cond
+          ((/= modcount (modcount tree))
+           (error "~A modified during iteration" tree))
+          ((null current)
+           (values nil nil))
+          (t
+           (let* ((next current)
+                  (top (pop stack))
+                  (node (if forwardp (right top) (left top))))
+             (cond
+               ((null node)
+                (setf current (first stack)))
+               (t
+                (setf (values current stack)
+                      (extreme-node-with-path node forwardp stack))))
+             (values next t))))))))
diff --git a/sequence.lisp b/sequence.lisp
new file mode 100644 (file)
index 0000000..1d7b2db
--- /dev/null
@@ -0,0 +1,35 @@
+(in-package :trees)
+
+(defmethod sequence:length ((binary-tree binary-tree))
+  (size binary-tree))
+
+(defmethod sequence:make-simple-sequence-iterator ((binary-tree binary-tree)
+                                                   &key from-end (start 0) end)
+  (when (or (not (zerop start)) end)
+    (error "~A and ~A are unsupported for ~A" 'start 'end 'binary-tree))
+  (multiple-value-bind (current stack)
+      (extreme-node-with-path (root binary-tree) (not from-end))
+    (declare (ignore current))
+    (values stack NIL from-end)))
+
+(defmethod sequence:iterator-step ((binary-tree binary-tree) iterator from-end)
+  (let* ((current (car iterator))
+         (stack (cdr iterator))
+         (node (if from-end (left current) (right current))))
+    (cond
+      ((null node)
+       stack)
+      (t
+       (multiple-value-bind (current stack)
+           (extreme-node-with-path node (not from-end) stack)
+         (declare (ignore current))
+         stack)))))
+
+(defmethod sequence:iterator-endp ((binary-tree binary-tree) iterator limit from-end)
+  (declare (ignore limit from-end))
+  (null iterator))
+
+(defmethod sequence:iterator-element ((binary-tree binary-tree) iterator)
+  (datum (car iterator)))
+
+;; (defmethod sequence:iterator-index ((binary-tree binary-tree) iterator))
index b8b3a47..8f13810 100644 (file)
--- a/trees.asd
+++ b/trees.asd
@@ -19,6 +19,7 @@
                (:file "avl-trees" :depends-on ("types" "binary-trees"))
                (:file "aa-trees" :depends-on ("types" "binary-trees"))
                (:file "iterator" :depends-on ("types" "binary-trees"))
                (:file "avl-trees" :depends-on ("types" "binary-trees"))
                (:file "aa-trees" :depends-on ("types" "binary-trees"))
                (:file "iterator" :depends-on ("types" "binary-trees"))
+               (:file "sequence" :depends-on ("iterator"))
                (:file "utils" :depends-on ("binary-trees"))
                (:static-file "LICENSE")
                (:static-file "README")
                (:file "utils" :depends-on ("binary-trees"))
                (:static-file "LICENSE")
                (:static-file "README")
index d2235d1..83f9821 100644 (file)
 \f
 ;;; trees
 
 \f
 ;;; trees
 
+#+sbcl
+(defclass binary-tree (sequence standard-object)
+  ((test :initform #1=(error "missing arg")
+         :initarg :test
+         :type 'function
+         :reader test)
+   (key :initform #1#
+        :initarg :key
+        :type 'function
+        :reader key)
+   (pred :initform #1#
+         :initarg :pred
+         :type 'function
+         :reader pred)
+   (size :initform 0
+         :initarg :size
+         :type 'fixnum
+         :accessor size)
+   (root :initform nil
+         :initarg :root
+         :type '(or null tree-node)
+         :accessor root)
+   (modcount :initform 0
+             :initarg :modcount
+             :type 'fixnum
+             :accessor modcount)
+   (nodegen :initform #1#
+            :initarg :nodegen
+            :type 'function
+            :reader nodegen)
+   (rebalance/insert :initform nil
+                     :initarg :rebalance/insert
+                     :type '(or null function)
+                     :reader rebalance/insert)
+   (rebalance/delete :initform nil
+                     :initarg :rebalance/delete
+                     :type '(or null function)
+                     :reader rebalance/delete)))
+
+#+sbcl
+(defun %make-binary-tree (pred key test nodegen rebalance/insert rebalance/delete)
+  (make-instance 'binary-tree :pred pred :key key :test test :nodegen nodegen
+                              :rebalance/insert rebalance/insert
+                              :rebalance/delete rebalance/delete))
+
+#-sbcl
 (defstruct (binary-tree
              (:conc-name)
              (:constructor %make-binary-tree (pred key test
 (defstruct (binary-tree
              (:conc-name)
              (:constructor %make-binary-tree (pred key test