rcpp_framework/libs/brynet/base/Stack.hpp
2020-11-24 15:41:18 +01:00

176 lines
3.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <cstdbool>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include <cstdint>
#include <brynet/base/Array.hpp>
namespace brynet { namespace base {
struct stack_s
{
struct array_s* array;
size_t element_size;
size_t element_num;
size_t front; /* Õ»µ× */
size_t num; /* Õ»ÓÐЧԪËØ´óС */
};
static void stack_delete(struct stack_s* self)
{
if (self == nullptr)
{
return;
}
if (self->array != nullptr)
{
array_delete(self->array);
self->array = nullptr;
}
self->element_num = 0;
self->front = 0;
self->num = 0;
free(self);
self = nullptr;
}
static struct stack_s* stack_new(size_t num, size_t element_size)
{
struct stack_s* ret = (struct stack_s*)malloc(sizeof(struct stack_s));
if (ret == nullptr)
{
return nullptr;
}
ret->element_size = 0;
ret->element_num = 0;
ret->front = 0;
ret->num = 0;
ret->array = array_new(num, element_size);
if (ret->array != nullptr)
{
ret->element_size = element_size;
ret->element_num = num;
}
else
{
stack_delete(ret);
ret = nullptr;
}
return ret;
}
static void stack_init(struct stack_s* self)
{
self->front = 0;
self->num = 0;
}
static size_t stack_num(struct stack_s* self)
{
return self->num;
}
static bool stack_increase(struct stack_s* self, size_t increase_num)
{
struct array_s* tmp = array_new(self->element_num + increase_num,
self->element_size);
if (tmp == nullptr)
{
return false;
}
{
size_t current_num = self->element_num;
size_t current_stack_num = stack_num(self);
for (size_t i = 0; i < current_stack_num; ++i)
{
array_set(tmp, i, array_at(self->array, (self->front + i) % current_num));
}
self->front = 0;
array_delete(self->array);
self->array = tmp;
self->element_num = array_num(self->array);
}
return true;
}
static size_t stack_size(struct stack_s* self)
{
return self->element_num;
}
static bool stack_isfull(struct stack_s* self)
{
return (self->num == self->element_num);
}
/* stackµÄstack_push»áÔڿռ䲻×ãµÄʱºò×Ô¶¯Ôö³¤(ͨ¹ýstack_increase) */
static bool stack_push(struct stack_s* self, const void* data)
{
if (stack_isfull(self))
{
stack_increase(self, stack_size(self));
}
if (stack_isfull(self))
{
return false;
}
array_set(self->array, (self->front + self->num) % self->element_num, data);
self->num++;
return true;
}
static void* stack_front(struct stack_s* self)
{
void* ret = nullptr;
if (stack_num(self) > 0)
{
ret = array_at(self->array, self->front);
}
return ret;
}
static void* stack_popfront(struct stack_s* self)
{
void* ret = stack_front(self);
if (ret != nullptr)
{
self->num--;
self->front++;
self->front %= self->element_num;
}
return ret;
}
static void* stack_popback(struct stack_s* self)
{
void* ret = nullptr;
if (stack_num(self) > 0)
{
self->num--;
ret = array_at(self->array, (self->front + self->num) % self->element_num);
}
return ret;
}
} }