branch: externals/stream commit bd614d022b043397e7294a5083e4dcf3f805e089 Author: Earl Hyatt <oka...@protonmail.com> Commit: Stefan Monnier <monn...@iro.umontreal.ca>
Add more efficient method for making streams from arrays. * stream.el (stream): Add method for arrays that avoids creating sub-sequences. * tests/stream-tests.el (stream-array-test): Add test for new method. --- stream.el | 18 ++++++++++++++++++ tests/stream-tests.el | 4 ++++ 2 files changed, 22 insertions(+) diff --git a/stream.el b/stream.el index 2439f958cb..300f3b8ae2 100644 --- a/stream.el +++ b/stream.el @@ -173,6 +173,24 @@ SEQ can be a list, vector or string." (seq-elt seq 0) (stream (seq-subseq seq 1))))) +(cl-defmethod stream ((array array)) + "Return a stream built from the array ARRAY." + (let ((len (length array))) + (if (= len 0) + (stream-empty) + ;; This approach could avoid one level of indirection by setting + ;; `stream--updater' directly, but using `funcall' makes for a + ;; good example of how to use a custom updater function using the public + ;; interface. + (let ((idx 0)) + (cl-labels ((updater () + (if (< idx len) + (prog1 (cons (aref array idx) + (stream-make (funcall #'updater))) + (setq idx (1+ idx))) + nil))) + (stream-make (funcall #'updater))))))) + (cl-defmethod stream ((list list)) "Return a stream built from the list LIST." (if (null list) diff --git a/tests/stream-tests.el b/tests/stream-tests.el index ba304f1ee4..997dd8607b 100644 --- a/tests/stream-tests.el +++ b/tests/stream-tests.el @@ -234,6 +234,10 @@ (dolist (list '(nil '(1 2 3) '(a . b))) (should (equal list (seq-into (stream list) 'list))))) +(ert-deftest stream-array-test () + (dolist (arr (list "cat" [0 1 2])) + (should (equal arr (seq-into (stream arr) (type-of arr)))))) + (ert-deftest stream-seq-subseq-test () (should (stream-empty-p (seq-subseq (stream-range 2 10) 0 0))) (should (= (stream-first (seq-subseq (stream-range 2 10) 0 3)) 2))