From 462a4e09b1a67562dd1a122936c1ad0fc1771e0e Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 27 Feb 2025 07:15:03 +0000 Subject: add smart pointers --- arch/x86_64/include/arch/stl/shared_pointer.hpp | 120 ++++++++++++++++++++++++ arch/x86_64/include/arch/stl/unique_pointer.hpp | 68 ++++++++++++++ 2 files changed, 188 insertions(+) create mode 100644 arch/x86_64/include/arch/stl/shared_pointer.hpp create mode 100644 arch/x86_64/include/arch/stl/unique_pointer.hpp 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 + struct shared_pointer + { + explicit shared_pointer(T * pointer = nullptr) + : pointer(pointer) + , ref_count(new std::atomic(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(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 * ref_count; + }; + + template + shared_pointer make_shared(Args &&... args) + { + return shared_pointer(new T(std::forward(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 + 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 + unique_pointer make_unique(Args &&... args) + { + return unique_pointer(new T(std::forward(args)...)); + } +} // namespace teachos::arch::stl + +#endif // TEACHOS_ARCH_X86_64_STL_UNIQUE_POINTER_HPP \ No newline at end of file -- cgit v1.2.3