Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2018-05-14 08:37:17 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-05-14 09:38:53 +0300
commitc1d737eb95455540e33f090a70645354aa04491f (patch)
tree67863a12bb79f27da7ff1008cb6af45b0e098a0a /source/blender/blenlib
parentb99d064e9142b2e9d790731f4c4c6c107ca43696 (diff)
BLI_utildefines: re-ordering array delete macro
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_utildefines.h49
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)