From d08af71f38b751323cc9506631bf9ce71070a4ae Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 4 Jun 2007 01:19:03 +0000 Subject: [PATCH] (move_range): New function. --- src/libpspp/ChangeLog | 1 + src/libpspp/array.c | 30 ++++++++++++++++++++++++++++++ src/libpspp/array.h | 6 ++++++ 3 files changed, 37 insertions(+) diff --git a/src/libpspp/ChangeLog b/src/libpspp/ChangeLog index fa02a8b9..acdad231 100644 --- a/src/libpspp/ChangeLog +++ b/src/libpspp/ChangeLog @@ -2,6 +2,7 @@ * array.c (insert_range): New function. (insert_element): New function. + (move_range): New function. 2007-04-25 Ben Pfaff diff --git a/src/libpspp/array.c b/src/libpspp/array.c index 8af5d8fe..f375f83d 100644 --- a/src/libpspp/array.c +++ b/src/libpspp/array.c @@ -415,6 +415,36 @@ move_element (void *array_, size_t count, size_t size, } } +/* Moves N elements in ARRAY starting at OLD_IDX, which consists + of COUNT elements of SIZE bytes each, so that they now start + at NEW_IDX, shifting around other elements as needed. */ +void +move_range (void *array_, size_t count, size_t size, + size_t old_idx, size_t new_idx, size_t n) +{ + assert (array_ != NULL || count == 0); + assert (n <= count); + assert (old_idx + n <= count); + assert (new_idx + n <= count); + + if (old_idx != new_idx && n > 0) + { + char *array = array_; + char *range = xmalloc (size * n); + char *new = array + new_idx * size; + char *old = array + old_idx * size; + + memcpy (range, old, size * n); + if (new < old) + memmove (new + size * n, new, (old_idx - new_idx) * size); + else + memmove (old, old + size * n, (new_idx - old_idx) * size); + memcpy (new, range, size * n); + + free (range); + } +} + /* A predicate and its auxiliary data. */ struct pred_aux { diff --git a/src/libpspp/array.h b/src/libpspp/array.h index 3cfb245a..a867adea 100644 --- a/src/libpspp/array.h +++ b/src/libpspp/array.h @@ -129,6 +129,12 @@ void insert_element (void *array, size_t count, size_t size, void move_element (void *array, size_t count, size_t size, size_t old_idx, size_t new_idx); +/* Moves N elements in ARRAY starting at OLD_IDX, which consists + of COUNT elements of SIZE bytes each, so that they now start + at NEW_IDX, shifting around other elements as needed. */ +void move_range (void *array, size_t count, size_t size, + size_t old_idx, size_t new_idx, size_t n); + /* Removes elements equal to ELEMENT from ARRAY, which consists of COUNT elements of SIZE bytes each. Returns the number of remaining elements. AUX is passed to COMPARE as auxiliary -- 2.30.2