diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-07-18 11:02:04 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@nekernel.org> | 2025-07-18 11:02:04 +0100 |
| commit | c44d6912bc2f37e8d1c239cfb9981bd5cd366c58 (patch) | |
| tree | 13ba46b3f3aa1d82e45a3cfde79b80ab4abc4864 | |
| parent | 142a0bc12ac8178ba7a3ac824a92c775ce6afbba (diff) | |
feat: tracked_ptr class and system.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
| -rw-r--r-- | examples/fix/fix.cc | 2 | ||||
| -rw-r--r-- | examples/tracked_ptr/CMakeLists.txt | 12 | ||||
| -rw-r--r-- | examples/tracked_ptr/tracked_ptr.cc | 29 | ||||
| -rw-r--r-- | lib/memory/tracked_ptr.hpp | 176 |
4 files changed, 218 insertions, 1 deletions
diff --git a/examples/fix/fix.cc b/examples/fix/fix.cc index 4a6fa8c..f67d8a0 100644 --- a/examples/fix/fix.cc +++ b/examples/fix/fix.cc @@ -1,5 +1,5 @@ /* - string checksum example + fix example written by Amlal El Mahrouss. licensed under the MIT license */ diff --git a/examples/tracked_ptr/CMakeLists.txt b/examples/tracked_ptr/CMakeLists.txt new file mode 100644 index 0000000..9396506 --- /dev/null +++ b/examples/tracked_ptr/CMakeLists.txt @@ -0,0 +1,12 @@ + +cmake_minimum_required(VERSION 3.15...3.31) + +project( + Fix + VERSION 1.0 + LANGUAGES CXX) + +add_executable(TrackedPtr tracked_ptr.cc) + +set_property(TARGET TrackedPtr PROPERTY CXX_STANDARD 20) +target_include_directories(TrackedPtr PUBLIC ../../) diff --git a/examples/tracked_ptr/tracked_ptr.cc b/examples/tracked_ptr/tracked_ptr.cc new file mode 100644 index 0000000..be88d17 --- /dev/null +++ b/examples/tracked_ptr/tracked_ptr.cc @@ -0,0 +1,29 @@ +/* + tracked_ptr example + written by Amlal El Mahrouss. + licensed under the MIT license + */ + +#include <lib/memory/tracked_ptr.hpp> +#include <iostream> + +void foo() +{ + snu::memory::tracked_ptr<int> ptr9; +} + +/* finally test it */ +int main(int argc, char** argv) +{ + foo(); + foo(); + foo(); + foo(); + + snu::memory::tracked_ptr<int> ptr; + + std::cout << ptr.manager().allocator().allocated_count_ << std::endl; + std::cout << ptr.manager().allocator().deallocated_count_ << std::endl; + + return 0; +} diff --git a/lib/memory/tracked_ptr.hpp b/lib/memory/tracked_ptr.hpp new file mode 100644 index 0000000..b94c9b4 --- /dev/null +++ b/lib/memory/tracked_ptr.hpp @@ -0,0 +1,176 @@ +/* + * 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 <cstddef> +#include <utility> +#include <memory> + +namespace snu::memory +{ + template <typename T> + class tracked_allocator; + + template <typename T> + class tracked_mgr; + + template <typename T, typename Mgr> + class tracked_ptr; + + template <typename T> + class tracked_allocator + { + public: + std::size_t allocated_count_ = 0; + std::size_t deallocated_count_ = 0; + bool is_initialized_ = false; + + public: + template <typename... U> + void allocate(T*& ptr, U&&... args) + { + if (!is_initialized_) + { + is_initialized_ = true; + } + + ptr = new T(args...); + + if (ptr) + { + ++allocated_count_; + } + else + { + throw std::bad_alloc(); + } + } + + void deallocate(T*& ptr) + { + if (ptr) + { + if (allocated_count_) + --allocated_count_; + + ++deallocated_count_; + + ::operator delete(ptr); + ptr = nullptr; + } + } + }; + + template <typename T> + class tracked_mgr + { + private: + tracked_allocator<T> allocator_; + + public: + const tracked_allocator<T>& allocator() + { + return allocator_; + } + + template <typename... U> + T* retain(U&&... args) + { + T* ptr = nullptr; + allocator_.allocate(ptr, std::forward<U>(args)...); + return ptr; + } + + void dispose(T* ptr) + { + allocator_.deallocate(ptr); + } + }; + + template <typename T, typename Mgr = tracked_mgr<T>> + class tracked_ptr + { + public: + static Mgr& manager() + { + static Mgr mgr; + return mgr; + } + + public: + template <typename... U> + explicit tracked_ptr(U&&... args) + : ptr_(nullptr) + { + ptr_ = tracked_ptr::manager().retain(std::forward<U>(args)...); + } + + ~tracked_ptr() noexcept + { + tracked_ptr::manager().dispose(ptr_); + } + + tracked_ptr(const tracked_ptr&) = delete; + tracked_ptr& operator=(const tracked_ptr&) = delete; + + public: + 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: + /// Move constructor + tracked_ptr(tracked_ptr&& other) noexcept + : ptr_(other.ptr_) + { + other.ptr_ = nullptr; + } + + /// Move assignment operator + tracked_ptr& operator=(tracked_ptr&& other) noexcept + { + if (this != &other) + { + this->reset(); + ptr_ = other.ptr_; + other.ptr_ = nullptr; + } + + return *this; + } + + private: + T* ptr_ = nullptr; + }; +} // namespace snu::memory
\ No newline at end of file |
