[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] Changes to emacs/lisp/emacs-lisp/ring.el,v
From: |
Richard M. Stallman |
Subject: |
[Emacs-diffs] Changes to emacs/lisp/emacs-lisp/ring.el,v |
Date: |
Sun, 14 Oct 2007 22:52:59 +0000 |
CVSROOT: /cvsroot/emacs
Module name: emacs
Changes by: Richard M. Stallman <rms> 07/10/14 22:52:59
Index: ring.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/emacs-lisp/ring.el,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -b -r1.25 -r1.26
--- ring.el 26 Jul 2007 05:26:48 -0000 1.25
+++ ring.el 14 Oct 2007 22:52:59 -0000 1.26
@@ -164,6 +164,78 @@
(dotimes (var (cadr ring) lst)
(push (aref vect (mod (+ start var) size)) lst))))
+(defun ring-member (ring item)
+ "Return index of ITEM if on RING, else nil. Comparison via `equal'.
+The index is 0-based."
+ (let ((ind 0)
+ (len (1- (ring-length ring)))
+ (memberp nil))
+ (while (and (<= ind len)
+ (not (setq memberp (equal item (ring-ref ring ind)))))
+ (setq ind (1+ ind)))
+ (and memberp ind)))
+
+(defun ring-next (ring item)
+ "Return the next item in the RING, after ITEM.
+Raise error if ITEM is not in the RING."
+ (let ((curr-index (ring-member ring item)))
+ (unless curr-index (error "Item is not in the ring: `%s'" item))
+ (ring-ref ring (ring-plus1 curr-index (ring-length ring)))))
+
+(defun ring-previous (ring item)
+ "Return the previous item in the RING, before ITEM.
+Raise error if ITEM is not in the RING."
+ (let ((curr-index (ring-member ring item)))
+ (unless curr-index (error "Item is not in the ring: `%s'" item))
+ (ring-ref ring (ring-minus1 curr-index (ring-length ring)))))
+
+(defun ring-insert+extend (ring item &optional grow-p)
+ "Like ring-insert, but if GROW-P is non-nil, then enlarge ring.
+Insert onto ring RING the item ITEM, as the newest (last) item.
+If the ring is full, behavior depends on GROW-P:
+ If GROW-P is non-nil, enlarge the ring to accommodate the new item.
+ If GROW-P is nil, dump the oldest item to make room for the new."
+ (let* ((vec (cdr (cdr ring)))
+ (veclen (length vec))
+ (hd (car ring))
+ (ringlen (ring-length ring)))
+ (prog1
+ (cond ((and grow-p (= ringlen veclen)) ; Full ring. Enlarge it.
+ (setq veclen (1+ veclen))
+ (setcdr ring (cons (setq ringlen (1+ ringlen))
+ (setq vec (vconcat vec (vector item)))))
+ (setcar ring hd))
+ (t (aset vec (mod (+ hd ringlen) veclen) item)))
+ (if (= ringlen veclen)
+ (setcar ring (ring-plus1 hd veclen))
+ (setcar (cdr ring) (1+ ringlen))))))
+
+(defun ring-remove+insert+extend (ring item &optional grow-p)
+ "`ring-remove' ITEM from RING, then `ring-insert+extend' it.
+This ensures that there is only one ITEM on RING.
+
+If the RING is full, behavior depends on GROW-P:
+ If GROW-P is non-nil, enlarge the ring to accommodate the new ITEM.
+ If GROW-P is nil, dump the oldest item to make room for the new."
+ (let (ind)
+ (while (setq ind (ring-member ring item)) (ring-remove ring ind)))
+ (ring-insert+extend ring item grow-p))
+
+(defun ring-convert-sequence-to-ring (seq)
+ "Convert sequence SEQ to a ring. Return the ring.
+If SEQ is already a ring, return it."
+ (if (ring-p seq)
+ seq
+ (let* ((size (length seq))
+ (ring (make-ring size))
+ (count 0))
+ (while (< count size)
+ (if (or (ring-empty-p ring)
+ (not (equal (ring-ref ring 0) (elt seq count))))
+ (ring-insert-at-beginning ring (elt seq count)))
+ (setq count (1+ count)))
+ ring)))
+
;;; provide ourself:
(provide 'ring)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] Changes to emacs/lisp/emacs-lisp/ring.el,v,
Richard M. Stallman <=