From 5b6427dde0bb8e3b466793243bbfc185f4739ac6 Mon Sep 17 00:00:00 2001 From: HampusM Date: Mon, 14 Mar 2022 14:13:54 +0100 Subject: refactor: implement & use shared ptr --- src/common/memory/shared_ptr.tpp | 153 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/common/memory/shared_ptr.tpp (limited to 'src/common/memory/shared_ptr.tpp') diff --git a/src/common/memory/shared_ptr.tpp b/src/common/memory/shared_ptr.tpp new file mode 100644 index 0000000..d9b57c3 --- /dev/null +++ b/src/common/memory/shared_ptr.tpp @@ -0,0 +1,153 @@ +#pragma once + +#include "shared_ptr.hpp" + +#include "common/memory.hpp" + +#include + +namespace common +{ + +template +SharedPtr::SharedPtr() noexcept + : _reference_cnt(malloc_s(sizeof(unsigned int))) +{ + (*_reference_cnt) = 0; +} + +template +SharedPtr::SharedPtr(nullptr_t) noexcept + : _reference_cnt(malloc_s(sizeof(unsigned int))) +{ + (*_reference_cnt) = 0; +} + +template +SharedPtr::SharedPtr(Target *target) noexcept + : _target(target), _reference_cnt(malloc_s(sizeof(unsigned int))) +{ + (*_reference_cnt) = 0; +} + +/** + * Copy constructor + */ +template +SharedPtr::SharedPtr(const SharedPtr &shared_ptr) noexcept + : _target(shared_ptr._target), _reference_cnt(shared_ptr._reference_cnt) +{ + (*_reference_cnt)++; +} + +/** + * Move constructor + */ +template +SharedPtr::SharedPtr(SharedPtr &&shared_ptr) noexcept + : _target(shared_ptr._target), _reference_cnt(shared_ptr._reference_cnt) +{ + shared_ptr._target = nullptr; +} + +template +SharedPtr::~SharedPtr() noexcept +{ + if ((*_reference_cnt) != 0U) + { + (*_reference_cnt)--; + } + + if ((*_reference_cnt) == 0U) + { + delete _target; + free(_reference_cnt); + _reference_cnt = nullptr; + } +} + +template +unsigned int SharedPtr::reference_cnt() const noexcept +{ + if (_reference_cnt == nullptr) + { + return 0; + } + + return *_reference_cnt; +} + +template +bool SharedPtr::is_disposable() const noexcept +{ + return _reference_cnt == nullptr || (*_reference_cnt) == 0U; +} + +/** + * Copy assignment operator + */ +template +SharedPtr &SharedPtr::operator=(const SharedPtr &rhs) noexcept +{ + if (&rhs != this) + { + if (is_disposable()) + { + delete _target; + free(_reference_cnt); + } + + _target = nullptr; + _target = rhs._target; + + _reference_cnt = nullptr; + _reference_cnt = rhs._reference_cnt; + (*_reference_cnt)++; + } + + return *this; +} + +/** + * Move assignment operator + */ +template +SharedPtr &SharedPtr::operator=(SharedPtr &&rhs) noexcept +{ + if (&rhs != this) + { + if (is_disposable()) + { + delete _target; + free(_reference_cnt); + } + + _target = rhs._target; + rhs._target = nullptr; + + _reference_cnt = rhs._reference_cnt; + rhs._reference_cnt = nullptr; + } + + return *this; +} + +template +Target &SharedPtr::operator*() const noexcept +{ + return *(_target); +} + +template +Target *SharedPtr::operator->() const noexcept +{ + return _target; +} + +template +SharedPtr make_shared(Args &&...args) noexcept +{ + return SharedPtr(new Target(args...)); +} + +} // namespace common -- cgit v1.2.3-18-g5258