diff options
author | HampusM <hampus@hampusmat.com> | 2022-03-14 14:13:54 +0100 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2022-03-14 14:13:54 +0100 |
commit | 5b6427dde0bb8e3b466793243bbfc185f4739ac6 (patch) | |
tree | bd8f09220d5c2354824f231c214dc6d9364717ce /src/common | |
parent | 5aa818e65eaa3cc288e097ed3b1a134015215500 (diff) |
refactor: implement & use shared ptr
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/memory/shared_ptr.hpp | 44 | ||||
-rw-r--r-- | src/common/memory/shared_ptr.tpp | 153 |
2 files changed, 197 insertions, 0 deletions
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 <stddef.h>
+
+namespace common
+{
+template <class Target>
+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 <typename Target, typename... Args>
+SharedPtr<Target> 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 <stdlib.h>
+
+namespace common
+{
+
+template <class Target>
+SharedPtr<Target>::SharedPtr() noexcept
+ : _reference_cnt(malloc_s<unsigned int>(sizeof(unsigned int)))
+{
+ (*_reference_cnt) = 0;
+}
+
+template <class Target>
+SharedPtr<Target>::SharedPtr(nullptr_t) noexcept
+ : _reference_cnt(malloc_s<unsigned int>(sizeof(unsigned int)))
+{
+ (*_reference_cnt) = 0;
+}
+
+template <class Target>
+SharedPtr<Target>::SharedPtr(Target *target) noexcept
+ : _target(target), _reference_cnt(malloc_s<unsigned int>(sizeof(unsigned int)))
+{
+ (*_reference_cnt) = 0;
+}
+
+/**
+ * Copy constructor
+ */
+template <class Target>
+SharedPtr<Target>::SharedPtr(const SharedPtr &shared_ptr) noexcept
+ : _target(shared_ptr._target), _reference_cnt(shared_ptr._reference_cnt)
+{
+ (*_reference_cnt)++;
+}
+
+/**
+ * Move constructor
+ */
+template <class Target>
+SharedPtr<Target>::SharedPtr(SharedPtr &&shared_ptr) noexcept
+ : _target(shared_ptr._target), _reference_cnt(shared_ptr._reference_cnt)
+{
+ shared_ptr._target = nullptr;
+}
+
+template <class Target>
+SharedPtr<Target>::~SharedPtr() noexcept
+{
+ if ((*_reference_cnt) != 0U)
+ {
+ (*_reference_cnt)--;
+ }
+
+ if ((*_reference_cnt) == 0U)
+ {
+ delete _target;
+ free(_reference_cnt);
+ _reference_cnt = nullptr;
+ }
+}
+
+template <class Target>
+unsigned int SharedPtr<Target>::reference_cnt() const noexcept
+{
+ if (_reference_cnt == nullptr)
+ {
+ return 0;
+ }
+
+ return *_reference_cnt;
+}
+
+template <class Target>
+bool SharedPtr<Target>::is_disposable() const noexcept
+{
+ return _reference_cnt == nullptr || (*_reference_cnt) == 0U;
+}
+
+/**
+ * Copy assignment operator
+ */
+template <class Target>
+SharedPtr<Target> &SharedPtr<Target>::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 <class Target>
+SharedPtr<Target> &SharedPtr<Target>::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 <class Target>
+Target &SharedPtr<Target>::operator*() const noexcept
+{
+ return *(_target);
+}
+
+template <class Target>
+Target *SharedPtr<Target>::operator->() const noexcept
+{
+ return _target;
+}
+
+template <class Target, typename... Args>
+SharedPtr<Target> make_shared(Args &&...args) noexcept
+{
+ return SharedPtr<Target>(new Target(args...));
+}
+
+} // namespace common
|