[gsharp-cvs] CVS update: gsharp/Flexichain/flexicursor.lisp gsharp/Flexichain/utilities.lisp

Timothy Moore tmoore at common-lisp.net
Fri Jan 14 16:12:43 UTC 2005


Update of /project/gsharp/cvsroot/gsharp/Flexichain
In directory common-lisp.net:/tmp/cvs-serv18364

Modified Files:
	flexicursor.lisp utilities.lisp 
Log Message:
Generalized weak pointer support and added an implementation for OpenMCL.
Date: Fri Jan 14 17:12:42 2005
Author: tmoore

Index: gsharp/Flexichain/flexicursor.lisp
diff -u gsharp/Flexichain/flexicursor.lisp:1.9 gsharp/Flexichain/flexicursor.lisp:1.10
--- gsharp/Flexichain/flexicursor.lisp:1.9	Mon Jan  3 07:44:42 2005
+++ gsharp/Flexichain/flexicursor.lisp	Fri Jan 14 17:12:41 2005
@@ -96,18 +96,11 @@
 (defgeneric (setf element>) (object cursor)
   (:documentation "Replaces the element immediately after the cursor."))
 
-(defclass standard-cursorchain (cursorchain standard-flexichain)
+(defclass standard-cursorchain
+    (weak-pointer-container-mixin cursorchain standard-flexichain)
   ((cursors :initform '()))
   (:documentation "The standard instantiable subclass of CURSORCHAIN"))
 
-(defun make-wp (value)
-  #+sbcl (sb-ext:make-weak-pointer value)
-  #+cmu  (ext:make-weak-pointer value))
-
-(defun wp-value (wp)
-  #+sbcl (sb-ext:weak-pointer-value wp)
-  #+cmu  (ext:weak-pointer-value wp))
-
 (defclass standard-flexicursor (flexicursor)
   ((chain :reader chain :initarg :chain)
    (index :accessor flexicursor-index))
@@ -123,7 +116,7 @@
   (with-slots (index chain) cursor
      (setf index (position-index chain (1- position)))
      (with-slots (cursors) chain
-	(push (make-wp cursor) cursors))))
+	(push (make-weak-pointer cursor chain) cursors))))
 
 (defmethod initialize-instance :after ((cursor right-sticky-flexicursor)
 				       &rest initargs &key (position 0))
@@ -131,30 +124,32 @@
   (with-slots (index chain) cursor
      (setf index (position-index chain position))
      (with-slots (cursors) chain
-	(push (make-wp cursor) cursors))))
+	(push (make-weak-pointer cursor chain) cursors))))
 
