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.hpp | 44 +++++++++++ src/common/memory/shared_ptr.tpp | 153 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 src/common/memory/shared_ptr.hpp create mode 100644 src/common/memory/shared_ptr.tpp (limited to 'src/common') diff --git a/src/common/memory/shared_ptr.hpp b/src/common/memory/shared_ptr.hpp new file mode 100644 index 0000000..7e8a910 --- /dev/null +++ b/src/common/memory/shared_ptr.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include + +namespace common +{ +template +class SharedPtr +{ +public: + SharedPtr() noexcept; + SharedPtr(nullptr_t) noexcept; // NOLINT(google-explicit-constructor) + + explicit SharedPtr(Target *target) noexcept; + + SharedPtr(const SharedPtr &shared_ptr) noexcept; + + SharedPtr(SharedPtr &&shared_ptr) noexcept; + + ~SharedPtr() noexcept; + + [[nodiscard]] unsigned int reference_cnt() const noexcept; + + [[nodiscard]] bool is_disposable() const noexcept; + + SharedPtr &operator=(const SharedPtr &rhs) noexcept; + + SharedPtr &operator=(SharedPtr &&rhs) noexcept; + + Target &operator*() const noexcept; + Target *operator->() const noexcept; + +private: + Target *_target = nullptr; + + unsigned int *_reference_cnt; +}; + +template +SharedPtr make_shared(Args &&...args) noexcept; + +} // namespace common + +#include "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