X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Falgorithm.c;h=ca427a0d49549acf11e8ce099ee1072a1793853d;hb=dbb0228a4c98cbf4756ba651fda158c1565b3b55;hp=209b0b0f63cce3e3c256adf8f4ef9293ac0fdd1a;hpb=4fdeb2145d081ff1b84e3f6c99f9d1c048c0d64a;p=pspp diff --git a/src/algorithm.c b/src/algorithm.c index 209b0b0f63..ca427a0d49 100644 --- a/src/algorithm.c +++ b/src/algorithm.c @@ -393,6 +393,36 @@ remove_element (void *array, size_t count, size_t size, remove_range (array, count, size, idx, 1); } +/* Moves an element in ARRAY, which consists of COUNT elements of + SIZE bytes each, from OLD_IDX to NEW_IDX, shifting around + other elements as needed. Runs in O(abs(OLD_IDX - NEW_IDX)) + time. */ +void +move_element (void *array_, size_t count, size_t size, + size_t old_idx, size_t new_idx) +{ + assert (array_ != NULL || count == 0); + assert (old_idx < count); + assert (new_idx < count); + + if (old_idx != new_idx) + { + char *array = array_; + char *element = xmalloc (size); + char *new = array + new_idx * size; + char *old = array + old_idx * size; + + memcpy (element, old, size); + if (new < old) + memmove (new + size, new, (old_idx - new_idx) * size); + else + memmove (old, old + size, (new_idx - old_idx) * size); + memcpy (new, element, size); + + free (element); + } +} + /* A predicate and its auxiliary data. */ struct pred_aux {