Browse Source

added namespace

channel
Ludovic 'Archivist' Lagouardette 3 years ago
parent
commit
bbe9854f78
1 changed files with 124 additions and 122 deletions
  1. +124
    -122
      include/gp/pointers.hpp

+ 124
- 122
include/gp/pointers.hpp View File

@ -5,132 +5,134 @@
#include "gp/buffer.hpp"
#include "gp/function.hpp"
namespace gp {
template<typename T>
class unique_ptr {
T* data;
gp::allocator& owner;
template<typename T>
class unique_ptr {
T* data;
gp::allocator& owner;
unique_ptr(T* _data, gp::allocator& _owner)
: data(data)
, owner(_owner)
{}
void dirty_clear() {
if(data) {
data->~T();
owner.deallocate(data);
}
}
public:
template<typename ...U>
unique_ptr make(gp::allocator& owner, U&&... args) {
auto ptr = owner.allocate(sizeof(T));
return unique_ptr(new(ptr) T(gp::forward<U>(args)...), owner);
}
T& operator->() {
return *data;
}
T& operator*() {
return *data;
}
unique_ptr(unique_ptr&) = delete;
unique_ptr(unique_ptr&& oth)
: data(oth.data)
, owner(oth.owner)
{
oth.data = nullptr;
}
unique_ptr& operator=(unique_ptr&) = delete;
unique_ptr& operator=(unique_ptr&& oth) {
dirty_clear();
data = oth.data;
owner = oth.owner;
}
~unique_ptr() {
dirty_clear();
}
};
template<typename T>
class shared_ptr {
T* data;
std::atomic_int* refcounter;
gp::allocator& owner;
shared_ptr(T* _data, gp::allocator& _owner)
: data(data)
, owner(_owner)
{}
void dirty_clear() {
if(!refcounter) return;
if(refcounter->fetch_sub(1, std::memory_order::acq_rel) == 0) {
unique_ptr(T* _data, gp::allocator& _owner)
: data(data)
, owner(_owner)
{}
void dirty_clear() {
if(data) {
data->~T();
owner.deallocate(refcounter);
owner.deallocate(data);
}
}
}
public:
template<typename ...U>
shared_ptr make(gp::allocator& owner, U&&... args) {
auto ptr = owner.allocate(sizeof(T));
auto shared_atomic = owner.allocate(sizeof(std::atomic_int));
refcounter = new(shared_atomic) std::atomic_int();
refcounter->store(1);
return shared_ptr(new(ptr) T(gp::forward<U>(args)...), owner);
}
T& operator->() {
return *data;
}
T& operator*() {
return *data;
}
shared_ptr(shared_ptr& oth) {
oth.refcounter->fetch_add(1, std::memory_order::acquire);
data = oth.data;
refcounter = oth.refcounter;
owner = oth.owner;
}
shared_ptr(shared_ptr&& oth)
: data(oth.data)
, owner(oth.owner)
{
oth.data = nullptr;
oth.refcounter = nullptr;
}
shared_ptr& operator=(shared_ptr& oth) {
dirty_clear();
(*oth.refcounter)++;
data = oth.data;
refcounter = oth.refcounter;
owner = oth.owner;
}
shared_ptr& operator=(shared_ptr&& oth) {
dirty_clear();
data = oth.data;
owner = oth.owner;
}
~shared_ptr() {
dirty_clear();
}
};
public:
template<typename ...U>
unique_ptr make(gp::allocator& owner, U&&... args) {
auto ptr = owner.allocate(sizeof(T));
return unique_ptr(new(ptr) T(gp::forward<U>(args)...), owner);
}
T& operator->() {
return *data;
}
T& operator*() {
return *data;
}
unique_ptr(unique_ptr&) = delete;
unique_ptr(unique_ptr&& oth)
: data(oth.data)
, owner(oth.owner)
{
oth.data = nullptr;
}
unique_ptr& operator=(unique_ptr&) = delete;
unique_ptr& operator=(unique_ptr&& oth) {
dirty_clear();
data = oth.data;
owner = oth.owner;
}
~unique_ptr() {
dirty_clear();
}
};
template<typename T>
class shared_ptr {
T* data;
std::atomic_int* refcounter;
gp::allocator& owner;
shared_ptr(T* _data, gp::allocator& _owner)
: data(data)
, owner(_owner)
{}
void dirty_clear() {
if(!refcounter) return;
if(refcounter->fetch_sub(1, std::memory_order::acq_rel) == 0) {
if(data) {
data->~T();
owner.deallocate(refcounter);
owner.deallocate(data);
}
}
}
public:
template<typename ...U>
shared_ptr make(gp::allocator& owner, U&&... args) {
auto ptr = owner.allocate(sizeof(T));
auto shared_atomic = owner.allocate(sizeof(std::atomic_int));
refcounter = new(shared_atomic) std::atomic_int();
refcounter->store(1);
return shared_ptr(new(ptr) T(gp::forward<U>(args)...), owner);
}
T& operator->() {
return *data;
}
T& operator*() {
return *data;
}
shared_ptr(shared_ptr& oth) {
oth.refcounter->fetch_add(1, std::memory_order::acquire);
data = oth.data;
refcounter = oth.refcounter;
owner = oth.owner;
}
shared_ptr(shared_ptr&& oth)
: data(oth.data)
, owner(oth.owner)
{
oth.data = nullptr;
oth.refcounter = nullptr;
}
shared_ptr& operator=(shared_ptr& oth) {
dirty_clear();
(*oth.refcounter)++;
data = oth.data;
refcounter = oth.refcounter;
owner = oth.owner;
}
shared_ptr& operator=(shared_ptr&& oth) {
dirty_clear();
data = oth.data;
owner = oth.owner;
}
~shared_ptr() {
dirty_clear();
}
};
}

Loading…
Cancel
Save