
;; ----------------------------------------------------------------------
;;  SRFI 133 ...
;; ----------------------------------------------------------------------

;; vectors/basics

(define v (make-vector 3 3))

(test "vectors/basics 1" #t (vector? #(1 2 3)))
(test "vectors/basics 2" #t (vector? (make-vector 10)))
(test "vectors/basics 3" 3 (vector-ref v 0))
(test "vectors/basics 4" 3 (vector-ref v 1))
(test "vectors/basics 5" 3 (vector-ref v 2))
(test/error "vectors/basics 6" (vector-ref v -1))
(test/error "vectors/basics 7" (vector-ref v 3))
(vector-set! v 0 -32)
(test "vectors/basics 8" -32 (vector-ref v 0))
(test "vectors/basics 9" 3 (vector-length v))
(test "vectors/basics 10" 0 (vector-length '#()))

;; "vectors/constructors"
(define a2i '#(a b c d e f g h i))
(test "vectors/constructors 1" '#(0 1 2 3 4) (vector 0 1 2 3 4))
(test "vectors/constructors 2" '#(0 -1 -2 -3 -4 -5 -6 -7 -8 -9)
      (vector-unfold (lambda (i x) (values x (- x 1))) 10 0))
(test "vectors/constructors 3" '#(0 1 2 3 4 5 6) (vector-unfold values 7))
(test "vectors/constructors 4" '#((0 . 4) (1 . 3) (2 . 2) (3 . 1) (4 . 0))
      (vector-unfold-right (lambda (i x) (values (cons i x) (+ x 1))) 5 0))
(test "vectors/constructors 5" a2i (vector-copy a2i))
(test "vectors/constructors 6" #t (not (eqv? a2i (vector-copy a2i))))
(test "vectors/constructors 7" '#(g h i) (vector-copy a2i 6))
(test "vectors/constructors 8" '#(d e f) (vector-copy a2i 3 6))
(test "vectors/constructors 9" '#(1 2 3 4) (vector-reverse-copy '#(5 4 3 2 1 0) 1 5))
(test "vectors/constructors 10" '#(x y) (vector-append '#(x) '#(y)))
(test "vectors/constructors 11" '#(a b c d) (vector-append '#(a) '#(b c d)))
(test "vectors/constructors 12" '#(a #(b) #(c)) (vector-append '#(a #(b)) '#(#(c))))
(test "vectors/constructors 13" '#(a b c d) (vector-concatenate '(#(a b) #(c d))))
(test "vectors/constructors 14" '#(a b h i) (vector-append-subvectors '#(a b c d e) 0 2 '#(f g h i j) 2 4))

;; vectors/predicates
(test "vectors/predicates 1" #f (vector-empty? '#(a)))
(test "vectors/predicates 2" #f (vector-empty? '#(())))
(test "vectors/predicates 3" #f (vector-empty? '#(#())))
(test "vectors/predicates 4" #t (vector-empty? '#()))
(test "vectors/predicates 5" #t (vector= eq? '#(a b c d) '#(a b c d)))
(test "vectors/predicates 6" #f (vector= eq? '#(a b c d) '#(a b d c)))
(test "vectors/predicates 7" #f (vector= = '#(1 2 3 4 5) '#(1 2 3 4)))
;;;(test "vectors/predicates 8" #f (vector= = '#(+nan.0) '#(+nan.0)))
;;;(test "vectors/predicates 9" #f (let ((nan '+nan.0)) (vector= = (vector nan) (vector nan))))
;;;(test "vectors/predicates 10" #f (let ((nanvec '#(+nan.0))) (vector= = nanvec nanvec)))
(test "vectors/predicates 11" #t (vector= eq?))
(test "vectors/predicates 12" #t (vector= eq? '#(a)))
(test "vectors/predicates 13" #f (vector= eq? (vector (vector 'a)) (vector (vector 'a))))
(test "vectors/predicates 14" #t (vector= equal? (vector (vector 'a)) (vector (vector 'a))))

;; "vectors/iteration"
(define vos '#("abc" "abcde" "abcd"))
(define vec '#(0 1 2 3 4 5))
(define vec2 (vector 0 1 2 3 4))
(define vec3 (vector 1 2 3 4 5))
(define res '())
(define (sqr x) (* x x))
(test "vectors/iteration 1" 5 (vector-fold (lambda (len str) (max (string-length str) len))
                     0 vos))
(test "vectors/iteration 2" '(5 4 3 2 1 0)
      (vector-fold (lambda (tail elt) (cons elt tail)) '() vec))
(test "vectors/iteration 3" 3 (vector-fold (lambda (ctr n) (if (even? n) (+ ctr 1) ctr)) 0 vec))
(test "vectors/iteration "'(a b c d) (vector-fold-right (lambda (tail elt) (cons elt tail))
                                    '() '#(a b c d)))
(test "vectors/iteration 4" '#(1 4 9 16) (vector-map sqr '#(1 2 3 4)))
(test "vectors/iteration 5" '#(5 8 9 8 5) (vector-map * '#(1 2 3 4 5) '#(5 4 3 2 1)))
(vector-map! sqr vec2)
(test "vectors/iteration 6" '#(0 1 4 9 16) (vector-copy vec2))
(vector-map! * vec2 vec3)
(test "vectors/iteration 7" '#(0 2 12 36 80) (vector-copy vec2))
(vector-for-each (lambda (x) (set! res (cons x res))) vec)
(test "vectors/iteration 8" '(5 4 3 2 1 0) (cons (car res) (cdr res)))
(test "vectors/iteration 9" 3 (vector-count even? '#(3 1 4 1 5 9 2 5 6)))
(test "vectors/iteration 10" 2 (vector-count < '#(1 3 6 9) '#(2 4 6 8 10 12)))
(test "vectors/iteration 11" '#(3 4 8 9 14 23 25 30 36) (vector-cumulate + 0 '#(3 1 4 1 5 9 2 5 6)))


;; "vectors/searching"
(define (cmp a b)
  (cond
   ((< a b) -1)
   ((= a b) 0)
   (else 1)))
(define v '#(0 2 4 6 8 10 12))

(test "vectors/searching 1" 2 (vector-index even? '#(3 1 4 1 5 9 6)))
(test "vectors/searching 2" 1 (vector-index < '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2)))
(test "vectors/searching 3" #f (vector-index = '#(3 1 4 1 5 9 2 5 6) '#(2 7 1 8 2)))
(test "vectors/searching 4" 5 (vector-index-right odd? '#(3 1 4 1 5 9 6)))
(test "vectors/searching 5" 3 (vector-index-right < '#(3 1 4 1 5) '#(2 7 1 8 2)))
(test "vectors/searching 6" 2 (vector-skip number? '#(1 2 a b 3 4 c d)))
(test "vectors/searching 7" 2 (vector-skip = '#(1 2 3 4 5) '#(1 2 -3 4)))
(test "vectors/searching 8" 7 (vector-skip-right number? '#(1 2 a b 3 4 c d)))
(test "vectors/searching 9" 3 (vector-skip-right = '#(1 2 3 4 5) '#(1 2 -3 -4 5)))
(test "vectors/searching 10" 0 (vector-binary-search v 0 cmp))
(test "vectors/searching 11" 3 (vector-binary-search v 6 cmp))
(test "vectors/searching 12" #f (vector-binary-search v 1 cmp))
(test "vectors/searching 13" #t (vector-any number? '#(1 2 x y z)))
(test "vectors/searching 14" #t (vector-any < '#(1 2 3 4 5) '#(2 1 3 4 5)))
(test "vectors/searching 15" #f (vector-any number? '#(a b c d e)))
(test "vectors/searching 16" #f (vector-any > '#(1 2 3 4 5) '#(1 2 3 4 5)))
(test "vectors/searching 17" #f (vector-every number? '#(1 2 x y z)))
(test "vectors/searching 18" #t (vector-every number? '#(1 2 3 4 5)))
(test "vectors/searching 19" #f (vector-every < '#(1 2 3) '#(2 3 3)))
(test "vectors/searching 20" #t (vector-every < '#(1 2 3) '#(2 3 4)))
(test "vectors/searching 21" 'yes (vector-any (lambda (x) (if (number? x) 'yes #f)) '#(1 2 x y z)))
(let-values (((new off) (vector-partition number? '#(1 x 2 y 3 z))))
  (test "vectors/searching 22" '#(1 2 3 x y z) (vector-copy new))
  (test "vectors/searching 23" 3 (+ off 0)))
  

;; "vectors/mutation"
(define vs (vector 1 2 3))
(define vf0 (vector 1 2 3))
(define vf1 (vector 1 2 3))
(define vf2 (vector 1 2 3))
(define vr0 (vector 1 2 3))
(define vr1 (vector 1 2 3))
(define vr2 (vector 1 2 3))
(define vc0 (vector 1 2 3 4 5))
(define vc1 (vector 1 2 3 4 5))
(define vc2 (vector 1 2 3 4 5))
(define vrc0 (vector 1 2 3 4 5))
(define vrc1 (vector 1 2 3 4 5))
(define vrc2 (vector 1 2 3 4 5))
(define vu0 (vector 1 2 3 4 5))
(define vu1 (vector 1 2 3 4 5))
(define vu2 (vector 1 2 3 4 5))
(define vur0 (vector 1 2 3 4 5))
(define vur1 (vector 1 2 3 4 5))
(define vur2 (vector 1 2 3 4 5))
(vector-swap! vs 0 1)
(test "vectors/mutation 1" '#(2 1 3) (vector-copy vs))
(vector-fill! vf0 0)
(test "vectors/mutation 2" '#(0 0 0) (vector-copy vf0))
(vector-fill! vf1 0 1)
(test "vectors/mutation 3" '#(1 0 0) (vector-copy vf1))
(vector-fill! vf2 0 0 1)
(test "vectors/mutation 4" '#(0 2 3) (vector-copy vf2))
(vector-reverse! vr0)
(test "vectors/mutation 5" '#(3 2 1) (vector-copy vr0))
(vector-reverse! vr1 1)
(test "vectors/mutation 6" '#(1 3 2) (vector-copy vr1))
(vector-reverse! vr2 0 2)
(test "vectors/mutation 7" '#(2 1 3) (vector-copy vr2))
(vector-copy! vc0 1 '#(10 20 30))
(test "vectors/mutation 8" '#(1 10 20 30 5) (vector-copy vc0))
(vector-copy! vc1 1 '#(0 10 20 30 40) 1)
(test "vectors/mutation 9" '#(1 10 20 30 40) (vector-copy vc1))
(vector-copy! vc2 1 '#(0 10 20 30 40) 1 4)
(test "vectors/mutation 10" '#(1 10 20 30 5) (vector-copy vc2))
(vector-reverse-copy! vrc0 1 '#(10 20 30))
(test "vectors/mutation 11" '#(1 30 20 10 5) (vector-copy vrc0))
(vector-reverse-copy! vrc1 1 '#(0 10 20 30 40) 1)
(test "vectors/mutation 12" '#(1 40 30 20 10) (vector-copy vrc1))
(vector-reverse-copy! vrc2 1 '#(0 10 20 30 40) 1 4)
(test "vectors/mutation 13" '#(1 30 20 10 5) (vector-copy vrc2))
(vector-unfold! (lambda (i) (+ 10 i)) vu0 1 4)
(test "vectors/mutation 14" '#(1 11 12 13 5) (vector-copy vu0))
(vector-unfold! (lambda (i x) (values (+ i x) (+ x 1))) vu1 1 4 0)
(test "vectors/mutation 15" '#(1 1 3 5 5) (vector-copy vu1))
(vector-unfold! (lambda (i x y) (values (+ i x y) (+ x 1) (+ x 1))) vu2 1 4 0 0)
(test "vectors/mutation 16" '#(1 1 4 7 5) (vector-copy vu2))
(vector-unfold-right! (lambda (i) (+ 10 i)) vur0 1 4)
(test "vectors/mutation 17" '#(1 11 12 13 5) (vector-copy vur0))
(vector-unfold-right! (lambda (i x) (values (+ i x) (+ x 1))) vur1 1 4 0)
(test "vectors/mutation 18" '#(1 3 3 3 5) (vector-copy vur1))
(vector-unfold-right! (lambda (i x y) (values (+ i x y) (+ x 1) (+ x 1))) vur2 1 4 0 0)
(test "vectors/mutation 19" '#(1 5 4 3 5) (vector-copy vur2))


;;;
;;; Extra tests
;;;

;; From Shiro Kawai, test for SRFI 43 (which is actually valid for
;; SRFI 133):

(test "vector-reverse-copy! self0"
       '#(e d c b a)
       (let ((v (vector 'a 'b 'c 'd 'e)))
         (vector-reverse-copy! v 0 v)
         v))

(test "vector-reverse-copy! self1"
      '#(b a c d e)
      (let ((v (vector 'a 'b 'c 'd 'e)))
        (vector-reverse-copy! v 0 v 0 2)
        v))
