Skip to content

Commit

Permalink
refactor. again...
Browse files Browse the repository at this point in the history
  • Loading branch information
EfesX committed May 28, 2024
1 parent e60248a commit e61b1bd
Show file tree
Hide file tree
Showing 11 changed files with 392 additions and 430 deletions.
72 changes: 72 additions & 0 deletions include/detail/list_storage.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#pragma once

#include <list>
#include <optional>

#include "detail/node.hpp"

namespace efesx {
namespace queue {
namespace detail
{


class list_storage {
private:
std::list<node> store;
public:
list_storage() = default;
list_storage(const list_storage&) = delete;
list_storage(list_storage&&) = delete;
list_storage& operator=(list_storage&&) = delete;
~list_storage() = default;

template<typename...Args>
void insert(Args...args){
store.emplace_back(args...);
store.sort();
}

template<typename T = bool>
std::optional<T> extract(void* buf = nullptr){
if(store.size() == 0) {
return std::optional<T>{};
}

node& val = store.front();

if(!val.has_value() || val.size() == 0){
return std::optional<T>{};
}

if (buf != nullptr){
val.blob_copy(buf);
return std::optional<T>{};
}

try{
return val.value_cast<T>();
} catch (std::runtime_error& e){
return std::optional<T>{};
}

}

void pop(){
store.pop_front();
}

template<typename T>
std::optional<T> extract_with_type(void* buf = nullptr){
throw std::runtime_error("Not Yet Implemented Error");
}



};



}; // namespace detail
}; // namespace queue
}; // namespace efesxzc
33 changes: 5 additions & 28 deletions include/detail/meta.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,14 @@ namespace efesx {
namespace queue {
namespace detail {

//@brief Structure for convertig T to value_t
template<typename T>
struct detector {
inline static constexpr value_t type = value_t::null_t;
};
template<>
struct detector<int>{
inline static constexpr value_t type = value_t::int_t;
};
template<>
struct detector<bool>{
inline static constexpr value_t type = value_t::bool_t;
};
template<>
struct detector<std::string>{
inline static constexpr value_t type = value_t::string_t;
};
template<>
struct detector<char>{
inline static constexpr value_t type = value_t::char_t;
};
concept IsIntegral = std::is_integral_v<T>;

template<typename T>
concept Container =
requires { typename T::iterator::iterator_category::forward_iterator_tag; } &&
!std::is_same_v<T, std::string> &&
requires (T a) {
{ a.begin()++ };
{ a.end() };
{ a.size() } -> std::convertible_to<std::size_t>;
};
concept IsFloating = std::is_floating_point_v<std::remove_cv_t<T>>;

template<typename T>
concept IsString = std::is_convertible_v<T, std::string>;

}; // namespace detail
}; // namespace queue
Expand Down
188 changes: 76 additions & 112 deletions include/detail/node.hpp
Original file line number Diff line number Diff line change
@@ -1,160 +1,124 @@
#pragma once

#include <cstring>

#include "types.hpp"
#include "meta.hpp"

namespace efesx {
namespace queue {
namespace detail {

class node {
struct node {
private:
union node_value
{
int int_value;
bool bool_value;
char char_value;
std::string* string_value;
std::vector<node>* array_value;

std::size_t v_size;

node_value() = default;
node_value(const node_value&) = default;
node_value(node_value&& oth) = default;

node_value(int v) : int_value(v) {}
node_value(bool v) : bool_value(v) {}
node_value(char v) : char_value(v) {}

node_value(value_t t, std::size_t size) {
switch (t)
{
case value_t::container_t: {
array_value = create<std::vector<node>>();
array_value->reserve(size);
break;
}

default: break;
}
}

node_value(const std::string& v) : string_value(create<std::string>(v)) {}
node_value(const std::string&& v) : string_value(create<std::string>(std::move(v))) {}

template<typename T, std::enable_if_t<std::is_pointer_v<T>, int> = 0>
node_value(T arr, std::size_t size) {
array_value = create<std::vector<node>>();
array_value->reserve(size);

for (auto i = 0; i < size; i++){
array_value->emplace_back(arr[i]);
}
}
const uint8_t m_priority = 0;
const value_t m_type;
const std::size_t m_size;
void* m_data;

template<typename T, typename... Args>
static T* create(Args&& ... args){
T* create(Args&& ... args){
using allocator_traits = std::allocator_traits<std::allocator<T>>;

std::allocator<T> alloc;


auto deleter = [&](T* obj){
allocator_traits::deallocate(alloc, obj, 1);
};

std::unique_ptr<T, decltype(deleter)> obj(allocator_traits::allocate(alloc, 1), deleter);
allocator_traits::construct(alloc, obj.get(), std::forward<Args>(args)...);
return obj.release();
}

void destroy(value_t t) {
switch (t)
{
case value_t::string_t: {
std::allocator<std::string> alloc;
std::allocator_traits<decltype(alloc)>::destroy(alloc, string_value);
std::allocator_traits<decltype(alloc)>::deallocate(alloc, string_value, 1);
break;
}
case value_t::array_t: {
std::allocator<std::vector<node>> alloc;
std::allocator_traits<decltype(alloc)>::destroy(alloc, array_value);
std::allocator_traits<decltype(alloc)>::deallocate(alloc, array_value, 1);
break;
}

default: break;
}
template<typename T>
void destroy(T* mem, std::size_t size){
std::allocator<T> alloc;
std::allocator_traits<decltype(alloc)>::destroy(alloc, mem);
std::allocator_traits<decltype(alloc)>::deallocate(alloc, mem, size);
m_data = nullptr;
}
};
public:
value_t m_type;
value_t m_subtype;
node() : m_type(value_t::null), m_size(0), m_data(nullptr) {}

node(const node&) = delete;
node(node&&) = delete;
node& operator=(node&&) = delete;
~node(){
if (m_type == value_t::blob) {
std::free(m_data);
return;
}
destroy<uint8_t>(static_cast<uint8_t*>(m_data), m_size);
}

node_value m_data;
template<IsIntegral T, uint8_t Size = sizeof(T)>
node(const T& val) : m_size(Size), m_type(value_t::integer), m_data(create<T>(val))
{}

// ARRAY
template<typename T, std::enable_if_t<std::is_pointer_v<T>, int> = 0> requires (!Container<T>)
node(const T val, std::size_t size, std::size_t priority = 0) :
m_data(val, size),
m_type(value_t::array_t),
m_subtype(detector<std::remove_const_t<std::remove_pointer_t<T>>>::type)
template<IsFloating T, uint8_t Size = sizeof(T)>
node(const T& val) : m_size(Size), m_type(value_t::floating), m_data(create<T>(val))
{}

// ANOTHER ALL
template<typename T, std::enable_if_t<std::is_fundamental_v<T> && !std::is_pointer_v<T>, int> = 0>
node(T val, std::size_t priority = 0) :
m_data(val),
m_type(detector<T>::type)
template<IsString T>
node(const T& val) : m_size(val.size()), m_type(value_t::text), m_data(create<T>(val))
{}

// STRING
template<typename T, std::enable_if_t<std::is_same_v<std::string, std::remove_cv_t<T>>, int> = 0>
node(T val, std::size_t priority = 0) :
m_data(val),
m_type(detector<T>::type)
node(const char* val, std::size_t _size) : m_size(_size), m_type(value_t::text), m_data(create<std::string>(std::string(val, _size)))
{}

// CONTAINERS
template<Container T>
node(const T& container, std::size_t priority = 0) :
m_data(value_t::container_t, container.size()),
m_type(value_t::container_t)
{
for (auto it = container.begin(); it != container.end(); it++){
m_data.array_value->emplace_back(*it, priority);
node(const void* val, std::size_t _size) : m_size(_size), m_type(value_t::blob), m_data(std::malloc(_size)) {
std::memcpy(m_data, val, _size);
}

template<typename T>
T&& value_cast(){
if (m_data == nullptr){
throw std::runtime_error("Node Value Is Empty");
}

if ((IsIntegral<T> && (m_type != value_t::integer)) ||
(IsFloating<T> && (m_type != value_t::floating))||
(IsString<T> && (m_type != value_t::text)))
{
throw std::runtime_error("Bad Node Value Cast");
}

return std::forward<T&&>(*static_cast<T*>(m_data));
}


node(const node&) = default;
node(node&& oth) = default;
void blob_copy(void *dst){
std::memcpy(dst, m_data, m_size);
}

~node() {
m_data.destroy(m_type);
std::size_t size(){
return m_size;
}

// ANOTHER ALL
template<typename T, std::enable_if_t<std::is_fundamental_v<T> && !std::is_pointer_v<T>, int> = 0>
void restore(T& data){
data = m_data.int_value;
bool has_value(){
return (m_data != nullptr);
}

// STRING
template<typename T, std::enable_if_t<std::is_same_v<std::string, std::remove_cv_t<T>>, int> = 0>
void restore(T& data){
data = *m_data.string_value;
value_t value_type(){
return m_type;
}

// ARRAY
template<typename T, std::enable_if_t<std::is_pointer_v<T>, int> = 0> requires (!Container<T>)
void restore(T val) {
std::size_t idx = 0;
for (auto it = m_data.array_value->begin(); it != m_data.array_value->end(); it++){
it->restore(val[idx]);
idx++;
}
uint8_t priority(){
return m_priority;
}

bool operator<(node& rhs){
return (m_priority > rhs.m_priority);
}
};







}; // namespace detail
}; // namespace queue
}; // namespace efesx
31 changes: 6 additions & 25 deletions include/detail/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,14 @@ namespace efesx {
namespace queue {
namespace detail {

enum class value_t : uint8_t
{
null_t = 0,
int_t,
char_t,
bool_t,
string_t,
array_t,
object_t,
container_t,
enum value_t {
null = 0,
integer,
floating,
text,
blob
};

std::ostream& operator<<(std::ostream& out, const value_t& val){
switch (val)
{
case value_t::null_t: { out << "null_t"; break; }
case value_t::int_t: { out << "int_t"; break; }
case value_t::bool_t: { out << "bool_t"; break; }
case value_t::string_t: { out << "string_t"; break; }
case value_t::array_t: { out << "array_t"; break; }
case value_t::object_t: { out << "object_t"; break; }
case value_t::char_t: { out << "char_t"; break; }
case value_t::container_t: { out << "conteiner_t"; break; }
default: {out << "other_t"; break; }
}
return out;
}

}; // namespace detail
}; // namespace queue
Expand Down
Loading

0 comments on commit e61b1bd

Please sign in to comment.