diff options
Diffstat (limited to 'source/blender/blenlib/intern/array_utils.c')
-rw-r--r-- | source/blender/blenlib/intern/array_utils.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/source/blender/blenlib/intern/array_utils.c b/source/blender/blenlib/intern/array_utils.c index 173effbc434..6c5dc5a7f1e 100644 --- a/source/blender/blenlib/intern/array_utils.c +++ b/source/blender/blenlib/intern/array_utils.c @@ -25,23 +25,28 @@ #include <string.h> #include <stdlib.h> +#include "MEM_guardedalloc.h" + #include "BLI_array_utils.h" #include "BLI_sys_types.h" #include "BLI_utildefines.h" #include "BLI_alloca.h" +#include "BLI_strict_flags.h" + void _bli_array_reverse(void *arr_v, unsigned int arr_len, size_t arr_stride) { - const unsigned int arr_half_stride = (arr_len / 2) * arr_stride; + const unsigned int arr_stride_uint = (unsigned int)arr_stride; + const unsigned int arr_half_stride = (arr_len / 2) * arr_stride_uint; unsigned int i, i_end; char *arr = arr_v; char *buf = BLI_array_alloca(buf, arr_stride); - for (i = 0, i_end = (arr_len - 1) * arr_stride; + for (i = 0, i_end = (arr_len - 1) * arr_stride_uint; i < arr_half_stride; - i += arr_stride, i_end -= arr_stride) + i += arr_stride_uint, i_end -= arr_stride_uint) { memcpy(buf, &arr[i], arr_stride); memcpy(&arr[i], &arr[i_end], arr_stride); @@ -69,6 +74,36 @@ void _bli_array_wrap(void *arr_v, unsigned int arr_len, size_t arr_stride, int d } } +void _bli_array_permute( + void *arr_v, const unsigned int arr_len, const size_t arr_stride, + const unsigned int *order, void *arr_temp) +{ + const size_t len = arr_len * arr_stride; + const unsigned int arr_stride_uint = (unsigned int)arr_stride; + void *arr_orig; + unsigned int i; + + if (arr_temp == NULL) { + arr_orig = MEM_mallocN(len, __func__); + } + else { + arr_orig = arr_temp; + } + + memcpy(arr_orig, arr_v, len); + + for (i = 0; i < arr_len; i++) { + BLI_assert(order[i] < arr_len); + memcpy(POINTER_OFFSET(arr_v, arr_stride_uint * i), + POINTER_OFFSET(arr_orig, arr_stride_uint * order[i]), + arr_stride); + } + + if (arr_temp == NULL) { + MEM_freeN(arr_orig); + } +} + /** * \note Not efficient, use for error checks/asserts. */ |