Update of /project/flexichain/cvsroot/flexichain
In directory clnet:/tmp/cvs-serv25104
Modified Files:
flexichain.lisp flexicursor.lisp flexirank.lisp utilities.lisp
Log Message:
Patches to make weak pointers work on a number of platforms.
Thanks to Luís Oliveira.
Date: Tue Oct 17 12:02:02 2006
Author: rstrandh
Index: flexichain/flexichain.lisp
diff -u flexichain/flexichain.lisp:1.1.1.1 flexichain/flexichain.lisp:1.2
--- flexichain/flexichain.lisp:1.1.1.1 Wed Feb 8 21:51:06 2006
+++ flexichain/flexichain.lisp Tue Oct 17 12:02:02 2006
@@ -99,6 +99,12 @@
than the length of CHAIN, the FLEXI-POSITION-ERROR condition will be
signaled."))
+(defgeneric insert-vector* (chain position vector)
+ (:documentation "Inserts the elements of VECTOR before the
+element at POSITION in the chain. If POSITION is out of
+range (less than 0 or greater than the length of CHAIN, the
+FLEXI-POSITION-ERROR condition will be signaled."))
+
(defgeneric delete* (chain position)
(:documentation "Deletes an element at POSITION of the chain.
If POSITION is out of range (less than 0 or greater than or equal
Index: flexichain/flexicursor.lisp
diff -u flexichain/flexicursor.lisp:1.1.1.1 flexichain/flexicursor.lisp:1.2
--- flexichain/flexicursor.lisp:1.1.1.1 Wed Feb 8 21:51:06 2006
+++ flexichain/flexicursor.lisp Tue Oct 17 12:02:02 2006
@@ -96,8 +96,7 @@
(defgeneric (setf element>) (object cursor)
(:documentation "Replaces the element immediately after the cursor."))
-(defclass standard-cursorchain
- (weak-pointer-container-mixin cursorchain standard-flexichain)
+(defclass standard-cursorchain (cursorchain standard-flexichain)
((cursors :initform '()))
(:documentation "The standard instantiable subclass of CURSORCHAIN"))
@@ -116,7 +115,7 @@
(with-slots (index chain) cursor
(setf index (position-index chain (1- position)))
(with-slots (cursors) chain
- (push (make-weak-pointer cursor chain) cursors))))
+ (push (make-weak-pointer cursor) cursors))))
(defmethod initialize-instance :after ((cursor right-sticky-flexicursor)
&rest initargs &key (position 0))
@@ -124,12 +123,12 @@
(with-slots (index chain) cursor
(setf index (position-index chain position))
(with-slots (cursors) chain
- (push (make-weak-pointer cursor chain) cursors))))
+ (push (make-weak-pointer cursor) cursors))))
-(defun adjust-cursors (chain cursors start end increment)
+(defun adjust-cursors (cursors start end increment)
(let ((acc '()))
(loop
- for cursor = (and cursors (weak-pointer-value (car cursors) chain))
+ for cursor = (and cursors (weak-pointer-value (car cursors)))
while cursors
do (cond ((null cursor)
(pop cursors))
@@ -149,7 +148,7 @@
(defmethod move-elements :after ((cc standard-cursorchain) to from start1 start2 end2)
(declare (ignore to from))
(with-slots (cursors) cc
- (setf cursors (adjust-cursors cc cursors start2 (1- end2) (- start1 start2)))))
+ (setf cursors (adjust-cursors cursors start2 (1- end2) (- start1 start2)))))
(defmethod clone-cursor ((cursor standard-flexicursor))
(make-instance (class-of cursor)
@@ -195,7 +194,7 @@
(with-slots (cursors) chain
(let* ((old-index (position-index chain position)))
(loop for cursor-wp in cursors
- as cursor = (weak-pointer-value cursor-wp chain)
+ as cursor = (weak-pointer-value cursor-wp)
when (and cursor (= old-index (flexicursor-index cursor)))
do (typecase cursor
(right-sticky-flexicursor (incf (cursor-pos cursor)))
Index: flexichain/flexirank.lisp
diff -u flexichain/flexirank.lisp:1.2 flexichain/flexirank.lisp:1.3
--- flexichain/flexirank.lisp:1.2 Mon Mar 13 13:13:33 2006
+++ flexichain/flexirank.lisp Tue Oct 17 12:02:02 2006
@@ -58,6 +58,7 @@
(defclass flexirank-mixin () ())
(defmethod move-elements :before ((chain flexirank-mixin) to from start1 start2 end2)
+ (declare (ignore to))
(loop for old from start2 below end2
for new from start1
do (let ((element (aref from old)))
Index: flexichain/utilities.lisp
diff -u flexichain/utilities.lisp:1.2 flexichain/utilities.lisp:1.3
--- flexichain/utilities.lisp:1.2 Mon Mar 13 13:13:33 2006
+++ flexichain/utilities.lisp Tue Oct 17 12:02:02 2006
@@ -34,60 +34,52 @@
(values nil nil)
(values (elt sequence position) t))))
-;;; CMUCL and SBCL have direct support for weak pointers. In OpenMCL and
-;;; Allegro 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 ()
- (#+(or openmcl allegro)
- (weak-hash :initform (make-hash-table :test #'eql
- ;; Get it together guys!
- #+openmcl :weak #+openmcl :value
- #+allegro :values #+allegro :weak))
- (key-counter :initform 0))
- (:documentation "Support for weak references, if needed"))
+;;;; Weak pointers
-(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))
-
-#+(or openmcl allegro)
-(defmethod make-weak-pointer (object (container weak-pointer-container-mixin))
- (let ((key (incf (slot-value container 'key-counter))))
- (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 openmcl allegro)
-(defmethod weak-pointer-value
- (weak-pointer (container weak-pointer-container-mixin))
- (let* ((table (slot-value container 'weak-hash))
- (val (gethash weak-pointer table)))
- #+allegro
- (unless val
- (remhash weak-pointer table))
- val))
-
-#-(or sbcl cmu openmcl)
-(progn
- (eval-when (:evaluate :compile-toplevel :load-toplevel)
- (warn "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))
+#+:openmcl
+(defvar *weak-pointers* (make-hash-table :test 'eq :weak :value)
+ "Weak value hash-table mapping between pseudo weak pointers and its values.")
+
+#+:openmcl
+(defstruct (weak-pointer (:constructor %make-weak-pointer)))
+
+(defun make-weak-pointer (object)
+ "Creates a new weak pointer which points to OBJECT. For
+ portability reasons, OBJECT most not be NIL."
+ (assert (not (null object)))
+ #+:sbcl (sb-ext:make-weak-pointer object)
+ #+:cmu (ext:make-weak-pointer object)
+ #+:clisp (ext:make-weak-pointer object)
+ #+:allegro
+ (let ((wv (excl:weak-vector 1)))
+ (setf (svref wv 0) object)
+ wv)
+ #+:openmcl
+ (let ((wp (%make-weak-pointer)))
+ (setf (gethash wp *weak-pointers*) object)
+ wp)
+ #+:corman (ccl:make-weak-pointer object)
+ #+:lispworks
+ (let ((array (make-array 1)))
+ (hcl:set-array-weak array t)
+ (setf (svref array 0) object)
+ array)
+ #-(or :sbcl :cmu :clisp :allegro :openmcl :corman :lispworks)
+ object)
+
+(defun weak-pointer-value (weak-pointer)
+ "If WEAK-POINTER is valid, returns its value. Otherwise, returns NIL."
+ #+:sbcl (prog1 (sb-ext:weak-pointer-value weak-pointer))
+ #+:cmu (prog1 (ext:weak-pointer-value weak-pointer))
+ #+:clisp (prog1 (ext:weak-pointer-value weak-pointer))
+ #+:allegro (svref weak-pointer 0)
+ #+:openmcl (prog1 (gethash weak-pointer *weak-pointers*))
+ #+:corman (ccl:weak-pointer-obj weak-pointer)
+ #+:lispworks (svref weak-pointer 0)
+ #-(or :sbcl :cmu :clisp :allegro :openmcl :corman :lispworks)
+ weak-pointer)
+
+#-(or :sbcl :cmu :clisp :allegro :openmcl :corman :lispworks)
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (warn "No support for weak pointers in this implementation. ~
+ Things may get big and slow."))