diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-05-14 09:41:15 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-05-14 09:41:15 +0300 |
commit | 66f0c10f844d5830b14c7dd2d1469edceb04f2aa (patch) | |
tree | a2c69bac012a608cd2c532e250d031dfcec576fa /source/blender | |
parent | a0c564f86aafd17f1614620dbe918898635a1e35 (diff) | |
parent | c1d737eb95455540e33f090a70645354aa04491f (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenlib/BLI_utildefines.h | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 65dcbf04913..5af97ebb411 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -373,19 +373,48 @@ extern "C" { #define UNPACK4_EX(pre, a, post) UNPACK3_EX(pre, a, post), (pre((a)[3])post) /* array helpers */ -#define ARRAY_LAST_ITEM(arr_start, arr_dtype, tot) \ - (arr_dtype *)((char *)(arr_start) + (sizeof(*((arr_dtype *)NULL)) * (size_t)(tot - 1))) +#define ARRAY_LAST_ITEM(arr_start, arr_dtype, arr_len) \ + (arr_dtype *)((char *)(arr_start) + (sizeof(*((arr_dtype *)NULL)) * (size_t)(arr_len - 1))) -#define ARRAY_HAS_ITEM(arr_item, arr_start, tot) ( \ +#define ARRAY_HAS_ITEM(arr_item, arr_start, arr_len) ( \ CHECK_TYPE_PAIR_INLINE(arr_start, arr_item), \ - ((unsigned int)((arr_item) - (arr_start)) < (unsigned int)(tot))) + ((unsigned int)((arr_item) - (arr_start)) < (unsigned int)(arr_len))) + +/** + * \note use faster #ARRAY_DELETE_REORDER_LAST when we can re-order. + */ +#define ARRAY_DELETE(arr, index, delete_len, arr_len) \ + { \ + BLI_assert(((index) >= 0) && ((index) + delete_len <= arr_len)); \ + memmove(&(arr)[index], \ + &(arr)[(index) + (delete_len)], \ + (((arr_len) - (index)) - (delete_len)) * sizeof(*(arr))); \ + } ((void)0) + +/** + * Re-ordering array removal. + * + * When removing single items this compiles down to: + * `if (index + 1 != arr_len) { arr[index] = arr[arr_len - 1]; }` (typical reordering removal), + * with removing multiple items, overlap is detected to avoid memcpy errors. + */ +#define ARRAY_DELETE_REORDER_LAST(arr, index, delete_len, arr_len) \ + { \ + BLI_assert(((index) >= 0) && ((index) + delete_len <= arr_len)); \ + if ((index) + (delete_len) != (arr_len)) { \ + if (((delete_len) == 1) || ((delete_len) <= ((arr_len) - ((index) + (delete_len))))) { \ + memcpy(&(arr)[index], \ + &(arr)[(arr_len) - (delete_len)], \ + (delete_len) * sizeof(*(arr))); \ + } \ + else { \ + memcpy(&(arr)[index], \ + &(arr)[(arr_len) - ((arr_len) - ((index) + (delete_len)))], \ + ((arr_len) - ((index) + (delete_len))) * sizeof(*(arr))); \ + } \ + } \ + } ((void)0) -#define ARRAY_DELETE(arr, index, tot_delete, tot) { \ - BLI_assert(index + tot_delete <= tot); \ - memmove(&(arr)[(index)], \ - &(arr)[(index) + (tot_delete)], \ - (((tot) - (index)) - (tot_delete)) * sizeof(*(arr))); \ - } (void)0 /* assuming a static array */ #if defined(__GNUC__) && !defined(__cplusplus) && !defined(__clang__) && !defined(__INTEL_COMPILER) |