rcpp_framework/libs/brynet/base/Stack.hpp

170 lines
3.1 KiB
C++
Raw Normal View History

2020-11-24 15:41:18 +01:00
#pragma once
#include <brynet/base/Array.hpp>
2021-04-30 16:10:14 +02:00
#include <cstdlib>
2020-11-24 15:41:18 +01:00
namespace brynet { namespace base {
2021-04-30 16:10:14 +02:00
struct stack_s
{
struct array_s* array;
size_t element_size;
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
size_t element_num;
size_t front;
size_t num;
};
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
static void stack_delete(struct stack_s* self)
{
if (self == nullptr)
2020-11-24 15:41:18 +01:00
{
2021-04-30 16:10:14 +02:00
return;
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
if (self->array != nullptr)
2020-11-24 15:41:18 +01:00
{
2021-04-30 16:10:14 +02:00
array_delete(self->array);
self->array = nullptr;
}
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
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;
}
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
ret->element_size = 0;
ret->element_num = 0;
ret->front = 0;
ret->num = 0;
ret->array = array_new(num, element_size);
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
if (ret->array != nullptr)
{
ret->element_size = element_size;
ret->element_num = num;
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
else
2020-11-24 15:41:18 +01:00
{
2021-04-30 16:10:14 +02:00
stack_delete(ret);
ret = nullptr;
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
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)
2020-11-24 15:41:18 +01:00
{
2021-04-30 16:10:14 +02:00
return false;
2020-11-24 15:41:18 +01:00
}
{
2021-04-30 16:10:14 +02:00
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)
2020-11-24 15:41:18 +01:00
{
2021-04-30 16:10:14 +02:00
array_set(tmp, i, array_at(self->array, (self->front + i) % current_num));
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
self->front = 0;
array_delete(self->array);
self->array = tmp;
self->element_num = array_num(self->array);
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
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);
}
static bool stack_push(struct stack_s* self, const void* data)
{
if (stack_isfull(self))
2020-11-24 15:41:18 +01:00
{
2021-04-30 16:10:14 +02:00
stack_increase(self, stack_size(self));
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
if (stack_isfull(self))
2020-11-24 15:41:18 +01:00
{
2021-04-30 16:10:14 +02:00
return false;
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
array_set(self->array, (self->front + self->num) % self->element_num, data);
self->num++;
return true;
}
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
static void* stack_front(struct stack_s* self)
{
void* ret = nullptr;
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
if (stack_num(self) > 0)
2020-11-24 15:41:18 +01:00
{
2021-04-30 16:10:14 +02:00
ret = array_at(self->array, self->front);
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
return ret;
}
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
static void* stack_popfront(struct stack_s* self)
{
void* ret = stack_front(self);
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
if (ret != nullptr)
{
self->num--;
self->front++;
self->front %= self->element_num;
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
return ret;
}
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
static void* stack_popback(struct stack_s* self)
{
void* ret = nullptr;
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
if (stack_num(self) > 0)
{
self->num--;
ret = array_at(self->array, (self->front + self->num) % self->element_num);
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
return ret;
}
}}// namespace brynet::base