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:
Diffstat (limited to 'source/blender/blenlib/intern/stack.c')
-rw-r--r--source/blender/blenlib/intern/stack.c78
1 files changed, 76 insertions, 2 deletions
diff --git a/source/blender/blenlib/intern/stack.c b/source/blender/blenlib/intern/stack.c
index 2d3a2f77a3e..084d692fcf0 100644
--- a/source/blender/blenlib/intern/stack.c
+++ b/source/blender/blenlib/intern/stack.c
@@ -125,8 +125,10 @@ void BLI_stack_free(BLI_Stack *stack)
}
/**
- * Copies the source value onto the stack (note that it copies
- * elem_size bytes from 'src', the pointer itself is not stored)
+ * Push a new item onto the stack.
+ *
+ * \return a pointer #BLI_Stack.elem_size
+ * bytes of uninitialized memory (caller must fill in).
*/
void *BLI_stack_push_r(BLI_Stack *stack)
{
@@ -158,6 +160,14 @@ void *BLI_stack_push_r(BLI_Stack *stack)
return CHUNK_LAST_ELEM(stack);
}
+/**
+ * Copies the source value onto the stack
+ *
+ * \note This copies #BLI_Stack.elem_size bytes from \a src,
+ * (the pointer itself is not stored).
+ *
+ * \param src: source data to be copied to the stack.
+ */
void BLI_stack_push(BLI_Stack *stack, const void *src)
{
void *dst = BLI_stack_push_r(stack);
@@ -179,6 +189,15 @@ void BLI_stack_pop(BLI_Stack *stack, void *dst)
BLI_stack_discard(stack);
}
+/**
+ * A version of #BLI_stack_pop which which fills in an array.
+ *
+ * \param dst: The destination array,
+ * must be at least (#BLI_Stack.elem_size * \a n) bytes long.
+ * \param n: The number of items to pop.
+ *
+ * \note The first item in the array will be last item added to the stack.
+ */
void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n)
{
BLI_assert(n <= BLI_stack_count(stack));
@@ -189,6 +208,23 @@ void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n)
}
}
+/**
+ * A version of #BLI_stack_pop_n which which fills in an array (in the reverse order).
+ *
+ * \note The first item in the array will be first item added to the stack.
+ */
+void BLI_stack_pop_n_reverse(BLI_Stack *stack, void *dst, unsigned int n)
+{
+ BLI_assert(n <= BLI_stack_count(stack));
+
+ dst = (void *)((char *)dst + (stack->elem_size * n));
+
+ while (n--) {
+ dst = (void *)((char *)dst - stack->elem_size);
+ BLI_stack_pop(stack, dst);
+ }
+}
+
void *BLI_stack_peek(BLI_Stack *stack)
{
BLI_assert(BLI_stack_is_empty(stack) == false);
@@ -196,6 +232,9 @@ void *BLI_stack_peek(BLI_Stack *stack)
return CHUNK_LAST_ELEM(stack);
}
+/**
+ * Removes the top element from the stack.
+ */
void BLI_stack_discard(BLI_Stack *stack)
{
BLI_assert(BLI_stack_is_empty(stack) == false);
@@ -216,6 +255,41 @@ void BLI_stack_discard(BLI_Stack *stack)
}
}
+/**
+ * Discards all elements without freeing.
+ */
+void BLI_stack_clear(BLI_Stack *stack)
+{
+#ifdef USE_TOTELEM
+ if (UNLIKELY(stack->totelem == 0)) {
+ return;
+ }
+ stack->totelem = 0;
+#else
+ if (UNLIKELY(stack->chunk_curr == NULL)) {
+ return;
+ }
+#endif
+
+ stack->chunk_index = stack->chunk_elem_max - 1;
+
+ if (stack->chunk_free) {
+ if (stack->chunk_curr) {
+ /* move all used chunks into tail of free list */
+ struct StackChunk *chunk_free_last = stack->chunk_free;
+ while (chunk_free_last->next) {
+ chunk_free_last = chunk_free_last->next;
+ }
+ chunk_free_last->next = stack->chunk_curr;
+ stack->chunk_curr = NULL;
+ }
+ }
+ else {
+ stack->chunk_free = stack->chunk_curr;
+ stack->chunk_curr = NULL;
+ }
+}
+
size_t BLI_stack_count(const BLI_Stack *stack)
{
#ifdef USE_TOTELEM