Blender V4.5
DNA_array_utils.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12
13#include "MEM_guardedalloc.h"
14
15#include "BLI_function_ref.hh"
16#include "BLI_index_range.hh"
17#include "BLI_utildefines.h"
18
20
24template<typename T>
25inline void remove_index(
26 T **items, int *items_num, int *active_index, const int index, void (*destruct_item)(T *))
27{
28 static_assert(std::is_trivial_v<T>);
29 BLI_assert(index >= 0);
30 BLI_assert(index < *items_num);
31
32 const int old_items_num = *items_num;
33 const int new_items_num = old_items_num - 1;
34
35 T *old_items = *items;
36 T *new_items = MEM_calloc_arrayN<T>(new_items_num, __func__);
37
38 std::copy_n(old_items, index, new_items);
39 std::copy_n(old_items + index + 1, old_items_num - index - 1, new_items + index);
40
41 destruct_item(&old_items[index]);
42 MEM_freeN(old_items);
43
44 *items = new_items;
45 *items_num = new_items_num;
46
47 if (active_index) {
48 const int old_active_index = active_index ? *active_index : 0;
49 const int new_active_index = std::max(
50 0, old_active_index == new_items_num ? new_items_num - 1 : old_active_index);
51 *active_index = new_active_index;
52 }
53}
54
59template<typename T>
60inline void remove_if(T **items,
61 int *items_num,
62 FunctionRef<bool(const T &)> predicate,
63 void (*destruct_item)(T *))
64{
65 static_assert(std::is_trivial_v<T>);
66 /* This sorts the items-to-remove to the back. */
67 const int remaining = std::stable_partition(*items,
68 *items + *items_num,
69 [&](const T &value) { return !predicate(value); }) -
70 *items;
71 for (const int i : IndexRange::from_begin_end(remaining, *items_num)) {
72 destruct_item(&(*items)[i]);
73 }
74 *items_num = remaining;
75}
76
80template<typename T>
81inline void clear(T **items, int *items_num, int *active_index, void (*destruct_item)(T *))
82{
83 static_assert(std::is_trivial_v<T>);
84 for (const int i : IndexRange(*items_num)) {
85 destruct_item(&(*items)[i]);
86 }
87 MEM_SAFE_FREE(*items);
88 *items_num = 0;
89 if (active_index) {
90 *active_index = 0;
91 }
92}
93
97template<typename T>
98inline void move_index(T *items, const int items_num, const int from_index, const int to_index)
99{
100 static_assert(std::is_trivial_v<T>);
101 BLI_assert(from_index >= 0);
102 BLI_assert(from_index < items_num);
103 BLI_assert(to_index >= 0);
104 BLI_assert(to_index < items_num);
105 UNUSED_VARS_NDEBUG(items_num);
106
107 if (from_index == to_index) {
108 return;
109 }
110
111 if (from_index < to_index) {
112 const T tmp = items[from_index];
113 for (int i = from_index; i < to_index; i++) {
114 items[i] = items[i + 1];
115 }
116 items[to_index] = tmp;
117 }
118 else if (from_index > to_index) {
119 const T tmp = items[from_index];
120 for (int i = from_index; i > to_index; i--) {
121 items[i] = items[i - 1];
122 }
123 items[to_index] = tmp;
124 }
125}
126
127} // namespace blender::dna::array
#define BLI_assert(a)
Definition BLI_assert.h:46
#define UNUSED_VARS_NDEBUG(...)
Read Guarded memory(de)allocation.
static constexpr IndexRange from_begin_end(const int64_t begin, const int64_t end)
#define MEM_SAFE_FREE(v)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define T
void remove_if(T **items, int *items_num, FunctionRef< bool(const T &)> predicate, void(*destruct_item)(T *))
void remove_index(T **items, int *items_num, int *active_index, const int index, void(*destruct_item)(T *))
void clear(T **items, int *items_num, int *active_index, void(*destruct_item)(T *))
void move_index(T *items, const int items_num, const int from_index, const int to_index)
i
Definition text_draw.cc:230