aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64
diff options
context:
space:
mode:
authorFabian Imhof <fabian.imhof@ost.ch>2025-02-27 07:15:03 +0000
committerFabian Imhof <fabian.imhof@ost.ch>2025-02-27 07:15:03 +0000
commit462a4e09b1a67562dd1a122936c1ad0fc1771e0e (patch)
treedd35dc14da82d758bce8a4474313cd2d94a07634 /arch/x86_64
parent2cbaf2d52bd9379e5c6e4a0d018b25d1c882193d (diff)
downloadteachos-462a4e09b1a67562dd1a122936c1ad0fc1771e0e.tar.xz
teachos-462a4e09b1a67562dd1a122936c1ad0fc1771e0e.zip
add smart pointers
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/include/arch/stl/shared_pointer.hpp120
-rw-r--r--arch/x86_64/include/arch/stl/unique_pointer.hpp68
2 files changed, 188 insertions, 0 deletions
diff --git a/arch/x86_64/include/arch/stl/shared_pointer.hpp b/arch/x86_64/include/arch/stl/shared_pointer.hpp
new file mode 100644
index 0000000..79a9f82
--- /dev/null
+++ b/arch/x86_64/include/arch/stl/shared_pointer.hpp
@@ -0,0 +1,120 @@
+#ifndef TEACHOS_ARCH_X86_64_STL_SHARED_POINTER_HPP
+#define TEACHOS_ARCH_X86_64_STL_SHARED_POINTER_HPP
+
+namespace teachos::arch::stl
+{
+ template<typename T>
+ struct shared_pointer
+ {
+ explicit shared_pointer(T * pointer = nullptr)
+ : pointer(pointer)
+ , ref_count(new std::atomic<int>(pointer != nullptr ? 1 : 0))
+ {
+ }
+
+ shared_pointer(const shared_pointer & other)
+ : pointer(other.pointer)
+ , ref_count(other.ref_count)
+ {
+ if (pointer != nullptr)
+ {
+ ++(*ref_count);
+ }
+ }
+
+ shared_pointer(shared_pointer && other) noexcept
+ : pointer(other.pointer)
+ , ref_count(other.ref_count)
+ {
+ other.pointer = nullptr;
+ other.ref_count = nullptr;
+ }
+
+ shared_pointer & operator=(const shared_pointer & other)
+ {
+ if (this != &other)
+ {
+ cleanup();
+ pointer = other.pointer;
+ ref_count = other.ref_count;
+
+ if (pointer != nullptr)
+ {
+ ++(*ref_count);
+ }
+ }
+
+ return *this;
+ }
+
+ shared_pointer & operator=(shared_pointer && other) noexcept
+ {
+ if (this != &other)
+ {
+ cleanup();
+ pointer = other.pointer;
+ ref_count = other.ref_count;
+ other.pointer = nullptr;
+ other.ref_count = nullptr;
+ }
+
+ return *this;
+ }
+
+ ~shared_pointer() { cleanup(); }
+
+ void cleanup()
+ {
+ if (pointer != nullptr && ref_count != nullptr && --(*ref_count) == 0)
+ {
+ delete pointer;
+ delete ref_count;
+ }
+ }
+
+ void reset(T * p = nullptr)
+ {
+ cleanup();
+ pointer = p;
+ ref_count = new std::atomic<int>(p != nullptr ? 1 : 0);
+ }
+
+ void swap(shared_pointer & other)
+ {
+ std::swap(pointer, other.pointer);
+ std::swap(ref_count, other.ref_count);
+ }
+
+ T & operator*() const { return *pointer; }
+
+ T * operator->() const { return pointer; }
+
+ T * get() const { return pointer; }
+
+ int use_count() const
+ {
+ if (pointer != nullptr)
+ {
+ return *ref_count;
+ }
+
+ return 0;
+ }
+
+ bool unique() const { return use_count() == 1; }
+
+ explicit operator bool() const { return pointer != nullptr; }
+
+ private:
+ T * pointer;
+ std::atomic<int> * ref_count;
+ };
+
+ template<typename T, typename... Args>
+ shared_pointer<T> make_shared(Args &&... args)
+ {
+ return shared_pointer<T>(new T(std::forward<Args>(args)...));
+ }
+} // namespace teachos::arch::stl
+
+#endif // TEACHOS_ARCH_X86_64_STL_SHARED_POINTER_HPP \ No newline at end of file
diff --git a/arch/x86_64/include/arch/stl/unique_pointer.hpp b/arch/x86_64/include/arch/stl/unique_pointer.hpp
new file mode 100644
index 0000000..0ec3c38
--- /dev/null
+++ b/arch/x86_64/include/arch/stl/unique_pointer.hpp
@@ -0,0 +1,68 @@
+#ifndef TEACHOS_ARCH_X86_64_STL_UNIQUE_POINTER_HPP
+#define TEACHOS_ARCH_X86_64_STL_UNIQUE_POINTER_HPP
+
+namespace teachos::arch::stl
+{
+ template<typename T>
+ struct unique_pointer
+ {
+ explicit unique_pointer(T * ptr = nullptr)
+ : pointer(ptr)
+ {
+ }
+
+ ~unique_pointer() { delete pointer; }
+
+ unique_pointer(const unique_pointer &) = delete;
+ unique_pointer & operator=(const unique_pointer &) = delete;
+
+ unique_pointer(unique_pointer && other) noexcept
+ : pointer(other.pointer)
+ {
+ other.pointer = nullptr;
+ }
+
+ unique_pointer & operator=(unique_pointer && other) noexcept
+ {
+ if (this != &other)
+ {
+ delete pointer;
+ pointer = other.pointer;
+ other.pointer = nullptr;
+ }
+ return *this;
+ }
+
+ T & operator*() const { return *pointer; }
+
+ T * operator->() const { return pointer; }
+
+ T * get() const { return pointer; }
+
+ T * release()
+ {
+ T * temp = pointer;
+ pointer = nullptr;
+ return temp;
+ }
+
+ void reset(T * ptr = nullptr)
+ {
+ delete pointer;
+ pointer = ptr;
+ }
+
+ void swap(unique_pointer & other) { std::swap(pointer, other.pointer); }
+
+ private:
+ T * pointer;
+ };
+
+ template<typename T, typename... Args>
+ unique_pointer<T> make_unique(Args &&... args)
+ {
+ return unique_pointer<T>(new T(std::forward<Args>(args)...));
+ }
+} // namespace teachos::arch::stl
+
+#endif // TEACHOS_ARCH_X86_64_STL_UNIQUE_POINTER_HPP \ No newline at end of file