X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=lisp%2Fgnus-range.el;h=b609074f923316cf6153634a95fb70a413fa602b;hb=9b741e050b400987d68ff761c6cc3276c932839c;hp=43aa8b219c3a8cc2c24c42e58dcffd836dfe7e23;hpb=5577537f351ed1daa999cf9e355a6007103612de;p=elisp%2Fgnus.git- diff --git a/lisp/gnus-range.el b/lisp/gnus-range.el index 43aa8b2..b609074 100644 --- a/lisp/gnus-range.el +++ b/lisp/gnus-range.el @@ -61,6 +61,43 @@ If RANGE is a single range, return (RANGE). Otherwise, return RANGE." (setq list2 (cdr list2))) list1)) +;;;###autoload +(defun gnus-sorted-difference (list1 list2) + "Return a list of elements of LIST1 that do not appear in LIST2. +Both lists have to be sorted over <. +The tail of LIST1 is not copied." + (let (out) + (while (and list1 list2) + (cond ((= (car list1) (car list2)) + (setq list1 (cdr list1) + list2 (cdr list2))) + ((< (car list1) (car list2)) + (setq out (cons (car list1) out)) + (setq list1 (cdr list1))) + (t + (setq list2 (cdr list2))))) + (nconc (nreverse out) list1))) + +;;;###autoload +(defun gnus-sorted-ndifference (list1 list2) + "Return a list of elements of LIST1 that do not appear in LIST2. +Both lists have to be sorted over <. +LIST1 is modified." + (let* ((top (cons nil list1)) + (prev top)) + (while (and list1 list2) + (cond ((= (car list1) (car list2)) + (setcdr prev (cdr list1)) + (setq list1 (cdr list1) + list2 (cdr list2))) + ((< (car list1) (car list2)) + (setq prev list1 + list1 (cdr list1))) + (t + (setq list2 (cdr list2))))) + (cdr top))) + +;;;###autoload (defun gnus-sorted-complement (list1 list2) "Return a list of elements that are in LIST1 or LIST2 but not both. Both lists have to be sorted over <." @@ -79,6 +116,7 @@ Both lists have to be sorted over <." (setq list2 (cdr list2))))) (nconc (nreverse out) (or list1 list2))))) +;;;###autoload (defun gnus-intersection (list1 list2) (let ((result nil)) (while list2 @@ -87,6 +125,7 @@ Both lists have to be sorted over <." (setq list2 (cdr list2))) result)) +;;;###autoload (defun gnus-sorted-intersection (list1 list2) "Return intersection of LIST1 and LIST2. LIST1 and LIST2 have to be sorted over <." @@ -102,7 +141,11 @@ LIST1 and LIST2 have to be sorted over <." (setq list2 (cdr list2))))) (nreverse out))) -(defun gnus-set-sorted-intersection (list1 list2) +;;;###autoload +(defalias 'gnus-set-sorted-intersection 'gnus-sorted-nintersection) + +;;;###autoload +(defun gnus-sorted-nintersection (list1 list2) "Return intersection of LIST1 and LIST2 by modifying cdr pointers of LIST1. LIST1 and LIST2 have to be sorted over <." (let* ((top (cons nil list1)) @@ -120,6 +163,7 @@ LIST1 and LIST2 have to be sorted over <." (setcdr prev nil) (cdr top))) +;;;###autoload (defun gnus-sorted-union (list1 list2) "Return union of LIST1 and LIST2. LIST1 and LIST2 have to be sorted over <." @@ -143,7 +187,8 @@ LIST1 and LIST2 have to be sorted over <." list2 (cdr list2))) (nreverse out))) -(defun gnus-set-sorted-union (list1 list2) +;;;###autoload +(defun gnus-sorted-nunion (list1 list2) "Return union of LIST1 and LIST2 by modifying cdr pointers of LIST1. LIST1 and LIST2 have to be sorted over <." (let* ((top (cons nil list1)) @@ -388,11 +433,13 @@ LIST is a sorted list." (if (numberp (car ranges)) (= (car ranges) number) ;; (caar ranges) <= number <= (cdar ranges) - (>= number (caar ranges)))) + (>= number (caar ranges)))) (push number result))) (nreverse result))) -(defun gnus-inverse-list-range-intersection (list ranges) +(defalias 'gnus-inverse-list-range-intersection 'gnus-list-range-difference) + +(defun gnus-list-range-difference (list ranges) "Return a list of numbers in LIST that are not members of RANGES. LIST is a sorted list." (setq ranges (gnus-range-normalize ranges)) @@ -413,7 +460,16 @@ LIST is a sorted list." (defun gnus-range-length (range) "Return the length RANGE would have if uncompressed." - (length (gnus-uncompress-range range))) + (cond + ((null range) + 0) + ((not (listp (cdr range))) + (- (cdr range) (car range) -1)) + (t + (let ((sum 0)) + (dolist (x range sum) + (setq sum + (+ sum (if (consp x) (- (cdr x) (car x) -1) 1)))))))) (defun gnus-sublist-p (list sublist) "Test whether all elements in SUBLIST are members of LIST." @@ -479,6 +535,18 @@ LIST is a sorted list." (if item (push item range)) (reverse range))) +;;;###autoload +(defun gnus-add-to-sorted-list (list num) + "Add NUM into sorted LIST by side effect." + (let* ((top (cons nil list)) + (prev top)) + (while (and list (< (car list) num)) + (setq prev list + list (cdr list))) + (unless (eq (car list) num) + (setcdr prev (cons num list))) + (cdr top))) + (provide 'gnus-range) ;;; gnus-range.el ends here