From c52dbf5513ae7f106634967162da5cfb01dc5af3 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sat, 26 Jul 2025 01:47:32 +0100 Subject: feat: SOCL v1.0.2, changelog soon! Signed-off-by: Amlal El Mahrouss --- dev/lib/memory/tracked_ptr.hpp | 196 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 dev/lib/memory/tracked_ptr.hpp (limited to 'dev/lib/memory') diff --git a/dev/lib/memory/tracked_ptr.hpp b/dev/lib/memory/tracked_ptr.hpp new file mode 100644 index 0000000..238d521 --- /dev/null +++ b/dev/lib/memory/tracked_ptr.hpp @@ -0,0 +1,196 @@ +/* + * File: memory/tracked_ptr.hpp + * Purpose: Custom smart pointer implementation in C++ + * Author: Amlal El Mahrouss (founder@snu.systems) + * Copyright 2025, Amlal El Mahrouss and SNU Systems Corp all rights reserved. + */ + +#pragma once + +#include +#include +#include +#include + +namespace snu::memory +{ + template + class tracked_allocator; + + template + class tracked_mgr; + + template + class tracked_ptr; + + template + class tracked_allocator + { + public: + std::atomic allocated_count_ = 0; + std::atomic deallocated_count_ = 0; + + public: + template + void retain(T*& ptr, U&&... args) + { + ptr = new T(args...); + + if (ptr) + { + ++allocated_count_; + } + else + { + throw std::bad_alloc(); + } + } + + void dispose(T* ptr) + { + if (ptr) + { + if (allocated_count_) + --allocated_count_; + + ++deallocated_count_; + + delete ptr; + ptr = nullptr; + } + } + }; + + template + class tracked_mgr + { + private: + tracked_allocator allocator_; + + public: + const tracked_allocator& allocator() + { + return allocator_; + } + + template + T* retain(U&&... args) + { + T* ptr = nullptr; + allocator_.retain(ptr, std::forward(args)...); + return ptr; + } + + void dispose(T* ptr) + { + allocator_.dispose(ptr); + } + }; + + template > + class tracked_ptr + { + public: + static Mgr& manager() + { + static Mgr mgr; + return mgr; + } + + public: + template + explicit tracked_ptr(U&&... args) + : ptr_(nullptr) + { + ptr_ = tracked_ptr::manager().retain(std::forward(args)...); + } + + ~tracked_ptr() noexcept + { + this->reset(); + } + + tracked_ptr(const tracked_ptr&) = delete; + tracked_ptr& operator=(const tracked_ptr&) = delete; + + public: + void reset() + { + if (ptr_) + { + tracked_ptr::manager().dispose(ptr_); + ptr_ = nullptr; + } + } + + T* get() const + { + return ptr_; + } + + T* data() + { + return ptr_; + } + + T& operator*() const + { + return *ptr_; + } + + T* operator->() const + { + return ptr_; + } + + explicit operator bool() const + { + return ptr_ != nullptr; + } + + void swap(tracked_ptr& other) + { + std::swap(ptr_, other.ptr_); + } + + public: + tracked_ptr(tracked_ptr&& other) noexcept + : ptr_(other.ptr_) + { + other.ptr_ = nullptr; + } + + tracked_ptr& operator=(tracked_ptr&& other) noexcept + { + if (this != &other) + { + this->reset(); + ptr_ = other.ptr_; + other.ptr_ = nullptr; + } + + return *this; + } + + private: + T* ptr_ = nullptr; + }; + + template + inline auto make_tracked(T arg) -> tracked_ptr + { + return tracked_ptr(std::forward(arg)); + } + + template + inline auto make_tracked(T&&... arg) -> tracked_ptr + { + return tracked_ptr(std::forward(arg)...); + } + + template + inline void swap(tracked_ptr& a, tracked_ptr& b) + { + a.swap(b); + } +} // namespace snu::memory \ No newline at end of file -- cgit v1.2.3