diff options
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
 | 