-(defun adjust-cursors (cursors start end increment)
+(defun adjust-cursors (chain cursors start end increment)
   (let ((acc '()))
-    (loop while cursors
-	  do (cond ((null (wp-value (car cursors)))
-		    (pop cursors))
-		   ((<= start (flexicursor-index (wp-value (car cursors))) end)
-		    (incf (flexicursor-index (wp-value (car cursors))) increment)
+    (loop
+       for cursor = (and cursors (weak-pointer-value (car cursors) chain))
+       while cursors
+       do (cond ((null cursor)
+		 (pop cursors))
+		((<= start (flexicursor-index cursor) end)
+		    (incf (flexicursor-index cursor) increment)
 		    (let ((rest (cdr cursors)))
 		      (setf (cdr cursors) acc
 			    acc cursors
 			    cursors rest)))
-		   (t
-		    (let ((rest (cdr cursors)))
-		      (setf (cdr cursors) acc
-			    acc cursors
-			    cursors rest)))))
+		(t
+		 (let ((rest (cdr cursors)))
+		   (setf (cdr cursors) acc
+			 acc cursors
+			 cursors rest)))))
     acc))
 
 (defmethod move-elements :after ((cc standard-cursorchain) to from start1 start2 end2)
   (declare (ignore to from))
   (with-slots (cursors) cc
-     (setf cursors (adjust-cursors cursors start2 (1- end2) (- start1 start2)))))
+     (setf cursors (adjust-cursors cc cursors start2 (1- end2) (- start1 start2)))))
 
 (defmethod clone-cursor ((cursor standard-flexicursor))
   (make-instance (class-of cursor)
@@ -200,7 +195,7 @@
   (with-slots (cursors) chain
      (let* ((old-index (position-index chain position)))
        (loop for cursor-wp in cursors
-	     as cursor = (wp-value cursor-wp)
+	     as cursor = (weak-pointer-value cursor-wp chain)
 	     when (and cursor (= old-index (flexicursor-index cursor)))
 	       do (typecase cursor
 		    (right-sticky-flexicursor (incf (cursor-pos cursor)))


Index: gsharp/Flexichain/utilities.lisp
diff -u gsharp/Flexichain/utilities.lisp:1.1 gsharp/Flexichain/utilities.lisp:1.2
--- gsharp/Flexichain/utilities.lisp:1.1	Sun Aug  1 17:27:19 2004
+++ gsharp/Flexichain/utilities.lisp	Fri Jan 14 17:12:41 2005
@@ -34,17 +34,52 @@
         (values nil nil)
         (values (elt sequence position) t))))
 
-(defun make-weak-pointer (object)
-  "Returns a weak pointer to OBJECT."
-  #+cmu (extensions:make-weak-pointer object)
-  #+sbcl (sb-ext:make-weak-pointer object)
-  #-(or cmu sbcl) (error "MAKE-WEAK-POINTER not implemented."))
-
-(defun weak-pointer-value (weak-pointer)
-  ;; TODO: check other CL implementations behavior wrt. return values
-  "Returns the object pointed to by WEAK-POINTER or NIL if the pointer
-is broken."
+;;; CMUCL and SBCL have direct support for weak pointers. In OpenMCL weak
+;;; references are only supported via weak hash tables. This class provides
+;;; the means for other classes to manage their weak references.
+;;;
+;;; TODO: check other CL implementations behavior wrt. return values
+(defclass weak-pointer-container-mixin ()
+  #+openmcl
+  ((weak-hash :initform (make-hash-table :test #'eq :weak :value)))
+  (:documentation "Support for weak references, if needed"))
+
+(defgeneric make-weak-pointer (object container))
+
+#+(or sbcl cmu)
+(defmethod make-weak-pointer (object container)
+  (declare (ignore container))
+    #+cmu (extensions:make-weak-pointer object)
+    #+sbcl (sb-ext:make-weak-pointer object))
+
+#+openmcl
+(defmethod make-weak-pointer (object (container weak-pointer-container-mixin))
+  (let ((key (cons nil nil)))
+    (setf (gethash key (slot-value container 'weak-hash)) object)
+    key))
+
+(defgeneric weak-pointer-value (weak-pointer container))
+
+#+(or sbcl cmu)
+(defmethod weak-pointer-value (weak-pointer container)
+  (declare (ignore container))
   #+cmu (extensions:weak-pointer-value weak-pointer)
-  #+sbcl (sb-ext:weak-pointer-value weak-pointer)
-  #-(or cmu sbcl) (error "WEAK-POINTER-VALUE not implemented."))
+  #+sbcl (sb-ext:weak-pointer-value weak-pointer))
+
+#+openmcl
+(defmethod weak-pointer-value
+    (weak-pointer (container weak-pointer-container-mixin))
+  (gethash weak-pointer (slot-value container 'weak-hash) nil))
 
+#-(or sbcl cmu openmcl)
+(progn
+  (eval-when (:evaluate :compile-toplevel :load-toplevel)
+    (warning "No support for weak pointers in this implementation. Things may
+get big and slow")
+    )
+  (defmethod make-weak-pointer (object container)
+    (declare (ignore container))
+    object)
+  (defmethod weak-pointer-value (weak-pointer container)
+    (declare (ignore container))
+    weak-pointer))




More information about the Gsharp-cvs mailing list