summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--examples/fix/fix.cc2
-rw-r--r--examples/tracked_ptr/CMakeLists.txt12
-rw-r--r--examples/tracked_ptr/tracked_ptr.cc29
-rw-r--r--lib/memory/tracked_ptr.hpp176
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