srfi-43.scm 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054
  1. ;;; srfi-43.scm -- SRFI 43 Vector library
  2. ;; Copyright (C) 2014, 2018 Free Software Foundation, Inc.
  3. ;;
  4. ;; This library is free software; you can redistribute it and/or
  5. ;; modify it under the terms of the GNU Lesser General Public
  6. ;; License as published by the Free Software Foundation; either
  7. ;; version 3 of the License, or (at your option) any later version.
  8. ;;
  9. ;; This library is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. ;; Lesser General Public License for more details.
  13. ;;
  14. ;; You should have received a copy of the GNU Lesser General Public
  15. ;; License along with this library; if not, write to the Free Software
  16. ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. ;;; Author: Mark H Weaver <mhw@netris.org>
  18. (define-module (srfi srfi-43)
  19. #:use-module (srfi srfi-1)
  20. #:use-module (srfi srfi-8)
  21. #:re-export (make-vector vector vector? vector-ref vector-set!
  22. vector-length vector-fill!)
  23. #:replace (vector-copy list->vector vector->list)
  24. #:export (vector-empty? vector= vector-unfold vector-unfold-right
  25. vector-reverse-copy
  26. vector-append vector-concatenate
  27. vector-fold vector-fold-right
  28. vector-map vector-map!
  29. vector-for-each vector-count
  30. vector-index vector-index-right
  31. vector-skip vector-skip-right
  32. vector-binary-search
  33. vector-any vector-every
  34. vector-swap! vector-reverse!
  35. vector-copy! vector-reverse-copy!
  36. reverse-vector->list
  37. reverse-list->vector))
  38. (cond-expand-provide (current-module) '(srfi-43))
  39. (define-syntax error-from
  40. (lambda (stx)
  41. (syntax-case stx (quote)
  42. ((_ 'who msg arg ...)
  43. #`(error #,(string-append (symbol->string (syntax->datum #'who))
  44. ": "
  45. (syntax->datum #'msg))
  46. arg ...)))))
  47. (define-syntax-rule (assert-nonneg-exact-integer k who)
  48. (unless (and (exact-integer? k)
  49. (not (negative? k)))
  50. (error-from who "expected non-negative exact integer, got" k)))
  51. (define-syntax-rule (assert-procedure f who)
  52. (unless (procedure? f)
  53. (error-from who "expected procedure, got" f)))
  54. (define-syntax-rule (assert-vector v who)
  55. (unless (vector? v)
  56. (error-from who "expected vector, got" v)))
  57. (define-syntax-rule (assert-valid-index i len who)
  58. (unless (and (exact-integer? i)
  59. (<= 0 i len))
  60. (error-from who "invalid index" i)))
  61. (define-syntax-rule (assert-valid-start start len who)
  62. (unless (and (exact-integer? start)
  63. (<= 0 start len))
  64. (error-from who "invalid start index" start)))
  65. (define-syntax-rule (assert-valid-range start end len who)
  66. (unless (and (exact-integer? start)
  67. (exact-integer? end)
  68. (<= 0 start end len))
  69. (error-from who "invalid index range" start end)))
  70. (define-syntax-rule (assert-vectors vs who)
  71. (let loop ((vs vs))
  72. (unless (null? vs)
  73. (assert-vector (car vs) who)
  74. (loop (cdr vs)))))
  75. ;; Return the length of the shortest vector in VS.
  76. ;; VS must have at least one element.
  77. (define (min-length vs)
  78. (let loop ((vs (cdr vs))
  79. (result (vector-length (car vs))))
  80. (if (null? vs)
  81. result
  82. (loop (cdr vs) (min result (vector-length (car vs)))))))
  83. ;; Return a list of the Ith elements of the vectors in VS.
  84. (define (vectors-ref vs i)
  85. (let loop ((vs vs) (xs '()))
  86. (if (null? vs)
  87. (reverse! xs)
  88. (loop (cdr vs) (cons (vector-ref (car vs) i)
  89. xs)))))
  90. (define vector-unfold
  91. (case-lambda
  92. "(vector-unfold f length initial-seed ...) -> vector
  93. The fundamental vector constructor. Create a vector whose length is
  94. LENGTH and iterates across each index k from 0 up to LENGTH - 1,
  95. applying F at each iteration to the current index and current seeds, in
  96. that order, to receive n + 1 values: the element to put in the kth slot
  97. of the new vector, and n new seeds for the next iteration. It is an
  98. error for the number of seeds to vary between iterations."
  99. ((f len)
  100. (assert-procedure f 'vector-unfold)
  101. (assert-nonneg-exact-integer len 'vector-unfold)
  102. (let ((v (make-vector len)))
  103. (let loop ((i 0))
  104. (unless (= i len)
  105. (vector-set! v i (f i))
  106. (loop (+ i 1))))
  107. v))
  108. ((f len seed)
  109. (assert-procedure f 'vector-unfold)
  110. (assert-nonneg-exact-integer len 'vector-unfold)
  111. (let ((v (make-vector len)))
  112. (let loop ((i 0) (seed seed))
  113. (unless (= i len)
  114. (receive (x seed) (f i seed)
  115. (vector-set! v i x)
  116. (loop (+ i 1) seed))))
  117. v))
  118. ((f len seed1 seed2)
  119. (assert-procedure f 'vector-unfold)
  120. (assert-nonneg-exact-integer len 'vector-unfold)
  121. (let ((v (make-vector len)))
  122. (let loop ((i 0) (seed1 seed1) (seed2 seed2))
  123. (unless (= i len)
  124. (receive (x seed1 seed2) (f i seed1 seed2)
  125. (vector-set! v i x)
  126. (loop (+ i 1) seed1 seed2))))
  127. v))
  128. ((f len . seeds)
  129. (assert-procedure f 'vector-unfold)
  130. (assert-nonneg-exact-integer len 'vector-unfold)
  131. (let ((v (make-vector len)))
  132. (let loop ((i 0) (seeds seeds))
  133. (unless (= i len)
  134. (receive (x . seeds) (apply f i seeds)
  135. (vector-set! v i x)
  136. (loop (+ i 1) seeds))))
  137. v))))
  138. (define vector-unfold-right
  139. (case-lambda
  140. "(vector-unfold-right f length initial-seed ...) -> vector
  141. The fundamental vector constructor. Create a vector whose length is
  142. LENGTH and iterates across each index k from LENGTH - 1 down to 0,
  143. applying F at each iteration to the current index and current seeds, in
  144. that order, to receive n + 1 values: the element to put in the kth slot
  145. of the new vector, and n new seeds for the next iteration. It is an
  146. error for the number of seeds to vary between iterations."
  147. ((f len)
  148. (assert-procedure f 'vector-unfold-right)
  149. (assert-nonneg-exact-integer len 'vector-unfold-right)
  150. (let ((v (make-vector len)))
  151. (let loop ((i (- len 1)))
  152. (unless (negative? i)
  153. (vector-set! v i (f i))
  154. (loop (- i 1))))
  155. v))
  156. ((f len seed)
  157. (assert-procedure f 'vector-unfold-right)
  158. (assert-nonneg-exact-integer len 'vector-unfold-right)
  159. (let ((v (make-vector len)))
  160. (let loop ((i (- len 1)) (seed seed))
  161. (unless (negative? i)
  162. (receive (x seed) (f i seed)
  163. (vector-set! v i x)
  164. (loop (- i 1) seed))))
  165. v))
  166. ((f len seed1 seed2)
  167. (assert-procedure f 'vector-unfold-right)
  168. (assert-nonneg-exact-integer len 'vector-unfold-right)
  169. (let ((v (make-vector len)))
  170. (let loop ((i (- len 1)) (seed1 seed1) (seed2 seed2))
  171. (unless (negative? i)
  172. (receive (x seed1 seed2) (f i seed1 seed2)
  173. (vector-set! v i x)
  174. (loop (- i 1) seed1 seed2))))
  175. v))
  176. ((f len . seeds)
  177. (assert-procedure f 'vector-unfold-right)
  178. (assert-nonneg-exact-integer len 'vector-unfold-right)
  179. (let ((v (make-vector len)))
  180. (let loop ((i (- len 1)) (seeds seeds))
  181. (unless (negative? i)
  182. (receive (x . seeds) (apply f i seeds)
  183. (vector-set! v i x)
  184. (loop (- i 1) seeds))))
  185. v))))
  186. (define guile-vector-copy (@ (guile) vector-copy))
  187. ;; TODO: Enhance Guile core 'vector-copy' to do this.
  188. (define vector-copy
  189. (case-lambda*
  190. "(vector-copy vec [start [end [fill]]]) -> vector
  191. Allocate a new vector whose length is END - START and fills it with
  192. elements from vec, taking elements from vec starting at index START
  193. and stopping at index END. START defaults to 0 and END defaults to
  194. the value of (vector-length VEC). If END extends beyond the length of
  195. VEC, the slots in the new vector that obviously cannot be filled by
  196. elements from VEC are filled with FILL, whose default value is
  197. unspecified."
  198. ((v) (guile-vector-copy v))
  199. ((v start)
  200. (assert-vector v 'vector-copy)
  201. (let ((len (vector-length v)))
  202. (assert-valid-start start len 'vector-copy)
  203. (let ((result (make-vector (- len start))))
  204. (vector-move-left! v start len result 0)
  205. result)))
  206. ((v start end #:optional (fill *unspecified*))
  207. (assert-vector v 'vector-copy)
  208. (let ((len (vector-length v)))
  209. (unless (and (exact-integer? start)
  210. (exact-integer? end)
  211. (<= 0 start end))
  212. (error-from 'vector-copy "invalid index range" start end))
  213. (let ((result (make-vector (- end start) fill)))
  214. (vector-move-left! v start (min end len) result 0)
  215. result)))))
  216. (define vector-reverse-copy
  217. (let ()
  218. (define (%vector-reverse-copy vec start end)
  219. (let* ((len (- end start))
  220. (result (make-vector len)))
  221. (let loop ((i 0) (j (- end 1)))
  222. (unless (= i len)
  223. (vector-set! result i (vector-ref vec j))
  224. (loop (+ i 1) (- j 1))))
  225. result))
  226. (case-lambda
  227. "(vector-reverse-copy vec [start [end]]) -> vector
  228. Allocate a new vector whose length is END - START and fills it with
  229. elements from vec, taking elements from vec in reverse order starting
  230. at index START and stopping at index END. START defaults to 0 and END
  231. defaults to the value of (vector-length VEC)."
  232. ((vec)
  233. (assert-vector vec 'vector-reverse-copy)
  234. (%vector-reverse-copy vec 0 (vector-length vec)))
  235. ((vec start)
  236. (assert-vector vec 'vector-reverse-copy)
  237. (let ((len (vector-length vec)))
  238. (assert-valid-start start len 'vector-reverse-copy)
  239. (%vector-reverse-copy vec start len)))
  240. ((vec start end)
  241. (assert-vector vec 'vector-reverse-copy)
  242. (let ((len (vector-length vec)))
  243. (assert-valid-range start end len 'vector-reverse-copy)
  244. (%vector-reverse-copy vec start end))))))
  245. (define (%vector-concatenate vs)
  246. (let* ((result-len (let loop ((vs vs) (len 0))
  247. (if (null? vs)
  248. len
  249. (loop (cdr vs) (+ len (vector-length (car vs)))))))
  250. (result (make-vector result-len)))
  251. (let loop ((vs vs) (pos 0))
  252. (unless (null? vs)
  253. (let* ((v (car vs))
  254. (len (vector-length v)))
  255. (vector-move-left! v 0 len result pos)
  256. (loop (cdr vs) (+ pos len)))))
  257. result))
  258. (define vector-append
  259. (case-lambda
  260. "(vector-append vec ...) -> vector
  261. Return a newly allocated vector that contains all elements in order
  262. from the subsequent locations in VEC ..."
  263. (() (vector))
  264. ((v)
  265. (assert-vector v 'vector-append)
  266. (guile-vector-copy v))
  267. ((v1 v2)
  268. (assert-vector v1 'vector-append)
  269. (assert-vector v2 'vector-append)
  270. (let ((len1 (vector-length v1))
  271. (len2 (vector-length v2)))
  272. (let ((result (make-vector (+ len1 len2))))
  273. (vector-move-left! v1 0 len1 result 0)
  274. (vector-move-left! v2 0 len2 result len1)
  275. result)))
  276. (vs
  277. (assert-vectors vs 'vector-append)
  278. (%vector-concatenate vs))))
  279. (define (vector-concatenate vs)
  280. "(vector-concatenate list-of-vectors) -> vector
  281. Append each vector in LIST-OF-VECTORS. Equivalent to:
  282. (apply vector-append LIST-OF-VECTORS)"
  283. (assert-vectors vs 'vector-concatenate)
  284. (%vector-concatenate vs))
  285. (define (vector-empty? vec)
  286. "(vector-empty? vec) -> boolean
  287. Return true if VEC is empty, i.e. its length is 0, and false if not."
  288. (assert-vector vec 'vector-empty?)
  289. (zero? (vector-length vec)))
  290. (define vector=
  291. (let ()
  292. (define (all-of-length? len vs)
  293. (or (null? vs)
  294. (and (= len (vector-length (car vs)))
  295. (all-of-length? len (cdr vs)))))
  296. (define (=up-to? i elt=? v1 v2)
  297. (or (negative? i)
  298. (let ((x1 (vector-ref v1 i))
  299. (x2 (vector-ref v2 i)))
  300. (and (or (eq? x1 x2) (elt=? x1 x2))
  301. (=up-to? (- i 1) elt=? v1 v2)))))
  302. (case-lambda
  303. "(vector= elt=? vec ...) -> boolean
  304. Return true if the vectors VEC ... have equal lengths and equal
  305. elements according to ELT=?. ELT=? is always applied to two
  306. arguments. Element comparison must be consistent with eq?, in the
  307. following sense: if (eq? a b) returns true, then (elt=? a b) must also
  308. return true. The order in which comparisons are performed is
  309. unspecified."
  310. ((elt=?)
  311. (assert-procedure elt=? 'vector=)
  312. #t)
  313. ((elt=? v)
  314. (assert-procedure elt=? 'vector=)
  315. (assert-vector v 'vector=)
  316. #t)
  317. ((elt=? v1 v2)
  318. (assert-procedure elt=? 'vector=)
  319. (assert-vector v1 'vector=)
  320. (assert-vector v2 'vector=)
  321. (let ((len (vector-length v1)))
  322. (and (= len (vector-length v2))
  323. (=up-to? (- len 1) elt=? v1 v2))))
  324. ((elt=? v1 . vs)
  325. (assert-procedure elt=? 'vector=)
  326. (assert-vector v1 'vector=)
  327. (assert-vectors vs 'vector=)
  328. (let ((len (vector-length v1)))
  329. (and (all-of-length? len vs)
  330. (let loop ((vs vs))
  331. (or (null? vs)
  332. (and (=up-to? (- len 1) elt=? v1 (car vs))
  333. (loop (cdr vs)))))))))))
  334. (define vector-fold
  335. (case-lambda
  336. "(vector-fold kons knil vec1 vec2 ...) -> value
  337. The fundamental vector iterator. KONS is iterated over each index in
  338. all of the vectors, stopping at the end of the shortest; KONS is
  339. applied as (KONS i state (vector-ref VEC1 i) (vector-ref VEC2 i) ...)
  340. where STATE is the current state value, and I is the current index.
  341. The current state value begins with KNIL, and becomes whatever KONS
  342. returned at the respective iteration. The iteration is strictly
  343. left-to-right."
  344. ((kcons knil v)
  345. (assert-procedure kcons 'vector-fold)
  346. (assert-vector v 'vector-fold)
  347. (let ((len (vector-length v)))
  348. (let loop ((i 0) (state knil))
  349. (if (= i len)
  350. state
  351. (loop (+ i 1) (kcons i state (vector-ref v i)))))))
  352. ((kcons knil v1 v2)
  353. (assert-procedure kcons 'vector-fold)
  354. (assert-vector v1 'vector-fold)
  355. (assert-vector v2 'vector-fold)
  356. (let ((len (min (vector-length v1) (vector-length v2))))
  357. (let loop ((i 0) (state knil))
  358. (if (= i len)
  359. state
  360. (loop (+ i 1)
  361. (kcons i state (vector-ref v1 i) (vector-ref v2 i)))))))
  362. ((kcons knil . vs)
  363. (assert-procedure kcons 'vector-fold)
  364. (assert-vectors vs 'vector-fold)
  365. (let ((len (min-length vs)))
  366. (let loop ((i 0) (state knil))
  367. (if (= i len)
  368. state
  369. (loop (+ i 1) (apply kcons i state (vectors-ref vs i)))))))))
  370. (define vector-fold-right
  371. (case-lambda
  372. "(vector-fold-right kons knil vec1 vec2 ...) -> value
  373. The fundamental vector iterator. KONS is iterated over each index in
  374. all of the vectors, starting at the end of the shortest; KONS is
  375. applied as (KONS i state (vector-ref VEC1 i) (vector-ref VEC2 i) ...)
  376. where STATE is the current state value, and I is the current index.
  377. The current state value begins with KNIL, and becomes whatever KONS
  378. returned at the respective iteration. The iteration is strictly
  379. right-to-left."
  380. ((kcons knil v)
  381. (assert-procedure kcons 'vector-fold-right)
  382. (assert-vector v 'vector-fold-right)
  383. (let ((len (vector-length v)))
  384. (let loop ((i (- len 1)) (state knil))
  385. (if (negative? i)
  386. state
  387. (loop (- i 1) (kcons i state (vector-ref v i)))))))
  388. ((kcons knil v1 v2)
  389. (assert-procedure kcons 'vector-fold-right)
  390. (assert-vector v1 'vector-fold-right)
  391. (assert-vector v2 'vector-fold-right)
  392. (let ((len (min (vector-length v1) (vector-length v2))))
  393. (let loop ((i (- len 1)) (state knil))
  394. (if (negative? i)
  395. state
  396. (loop (- i 1)
  397. (kcons i state (vector-ref v1 i) (vector-ref v2 i)))))))
  398. ((kcons knil . vs)
  399. (assert-procedure kcons 'vector-fold-right)
  400. (assert-vectors vs 'vector-fold-right)
  401. (let ((len (min-length vs)))
  402. (let loop ((i (- len 1)) (state knil))
  403. (if (negative? i)
  404. state
  405. (loop (- i 1) (apply kcons i state (vectors-ref vs i)))))))))
  406. (define vector-map
  407. (case-lambda
  408. "(vector-map f vec2 vec2 ...) -> vector
  409. Return a new vector of the shortest size of the vector arguments.
  410. Each element at index i of the new vector is mapped from the old
  411. vectors by (F i (vector-ref VEC1 i) (vector-ref VEC2 i) ...). The
  412. dynamic order of application of F is unspecified."
  413. ((f v)
  414. (assert-procedure f 'vector-map)
  415. (assert-vector v 'vector-map)
  416. (let* ((len (vector-length v))
  417. (result (make-vector len)))
  418. (let loop ((i 0))
  419. (unless (= i len)
  420. (vector-set! result i (f i (vector-ref v i)))
  421. (loop (+ i 1))))
  422. result))
  423. ((f v1 v2)
  424. (assert-procedure f 'vector-map)
  425. (assert-vector v1 'vector-map)
  426. (assert-vector v2 'vector-map)
  427. (let* ((len (min (vector-length v1) (vector-length v2)))
  428. (result (make-vector len)))
  429. (let loop ((i 0))
  430. (unless (= i len)
  431. (vector-set! result i (f i (vector-ref v1 i) (vector-ref v2 i)))
  432. (loop (+ i 1))))
  433. result))
  434. ((f . vs)
  435. (assert-procedure f 'vector-map)
  436. (assert-vectors vs 'vector-map)
  437. (let* ((len (min-length vs))
  438. (result (make-vector len)))
  439. (let loop ((i 0))
  440. (unless (= i len)
  441. (vector-set! result i (apply f i (vectors-ref vs i)))
  442. (loop (+ i 1))))
  443. result))))
  444. (define vector-map!
  445. (case-lambda
  446. "(vector-map! f vec2 vec2 ...) -> unspecified
  447. Similar to vector-map, but rather than mapping the new elements into a
  448. new vector, the new mapped elements are destructively inserted into
  449. VEC1. The dynamic order of application of F is unspecified."
  450. ((f v)
  451. (assert-procedure f 'vector-map!)
  452. (assert-vector v 'vector-map!)
  453. (let ((len (vector-length v)))
  454. (let loop ((i 0))
  455. (unless (= i len)
  456. (vector-set! v i (f i (vector-ref v i)))
  457. (loop (+ i 1))))))
  458. ((f v1 v2)
  459. (assert-procedure f 'vector-map!)
  460. (assert-vector v1 'vector-map!)
  461. (assert-vector v2 'vector-map!)
  462. (let ((len (min (vector-length v1) (vector-length v2))))
  463. (let loop ((i 0))
  464. (unless (= i len)
  465. (vector-set! v1 i (f i (vector-ref v1 i) (vector-ref v2 i)))
  466. (loop (+ i 1))))))
  467. ((f . vs)
  468. (assert-procedure f 'vector-map!)
  469. (assert-vectors vs 'vector-map!)
  470. (let ((len (min-length vs))
  471. (v1 (car vs)))
  472. (let loop ((i 0))
  473. (unless (= i len)
  474. (vector-set! v1 i (apply f i (vectors-ref vs i)))
  475. (loop (+ i 1))))))))
  476. (define vector-for-each
  477. (case-lambda
  478. "(vector-for-each f vec1 vec2 ...) -> unspecified
  479. Call (F i VEC1[i] VEC2[i] ...) for each index i less than the length
  480. of the shortest vector passed. The iteration is strictly
  481. left-to-right."
  482. ((f v)
  483. (assert-procedure f 'vector-for-each)
  484. (assert-vector v 'vector-for-each)
  485. (let ((len (vector-length v)))
  486. (let loop ((i 0))
  487. (unless (= i len)
  488. (f i (vector-ref v i))
  489. (loop (+ i 1))))))
  490. ((f v1 v2)
  491. (assert-procedure f 'vector-for-each)
  492. (assert-vector v1 'vector-for-each)
  493. (assert-vector v2 'vector-for-each)
  494. (let ((len (min (vector-length v1)
  495. (vector-length v2))))
  496. (let loop ((i 0))
  497. (unless (= i len)
  498. (f i (vector-ref v1 i) (vector-ref v2 i))
  499. (loop (+ i 1))))))
  500. ((f . vs)
  501. (assert-procedure f 'vector-for-each)
  502. (assert-vectors vs 'vector-for-each)
  503. (let ((len (min-length vs)))
  504. (let loop ((i 0))
  505. (unless (= i len)
  506. (apply f i (vectors-ref vs i))
  507. (loop (+ i 1))))))))
  508. (define vector-count
  509. (case-lambda
  510. "(vector-count pred? vec1 vec2 ...) -> exact nonnegative integer
  511. Count the number of indices i for which (PRED? VEC1[i] VEC2[i] ...)
  512. returns true, where i is less than the length of the shortest vector
  513. passed."
  514. ((pred? v)
  515. (assert-procedure pred? 'vector-count)
  516. (assert-vector v 'vector-count)
  517. (let ((len (vector-length v)))
  518. (let loop ((i 0) (count 0))
  519. (cond ((= i len) count)
  520. ((pred? i (vector-ref v i))
  521. (loop (+ i 1) (+ count 1)))
  522. (else
  523. (loop (+ i 1) count))))))
  524. ((pred? v1 v2)
  525. (assert-procedure pred? 'vector-count)
  526. (assert-vector v1 'vector-count)
  527. (assert-vector v2 'vector-count)
  528. (let ((len (min (vector-length v1)
  529. (vector-length v2))))
  530. (let loop ((i 0) (count 0))
  531. (cond ((= i len) count)
  532. ((pred? i (vector-ref v1 i) (vector-ref v2 i))
  533. (loop (+ i 1) (+ count 1)))
  534. (else
  535. (loop (+ i 1) count))))))
  536. ((pred? . vs)
  537. (assert-procedure pred? 'vector-count)
  538. (assert-vectors vs 'vector-count)
  539. (let ((len (min-length vs)))
  540. (let loop ((i 0) (count 0))
  541. (cond ((= i len) count)
  542. ((apply pred? i (vectors-ref vs i))
  543. (loop (+ i 1) (+ count 1)))
  544. (else
  545. (loop (+ i 1) count))))))))
  546. (define vector-index
  547. (case-lambda
  548. "(vector-index pred? vec1 vec2 ...) -> exact nonnegative integer or #f
  549. Find and return the index of the first elements in VEC1 VEC2 ... that
  550. satisfy PRED?. If no matching element is found by the end of the
  551. shortest vector, return #f."
  552. ((pred? v)
  553. (assert-procedure pred? 'vector-index)
  554. (assert-vector v 'vector-index)
  555. (let ((len (vector-length v)))
  556. (let loop ((i 0))
  557. (and (< i len)
  558. (if (pred? (vector-ref v i))
  559. i
  560. (loop (+ i 1)))))))
  561. ((pred? v1 v2)
  562. (assert-procedure pred? 'vector-index)
  563. (assert-vector v1 'vector-index)
  564. (assert-vector v2 'vector-index)
  565. (let ((len (min (vector-length v1)
  566. (vector-length v2))))
  567. (let loop ((i 0))
  568. (and (< i len)
  569. (if (pred? (vector-ref v1 i)
  570. (vector-ref v2 i))
  571. i
  572. (loop (+ i 1)))))))
  573. ((pred? . vs)
  574. (assert-procedure pred? 'vector-index)
  575. (assert-vectors vs 'vector-index)
  576. (let ((len (min-length vs)))
  577. (let loop ((i 0))
  578. (and (< i len)
  579. (if (apply pred? (vectors-ref vs i))
  580. i
  581. (loop (+ i 1)))))))))
  582. (define vector-index-right
  583. (case-lambda
  584. "(vector-index-right pred? vec1 vec2 ...) -> exact nonnegative integer or #f
  585. Find and return the index of the last elements in VEC1 VEC2 ... that
  586. satisfy PRED?, searching from right-to-left. If no matching element
  587. is found before the end of the shortest vector, return #f."
  588. ((pred? v)
  589. (assert-procedure pred? 'vector-index-right)
  590. (assert-vector v 'vector-index-right)
  591. (let ((len (vector-length v)))
  592. (let loop ((i (- len 1)))
  593. (and (>= i 0)
  594. (if (pred? (vector-ref v i))
  595. i
  596. (loop (- i 1)))))))
  597. ((pred? v1 v2)
  598. (assert-procedure pred? 'vector-index-right)
  599. (assert-vector v1 'vector-index-right)
  600. (assert-vector v2 'vector-index-right)
  601. (let ((len (min (vector-length v1)
  602. (vector-length v2))))
  603. (let loop ((i (- len 1)))
  604. (and (>= i 0)
  605. (if (pred? (vector-ref v1 i)
  606. (vector-ref v2 i))
  607. i
  608. (loop (- i 1)))))))
  609. ((pred? . vs)
  610. (assert-procedure pred? 'vector-index-right)
  611. (assert-vectors vs 'vector-index-right)
  612. (let ((len (min-length vs)))
  613. (let loop ((i (- len 1)))
  614. (and (>= i 0)
  615. (if (apply pred? (vectors-ref vs i))
  616. i
  617. (loop (- i 1)))))))))
  618. (define vector-skip
  619. (case-lambda
  620. "(vector-skip pred? vec1 vec2 ...) -> exact nonnegative integer or #f
  621. Find and return the index of the first elements in VEC1 VEC2 ... that
  622. do not satisfy PRED?. If no matching element is found by the end of
  623. the shortest vector, return #f."
  624. ((pred? v)
  625. (assert-procedure pred? 'vector-skip)
  626. (assert-vector v 'vector-skip)
  627. (let ((len (vector-length v)))
  628. (let loop ((i 0))
  629. (and (< i len)
  630. (if (pred? (vector-ref v i))
  631. (loop (+ i 1))
  632. i)))))
  633. ((pred? v1 v2)
  634. (assert-procedure pred? 'vector-skip)
  635. (assert-vector v1 'vector-skip)
  636. (assert-vector v2 'vector-skip)
  637. (let ((len (min (vector-length v1)
  638. (vector-length v2))))
  639. (let loop ((i 0))
  640. (and (< i len)
  641. (if (pred? (vector-ref v1 i)
  642. (vector-ref v2 i))
  643. (loop (+ i 1))
  644. i)))))
  645. ((pred? . vs)
  646. (assert-procedure pred? 'vector-skip)
  647. (assert-vectors vs 'vector-skip)
  648. (let ((len (min-length vs)))
  649. (let loop ((i 0))
  650. (and (< i len)
  651. (if (apply pred? (vectors-ref vs i))
  652. (loop (+ i 1))
  653. i)))))))
  654. (define vector-skip-right
  655. (case-lambda
  656. "(vector-skip-right pred? vec1 vec2 ...) -> exact nonnegative integer or #f
  657. Find and return the index of the last elements in VEC1 VEC2 ... that
  658. do not satisfy PRED?, searching from right-to-left. If no matching
  659. element is found before the end of the shortest vector, return #f."
  660. ((pred? v)
  661. (assert-procedure pred? 'vector-skip-right)
  662. (assert-vector v 'vector-skip-right)
  663. (let ((len (vector-length v)))
  664. (let loop ((i (- len 1)))
  665. (and (not (negative? i))
  666. (if (pred? (vector-ref v i))
  667. (loop (- i 1))
  668. i)))))
  669. ((pred? v1 v2)
  670. (assert-procedure pred? 'vector-skip-right)
  671. (assert-vector v1 'vector-skip-right)
  672. (assert-vector v2 'vector-skip-right)
  673. (let ((len (min (vector-length v1)
  674. (vector-length v2))))
  675. (let loop ((i (- len 1)))
  676. (and (not (negative? i))
  677. (if (pred? (vector-ref v1 i)
  678. (vector-ref v2 i))
  679. (loop (- i 1))
  680. i)))))
  681. ((pred? . vs)
  682. (assert-procedure pred? 'vector-skip-right)
  683. (assert-vectors vs 'vector-skip-right)
  684. (let ((len (min-length vs)))
  685. (let loop ((i (- len 1)))
  686. (and (not (negative? i))
  687. (if (apply pred? (vectors-ref vs i))
  688. (loop (- i 1))
  689. i)))))))
  690. (define vector-binary-search
  691. (let ()
  692. (define (%vector-binary-search vec value cmp start end)
  693. (let loop ((lo start) (hi end))
  694. (and (< lo hi)
  695. (let* ((i (quotient (+ lo hi) 2))
  696. (x (vector-ref vec i))
  697. (c (cmp x value)))
  698. (cond ((zero? c) i)
  699. ((positive? c) (loop lo i))
  700. ((negative? c) (loop (+ i 1) hi)))))))
  701. (case-lambda
  702. "(vector-binary-search vec value cmp [start [end]]) -> exact nonnegative integer or #f
  703. Find and return an index of VEC between START and END whose value is
  704. VALUE using a binary search. If no matching element is found, return
  705. #f. The default START is 0 and the default END is the length of VEC.
  706. CMP must be a procedure of two arguments such that (CMP A B) returns
  707. a negative integer if A < B, a positive integer if A > B, or zero if
  708. A = B. The elements of VEC must be sorted in non-decreasing order
  709. according to CMP."
  710. ((vec value cmp)
  711. (assert-vector vec 'vector-binary-search)
  712. (assert-procedure cmp 'vector-binary-search)
  713. (%vector-binary-search vec value cmp 0 (vector-length vec)))
  714. ((vec value cmp start)
  715. (assert-vector vec 'vector-binary-search)
  716. (let ((len (vector-length vec)))
  717. (assert-valid-start start len 'vector-binary-search)
  718. (%vector-binary-search vec value cmp start len)))
  719. ((vec value cmp start end)
  720. (assert-vector vec 'vector-binary-search)
  721. (let ((len (vector-length vec)))
  722. (assert-valid-range start end len 'vector-binary-search)
  723. (%vector-binary-search vec value cmp start end))))))
  724. (define vector-any
  725. (case-lambda
  726. "(vector-any pred? vec1 vec2 ...) -> value or #f
  727. Find the first parallel set of elements from VEC1 VEC2 ... for which
  728. PRED? returns a true value. If such a parallel set of elements
  729. exists, vector-any returns the value that PRED? returned for that set
  730. of elements. The iteration is strictly left-to-right."
  731. ((pred? v)
  732. (assert-procedure pred? 'vector-any)
  733. (assert-vector v 'vector-any)
  734. (let ((len (vector-length v)))
  735. (let loop ((i 0))
  736. (and (< i len)
  737. (or (pred? (vector-ref v i))
  738. (loop (+ i 1)))))))
  739. ((pred? v1 v2)
  740. (assert-procedure pred? 'vector-any)
  741. (assert-vector v1 'vector-any)
  742. (assert-vector v2 'vector-any)
  743. (let ((len (min (vector-length v1)
  744. (vector-length v2))))
  745. (let loop ((i 0))
  746. (and (< i len)
  747. (or (pred? (vector-ref v1 i)
  748. (vector-ref v2 i))
  749. (loop (+ i 1)))))))
  750. ((pred? . vs)
  751. (assert-procedure pred? 'vector-any)
  752. (assert-vectors vs 'vector-any)
  753. (let ((len (min-length vs)))
  754. (let loop ((i 0))
  755. (and (< i len)
  756. (or (apply pred? (vectors-ref vs i))
  757. (loop (+ i 1)))))))))
  758. (define vector-every
  759. (case-lambda
  760. "(vector-every pred? vec1 vec2 ...) -> value or #f
  761. If, for every index i less than the length of the shortest vector
  762. argument, the set of elements VEC1[i] VEC2[i] ... satisfies PRED?,
  763. vector-every returns the value that PRED? returned for the last set of
  764. elements, at the last index of the shortest vector. The iteration is
  765. strictly left-to-right."
  766. ((pred? v)
  767. (assert-procedure pred? 'vector-every)
  768. (assert-vector v 'vector-every)
  769. (let ((len (vector-length v)))
  770. (or (zero? len)
  771. (let loop ((i 0))
  772. (let ((val (pred? (vector-ref v i)))
  773. (next-i (+ i 1)))
  774. (if (or (not val) (= next-i len))
  775. val
  776. (loop next-i)))))))
  777. ((pred? v1 v2)
  778. (assert-procedure pred? 'vector-every)
  779. (assert-vector v1 'vector-every)
  780. (assert-vector v2 'vector-every)
  781. (let ((len (min (vector-length v1)
  782. (vector-length v2))))
  783. (or (zero? len)
  784. (let loop ((i 0))
  785. (let ((val (pred? (vector-ref v1 i)
  786. (vector-ref v2 i)))
  787. (next-i (+ i 1)))
  788. (if (or (not val) (= next-i len))
  789. val
  790. (loop next-i)))))))
  791. ((pred? . vs)
  792. (assert-procedure pred? 'vector-every)
  793. (assert-vectors vs 'vector-every)
  794. (let ((len (min-length vs)))
  795. (or (zero? len)
  796. (let loop ((i 0))
  797. (let ((val (apply pred? (vectors-ref vs i)))
  798. (next-i (+ i 1)))
  799. (if (or (not val) (= next-i len))
  800. val
  801. (loop next-i)))))))))
  802. (define (vector-swap! vec i j)
  803. "(vector-swap! vec i j) -> unspecified
  804. Swap the values of the locations in VEC at I and J."
  805. (assert-vector vec 'vector-swap!)
  806. (let ((len (vector-length vec)))
  807. (assert-valid-index i len 'vector-swap!)
  808. (assert-valid-index j len 'vector-swap!)
  809. (let ((tmp (vector-ref vec i)))
  810. (vector-set! vec i (vector-ref vec j))
  811. (vector-set! vec j tmp))))
  812. (define (%vector-reverse! vec start end)
  813. (let loop ((i start) (j (- end 1)))
  814. (when (< i j)
  815. (let ((tmp (vector-ref vec i)))
  816. (vector-set! vec i (vector-ref vec j))
  817. (vector-set! vec j tmp)
  818. (loop (+ i 1) (- j 1))))))
  819. (define vector-reverse!
  820. (case-lambda
  821. "(vector-reverse! vec [start [end]]) -> unspecified
  822. Destructively reverse the contents of VEC between START and END.
  823. START defaults to 0 and END defaults to the length of VEC."
  824. ((vec)
  825. (assert-vector vec 'vector-reverse!)
  826. (%vector-reverse! vec 0 (vector-length vec)))
  827. ((vec start)
  828. (assert-vector vec 'vector-reverse!)
  829. (let ((len (vector-length vec)))
  830. (assert-valid-start start len 'vector-reverse!)
  831. (%vector-reverse! vec start len)))
  832. ((vec start end)
  833. (assert-vector vec 'vector-reverse!)
  834. (let ((len (vector-length vec)))
  835. (assert-valid-range start end len 'vector-reverse!)
  836. (%vector-reverse! vec start end)))))
  837. (define-syntax-rule (define-vector-copier! copy! docstring inner-proc)
  838. (define copy!
  839. (let ((%copy! inner-proc))
  840. (case-lambda
  841. docstring
  842. ((target tstart source)
  843. (assert-vector target 'copy!)
  844. (assert-vector source 'copy!)
  845. (let ((tlen (vector-length target))
  846. (slen (vector-length source)))
  847. (assert-valid-start tstart tlen 'copy!)
  848. (unless (>= tlen (+ tstart slen))
  849. (error-from 'copy! "would write past end of target"))
  850. (%copy! target tstart source 0 slen)))
  851. ((target tstart source sstart)
  852. (assert-vector target 'copy!)
  853. (assert-vector source 'copy!)
  854. (let ((tlen (vector-length target))
  855. (slen (vector-length source)))
  856. (assert-valid-start tstart tlen 'copy!)
  857. (assert-valid-start sstart slen 'copy!)
  858. (unless (>= tlen (+ tstart (- slen sstart)))
  859. (error-from 'copy! "would write past end of target"))
  860. (%copy! target tstart source sstart slen)))
  861. ((target tstart source sstart send)
  862. (assert-vector target 'copy!)
  863. (assert-vector source 'copy!)
  864. (let ((tlen (vector-length target))
  865. (slen (vector-length source)))
  866. (assert-valid-start tstart tlen 'copy!)
  867. (assert-valid-range sstart send slen 'copy!)
  868. (unless (>= tlen (+ tstart (- send sstart)))
  869. (error-from 'copy! "would write past end of target"))
  870. (%copy! target tstart source sstart send)))))))
  871. (define-vector-copier! vector-copy!
  872. "(vector-copy! target tstart source [sstart [send]]) -> unspecified
  873. Copy a block of elements from SOURCE to TARGET, both of which must be
  874. vectors, starting in TARGET at TSTART and starting in SOURCE at
  875. SSTART, ending when SEND - SSTART elements have been copied. It is an
  876. error for TARGET to have a length less than TSTART + (SEND - SSTART).
  877. SSTART defaults to 0 and SEND defaults to the length of SOURCE."
  878. (lambda (target tstart source sstart send)
  879. (if (< tstart sstart)
  880. (vector-move-left! source sstart send target tstart)
  881. (vector-move-right! source sstart send target tstart))))
  882. (define-vector-copier! vector-reverse-copy!
  883. "(vector-reverse-copy! target tstart source [sstart [send]]) -> unspecified
  884. Like vector-copy!, but copy the elements in the reverse order. It is
  885. an error if TARGET and SOURCE are identical vectors and the TARGET and
  886. SOURCE ranges overlap; however, if TSTART = SSTART,
  887. vector-reverse-copy! behaves as (vector-reverse! TARGET TSTART SEND)
  888. would."
  889. (lambda (target tstart source sstart send)
  890. (if (and (eq? target source) (= tstart sstart))
  891. (%vector-reverse! target sstart send)
  892. (let loop ((i tstart) (j (- send 1)))
  893. (when (>= j sstart)
  894. (vector-set! target i (vector-ref source j))
  895. (loop (+ i 1) (- j 1)))))))
  896. (define vector->list
  897. (let ()
  898. (define (%vector->list vec start end)
  899. (let loop ((i (- end 1))
  900. (result '()))
  901. (if (< i start)
  902. result
  903. (loop (- i 1) (cons (vector-ref vec i) result)))))
  904. (case-lambda
  905. "(vector->list vec [start [end]]) -> proper-list
  906. Return a newly allocated list containing the elements in VEC between
  907. START and END. START defaults to 0 and END defaults to the length of
  908. VEC."
  909. ((vec)
  910. (assert-vector vec 'vector->list)
  911. (%vector->list vec 0 (vector-length vec)))
  912. ((vec start)
  913. (assert-vector vec 'vector->list)
  914. (let ((len (vector-length vec)))
  915. (assert-valid-start start len 'vector->list)
  916. (%vector->list vec start len)))
  917. ((vec start end)
  918. (assert-vector vec 'vector->list)
  919. (let ((len (vector-length vec)))
  920. (assert-valid-range start end len 'vector->list)
  921. (%vector->list vec start end))))))
  922. (define reverse-vector->list
  923. (let ()
  924. (define (%reverse-vector->list vec start end)
  925. (let loop ((i start)
  926. (result '()))
  927. (if (>= i end)
  928. result
  929. (loop (+ i 1) (cons (vector-ref vec i) result)))))
  930. (case-lambda
  931. "(reverse-vector->list vec [start [end]]) -> proper-list
  932. Return a newly allocated list containing the elements in VEC between
  933. START and END in reverse order. START defaults to 0 and END defaults
  934. to the length of VEC."
  935. ((vec)
  936. (assert-vector vec 'reverse-vector->list)
  937. (%reverse-vector->list vec 0 (vector-length vec)))
  938. ((vec start)
  939. (assert-vector vec 'reverse-vector->list)
  940. (let ((len (vector-length vec)))
  941. (assert-valid-start start len 'reverse-vector->list)
  942. (%reverse-vector->list vec start len)))
  943. ((vec start end)
  944. (assert-vector vec 'reverse-vector->list)
  945. (let ((len (vector-length vec)))
  946. (assert-valid-range start end len 'reverse-vector->list)
  947. (%reverse-vector->list vec start end))))))
  948. ;; TODO: change to use 'case-lambda' and improve error checking.
  949. (define* (list->vector lst #:optional (start 0) (end (length lst)))
  950. "(list->vector proper-list [start [end]]) -> vector
  951. Return a newly allocated vector of the elements from PROPER-LIST with
  952. indices between START and END. START defaults to 0 and END defaults
  953. to the length of PROPER-LIST."
  954. (let* ((len (- end start))
  955. (result (make-vector len)))
  956. (let loop ((i 0) (lst (drop lst start)))
  957. (if (= i len)
  958. result
  959. (begin (vector-set! result i (car lst))
  960. (loop (+ i 1) (cdr lst)))))))
  961. ;; TODO: change to use 'case-lambda' and improve error checking.
  962. (define* (reverse-list->vector lst #:optional (start 0) (end (length lst)))
  963. "(reverse-list->vector proper-list [start [end]]) -> vector
  964. Return a newly allocated vector of the elements from PROPER-LIST with
  965. indices between START and END, in reverse order. START defaults to 0
  966. and END defaults to the length of PROPER-LIST."
  967. (let* ((len (- end start))
  968. (result (make-vector len)))
  969. (let loop ((i (- len 1)) (lst (drop lst start)))
  970. (if (negative? i)
  971. result
  972. (begin (vector-set! result i (car lst))
  973. (loop (- i 1) (cdr lst)))))))