Skip to content

Commit

Permalink
api: remove reference counting things from jule::Any
Browse files Browse the repository at this point in the history
  • Loading branch information
mertcandav committed Aug 12, 2023
1 parent baea228 commit 1662b11
Showing 1 changed file with 25 additions and 65 deletions.
90 changes: 25 additions & 65 deletions api/any.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,28 +54,28 @@ namespace jule {

struct Type {
public:
const char*(*type_id)(void) ;
void(*dealloc)(void *alloc) ;
jule::Bool(*eq)(void *alloc, void *other) ;
const jule::Str(*to_str)(const void *alloc) ;
void *(*alloc_new_copy)(void *data) ;
const char*(*type_id)(void);
void(*dealloc)(void *alloc);
jule::Bool(*eq)(void *alloc, void *other);
const jule::Str(*to_str)(const void *alloc);
void *(*alloc_new_copy)(void *data);
};

template<typename T>
static jule::Any::Type *new_type(void) {
using t = typename std::decay<DynamicType<T>>::type;
using type = typename std::decay<DynamicType<T>>::type;
static jule::Any::Type table = {
t::type_id,
t::dealloc,
t::eq,
t::to_str,
t::alloc_new_copy,
.type_id = type::type_id,
.dealloc = type::dealloc,
.eq = type::eq,
.to_str = type::to_str,
.alloc_new_copy = type::alloc_new_copy,
};
return &table;
}

public:
jule::Ref<void*> data{};
void *data{ nullptr };
jule::Any::Type *type{ nullptr };

Any(void) {}
Expand All @@ -94,38 +94,11 @@ namespace jule {
{ this->dealloc(); }

void dealloc(void) {
#ifdef __JULE_DISABLE__REFERENCE_COUNTING
this->type = nullptr;
this->data.drop();
#else
if (!this->data.ref) {
this->type = nullptr;
this->data.drop();
return;
}
if (this->data)
this->type->dealloc(this->data);

// Use jule::REFERENCE_DELTA, DON'T USE drop_ref METHOD BECAUSE
// jule_ref does automatically this.
// If not in this case:
// if this is method called from destructor, reference count setted to
// negative integer but reference count is unsigned, for this reason
// allocation is not deallocated.
if (this->data.get_ref_n() != jule::REFERENCE_DELTA) {
this->type = nullptr;
this->data.drop();
return;
}

this->type->dealloc(*this->data.alloc);
*this->data.alloc = nullptr;
this->type = nullptr;

delete this->data.ref;
this->data.ref = nullptr;
std::free(this->data.alloc);
this->data.alloc = nullptr;
this->data.drop();
#endif // __JULE_DISABLE__REFERENCE_COUNTING
this->data = nullptr;
}

template<typename T>
Expand All @@ -143,27 +116,18 @@ namespace jule {
void operator=(const T &expr) {
this->dealloc();

T *alloc{ new(std::nothrow) T };
T *alloc{ new (std::nothrow) T };
if (!alloc)
jule::panic(jule::ERROR_MEMORY_ALLOCATION_FAILED);

void **main_alloc{ new(std::nothrow) void* };
if (!main_alloc)
jule::panic(jule::ERROR_MEMORY_ALLOCATION_FAILED);

*alloc = expr;
*main_alloc = static_cast<void*>(alloc);
#ifdef __JULE_DISABLE__REFERENCE_COUNTING
this->data = jule::Ref<void*>::make(main_alloc, nullptr);
#else
this->data = jule::Ref<void*>::make(main_alloc);
#endif
this->data = static_cast<void*>(alloc);
this->type = jule::Any::new_type<T>();
}

void operator=(const jule::Any &src) {
// Assignment to itself.
if (this->data.alloc != nullptr && this->data.alloc == src.data.alloc)
if (this->data != nullptr && this->data == src.data)
return;

if (src.operator==(nullptr)) {
Expand All @@ -173,15 +137,11 @@ namespace jule {

this->dealloc();

void *new_heap{ src.type->alloc_new_copy(*src.data.alloc) };
void *new_heap{ src.type->alloc_new_copy(src.data) };
if (!new_heap)
jule::panic(jule::ERROR_MEMORY_ALLOCATION_FAILED);

#ifdef __JULE_DISABLE__REFERENCE_COUNTING
this->data = jule::Ref<void*>::make(new_heap, nullptr);
#else
this->data = jule::Ref<void*>::make(new_heap);
#endif
this->data = new_heap;
this->type = src.type;
}

Expand All @@ -196,7 +156,7 @@ namespace jule {
if (!this->type_is<T>())
jule::panic(jule::ERROR_INCOMPATIBLE_TYPE);

return *static_cast<T*>(*this->data.alloc);
return *static_cast<T*>(this->data);
}

template<typename T>
Expand All @@ -210,7 +170,7 @@ namespace jule {

inline jule::Bool operator==(const jule::Any &other) const {
// Break comparison cycle.
if (this->data.alloc != nullptr && this->data.alloc == other.data.alloc)
if (this->data != nullptr && this->data == other.data)
return true;

if (this->operator==(nullptr))
Expand All @@ -222,22 +182,22 @@ namespace jule {
if (std::strcmp(this->type->type_id(), other.type->type_id()) != 0)
return false;

return this->type->eq(*this->data.alloc, *other.data.alloc);
return this->type->eq(this->data, other.data);
}

inline jule::Bool operator!=(const jule::Any &other) const
{ return !this->operator==(other); }

inline jule::Bool operator==(std::nullptr_t) const
{ return !this->data.alloc; }
{ return !this->data; }

inline jule::Bool operator!=(std::nullptr_t) const
{ return !this->operator==(nullptr); }

friend std::ostream &operator<<(std::ostream &stream,
const jule::Any &src) {
if (src.operator!=(nullptr))
stream << src.type->to_str(*src.data.alloc);
stream << src.type->to_str(src.data);
else
stream << 0;
return stream;
Expand Down

0 comments on commit 1662b11

Please sign in to comment.