From b834553c34f739daffa03dc616b3119995cd1f53 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Tue, 22 Jul 2014 08:58:48 +0900 Subject: [PATCH] rewrite vector-copy in c --- piclib/prelude.scm | 25 --------------------- src/vector.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/piclib/prelude.scm b/piclib/prelude.scm index 2f5f9dae..9c2b568f 100644 --- a/piclib/prelude.scm +++ b/piclib/prelude.scm @@ -700,31 +700,6 @@ (define (vector . objs) (list->vector objs)) -(define (vector-copy! to at from . opts) - (let* ((start (if (pair? opts) (car opts) 0)) - (end (if (>= (length opts) 2) - (cadr opts) - (vector-length from))) - (vs #f)) - (if (eq? from to) - (begin - (set! vs (make-vector (- end start))) - (vector-copy! vs 0 from start end) - (vector-copy! to at vs)) - (do ((i at (+ i 1)) - (j start (+ j 1))) - ((= j end)) - (vector-set! to i (vector-ref from j)))))) - -(define (vector-copy v . opts) - (let ((start (if (pair? opts) (car opts) 0)) - (end (if (>= (length opts) 2) - (cadr opts) - (vector-length v)))) - (let ((res (make-vector (- end start)))) - (vector-copy! res 0 v start end) - res))) - (define (vector-append . vs) (define (vector-append-2-inv w v) (let ((res (make-vector (+ (vector-length v) (vector-length w))))) diff --git a/src/vector.c b/src/vector.c index 1315753f..af9264d1 100644 --- a/src/vector.c +++ b/src/vector.c @@ -119,6 +119,60 @@ pic_vec_vector_set(pic_state *pic) return pic_none_value(); } +static pic_value +pic_vec_vector_copy_i(pic_state *pic) +{ + pic_vec *to, *from; + int n, at, start, end; + + n = pic_get_args(pic, "viv|ii", &to, &at, &from, &start, &end); + + switch (n) { + case 3: + start = 0; + case 4: + end = from->len; + } + + if (to == from && (start <= at && at < end)) { + /* copy in reversed order */ + at += end - start; + while (start < end) { + to->data[--at] = from->data[--end]; + } + return pic_none_value(); + } + + while (start < end) { + to->data[at++] = from->data[start++]; + } + + return pic_none_value(); +} + +static pic_value +pic_vec_vector_copy(pic_state *pic) +{ + pic_vec *vec, *to; + int n, start, end, i = 0; + + n = pic_get_args(pic, "v|ii", &vec, &start, &end); + + switch (n) { + case 1: + start = 0; + case 2: + end = vec->len; + } + + to = pic_vec_new(pic, end - start); + while (start < end) { + to->data[i++] = vec->data[start++]; + } + + return pic_obj_value(to); +} + static pic_value pic_vec_list_to_vector(pic_state *pic) { @@ -169,6 +223,8 @@ pic_init_vector(pic_state *pic) pic_defun(pic, "vector-length", pic_vec_vector_length); pic_defun(pic, "vector-ref", pic_vec_vector_ref); pic_defun(pic, "vector-set!", pic_vec_vector_set); + pic_defun(pic, "vector-copy!", pic_vec_vector_copy_i); + pic_defun(pic, "vector-copy", pic_vec_vector_copy); pic_defun(pic, "list->vector", pic_vec_list_to_vector); pic_defun(pic, "vector->list", pic_vec_vector_to_list); }