rcpp_framework/libs/brynet/base/Array.hpp

129 lines
2.3 KiB
C++
Raw Normal View History

2020-11-24 15:41:18 +01:00
#pragma once
#include <cassert>
2021-04-30 16:10:14 +02:00
#include <cstdlib>
#include <cstring>
2020-11-24 15:41:18 +01:00
namespace brynet { namespace base {
2021-04-30 16:10:14 +02:00
struct array_s
{
void* buffer;
size_t buffer_size;
size_t element_size;
size_t element_num;
};
static void array_delete(struct array_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->buffer != nullptr)
2020-11-24 15:41:18 +01:00
{
2021-04-30 16:10:14 +02:00
free(self->buffer);
self->buffer = nullptr;
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
self->element_num = 0;
free(self);
self = nullptr;
}
static struct array_s* array_new(size_t num, size_t element_size)
{
auto ret = (struct array_s*) malloc(sizeof(struct array_s));
if (ret == nullptr)
{
return nullptr;
}
const auto buffer_size = num * element_size;
ret->buffer_size = 0;
ret->element_size = 0;
ret->element_num = 0;
ret->buffer = malloc(buffer_size);
if (ret->buffer != nullptr)
{
ret->element_size = element_size;
ret->element_num = num;
ret->buffer_size = buffer_size;
}
else
2020-11-24 15:41:18 +01:00
{
2021-04-30 16:10:14 +02:00
array_delete(ret);
ret = nullptr;
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
return ret;
}
static void* array_at(struct array_s* self, size_t index)
{
void* ret = nullptr;
if (index < self->element_num)
{
ret = (char*) (self->buffer) + (index * self->element_size);
}
else
2020-11-24 15:41:18 +01:00
{
2021-04-30 16:10:14 +02:00
assert(false);
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
return ret;
}
static bool array_set(struct array_s* self, size_t index, const void* data)
{
void* old_data = array_at(self, index);
if (old_data != nullptr)
2020-11-24 15:41:18 +01:00
{
2021-04-30 16:10:14 +02:00
memcpy(old_data, data, self->element_size);
return true;
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
else
{
return false;
}
}
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
static bool array_increase(struct array_s* self, size_t increase_num)
{
if (increase_num == 0)
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
const auto new_buffer_size = self->buffer_size + increase_num * self->element_size;
auto new_buffer = malloc(new_buffer_size);
if (new_buffer != nullptr)
{
memcpy(new_buffer, self->buffer, self->buffer_size);
free(self->buffer);
self->buffer = new_buffer;
self->element_num += increase_num;
self->buffer_size = new_buffer_size;
return true;
}
else
2020-11-24 15:41:18 +01:00
{
2021-04-30 16:10:14 +02:00
assert(false);
return false;
2020-11-24 15:41:18 +01:00
}
2021-04-30 16:10:14 +02:00
}
static size_t array_num(const struct array_s* self)
{
return self->element_num;
}
2020-11-24 15:41:18 +01:00
2021-04-30 16:10:14 +02:00
}}// namespace brynet::base