diff --git a/src/kernel/templates/PointersCollection.hpp b/src/kernel/templates/PointersCollection.hpp index 9c641150e..be492c7f0 100644 --- a/src/kernel/templates/PointersCollection.hpp +++ b/src/kernel/templates/PointersCollection.hpp @@ -1,108 +1,111 @@ #ifndef POINTERS_H #define POINTERS_H -namespace SUSTL { - class SharedPtrTester; +#include - template - class SharedPtr { - friend SharedPtrTester; - public: - SharedPtr() = default; +#include "kmem.hpp" - SharedPtr(T *data) : ptr(data), uses(new int(1)) {} +class SharedPtrTester; - ~SharedPtr() { - if (ptr == nullptr || uses == nullptr) return; - --(*uses); - if (*uses == 0) { - delete ptr; - delete uses; - } +template +class SharedPtr { + friend SharedPtrTester; + +public: + SharedPtr() = default; + + SharedPtr(T *data) : ptr(data), uses(new int(1)) {} + + ~SharedPtr() { + if (ptr == nullptr || uses == nullptr) return; + --(*uses); + if (*uses == 0) { + delete ptr; + delete uses; } + } - SharedPtr(SharedPtr const &other) : ptr(other.ptr), uses(other.uses) { - ++(*uses); + SharedPtr(SharedPtr const &other) : ptr(other.ptr), uses(other.uses) { + ++(*uses); + } + + SharedPtr(SharedPtr &&other) { + uses = other.uses; + ptr = other.ptr; + other.uses = nullptr; + other.ptr = nullptr; + } + + SharedPtr &operator=(SharedPtr other) { + std::swap(ptr, other.ptr); + std::swap(uses, other.uses); + return *this; + } + + T *operator->() const { return ptr; } + + T &operator*() const { return *ptr; } + + T *get() const noexcept { return ptr; } + + int useCount() const { return *uses; } + +private: + T *ptr = nullptr; + int *uses = nullptr; +}; + +class COWTester; + +template +class COWPointer { +private: + friend COWTester; + SharedPtr ptr; + + void copy() { + if (ptr.get() && ptr.useCount() > 1) { + ptr = SharedPtr(new T(*ptr)); } + } - SharedPtr(SharedPtr &&other) { - uses = other.uses; - ptr = other.ptr; - other.uses = nullptr; - other.ptr = nullptr; - } +public: + COWPointer() = default; - SharedPtr &operator=(SharedPtr other) { - std::swap(ptr, other.ptr); - std::swap(uses, other.uses); - return *this; - } + COWPointer(T *data) : ptr(data) {} - T *operator->() const { return ptr; } + COWPointer(SharedPtr data) : ptr(std::move(data)) {} - T &operator*() const { return *ptr; } + COWPointer(COWPointer &&other) = default; - T *get() const noexcept { return ptr; } + COWPointer(COWPointer const &data) = default; - int useCount() const { return *uses; } + COWPointer &operator=(COWPointer other) { + std::swap(ptr, other.ptr); + return *this; + } - private: - T *ptr = nullptr; - int *uses = nullptr; - }; + ~COWPointer() = default; - class COWTester; + T *get() const { + return ptr.get(); + } - template - class COWPointer { - private: - friend COWTester; - SharedPtr ptr; + T *getRW() { + copy(); + return ptr.get(); + } - void copy() { - if (ptr.get() && ptr.useCount() > 1) { - ptr = SharedPtr(new T(*ptr)); - } - } + int useCount() { return ptr.useCount(); }; - public: - COWPointer() = default; + const T &operator*() const { + return *ptr; + } - COWPointer(T *data) : ptr(data) {} + const T *operator->() const { + return ptr.operator->(); + } +}; - COWPointer(SharedPtr data) : ptr(std::move(data)) {} - - COWPointer(COWPointer &&other) = default; - - COWPointer(COWPointer const &data) = default; - - COWPointer &operator=(COWPointer other) { - std::swap(ptr, other.ptr); - return *this; - } - - ~COWPointer() = default; - - T *get() const { - return ptr.get(); - } - - T *getRW() { - copy(); - return ptr.get(); - } - - int useCount() { return ptr.useCount(); }; - - const T &operator*() const { - return *ptr; - } - - const T *operator->() const { - return ptr.operator->(); - } - - }; -} #endif \ No newline at end of file diff --git a/src/kernel/templates/TestTemplates.cpp b/src/kernel/templates/TestTemplates.cpp index e1bd14b92..ce1f26fab 100644 --- a/src/kernel/templates/TestTemplates.cpp +++ b/src/kernel/templates/TestTemplates.cpp @@ -5,6 +5,7 @@ #include "TestTemplates.hpp" +#include "PointersCollection.hpp" #include "SkipList.hpp" #include "SkipListSet.hpp" #include "String.hpp" @@ -13,82 +14,75 @@ #include "tty.hpp" -//#include "String.hpp" -//#include "String.hpp" +class SharedPtrTester { +private: + auto getThingy() { + return SharedPtr>( + new Vector{"Thingy1", "Thingy2", "Thingy3"}); + } -//template -//std::string toString(const T &x) { -// std::ostringstream oss; -// oss << x; -// return oss.str(); -//} -// -//class SharedPtrTester { -//private: -// auto getThingy() { -// return SharedPtr>( -// new Vector{"Thingy1", "Thingy2", "Thingy3"}); -// } -// -//public: -// bool test() { -// SharedPtr> test1( -// new Vector{"hello1", "hello2", "hello3"}); -// SharedPtr> test2(getThingy()); -// assert((*test2 == Vector{"Thingy1", "Thingy2", "Thingy3"})); -// auto test22 = test2; -// auto test12 = test1; -// test12->emplace_back("hello4"); -// assert((*test1)[3] == "hello4"); -// test22->erase(2); -// assert(test2->size() == 2); -// assert((*test2)[1] == "Thingy2"); -// return true; -// } -//}; -// -//class COWTester { -//private: -// auto getThingy() const { -// return COWPointer>( -// new Vector{"Thingy1", "Thingy2", "Thingy3"}); -// } -// -//public: -// bool test() const { -// COWPointer> test1( -// new Vector{"hello1", "hello2", "hello3"}); -// COWPointer> test2(getThingy()); -// assert((*test2.get() == Vector{"Thingy1", "Thingy2", "Thingy3"})); -// -// auto test22 = test2; -// auto test12 = test1; -// -// assert(test12.ptr.get() == test1.ptr.get()); -// assert(test22.ptr.get() == test2.ptr.get()); -// assert((*test2.get() == Vector{"Thingy1", "Thingy2", "Thingy3"})); -// assert((*test22.get() == Vector{"Thingy1", "Thingy2", "Thingy3"})); -// assert((*test1.get() == Vector{"hello1", "hello2", "hello3"})); -// assert((*test12.get() == Vector{"hello1", "hello2", "hello3"})); -// assert(test12.ptr.get() == test1.ptr.get()); -// assert(test22.ptr.get() == test2.ptr.get()); -// -// test12.getRW()->emplace_back("hello4"); -// assert(test1.get()->size() == 3); -// assert(test12.get()->size() == 4); -// assert((*test12.get())[3] == "hello4"); -// test22.getRW()->erase(2); -// assert(test2.get()->size() == 3); -// assert(test22.get()->size() == 2); -// assert((*test22.get())[1] == "Thingy2"); -// assert((*test2.get())[1] == "Thingy2"); -// -// assert(test12.ptr.get() != test1.ptr.get()); -// assert(test22.ptr.get() != test2.ptr.get()); -// -// return true; -// } -//}; +public: + bool test() { + SharedPtr> test1( + new Vector{"hello1", "hello2", "hello3"}); + SharedPtr> test2(getThingy()); + assert((*test2 == Vector{"Thingy1", "Thingy2", "Thingy3"})); + auto test22 = test2; + auto test12 = test1; + test12->emplace_back("hello4"); + assert((*test1)[3] == "hello4"); + test22->erase(2); + assert(test2->size() == 2); + assert((*test2)[1] == "Thingy2"); + + all_tty_putstr("SharedPtr tests ok!\n"); + return true; + } +}; + +class COWTester { +private: + auto getThingy() const { + return COWPointer>( + new Vector{"Thingy1", "Thingy2", "Thingy3"}); + } + +public: + bool test() const { + COWPointer> test1( + new Vector{"hello1", "hello2", "hello3"}); + COWPointer> test2(getThingy()); + assert((*test2.get() == Vector{"Thingy1", "Thingy2", "Thingy3"})); + + auto test22 = test2; + auto test12 = test1; + + assert(test12.ptr.get() == test1.ptr.get()); + assert(test22.ptr.get() == test2.ptr.get()); + assert((*test2.get() == Vector{"Thingy1", "Thingy2", "Thingy3"})); + assert((*test22.get() == Vector{"Thingy1", "Thingy2", "Thingy3"})); + assert((*test1.get() == Vector{"hello1", "hello2", "hello3"})); + assert((*test12.get() == Vector{"hello1", "hello2", "hello3"})); + assert(test12.ptr.get() == test1.ptr.get()); + assert(test22.ptr.get() == test2.ptr.get()); + + test12.getRW()->emplace_back("hello4"); + assert(test1.get()->size() == 3); + assert(test12.get()->size() == 4); + assert((*test12.get())[3] == "hello4"); + test22.getRW()->erase(2); + assert(test2.get()->size() == 3); + assert(test22.get()->size() == 2); + assert((*test22.get())[1] == "Thingy2"); + assert((*test2.get())[1] == "Thingy2"); + + assert(test12.ptr.get() != test1.ptr.get()); + assert(test22.ptr.get() != test2.ptr.get()); + + all_tty_putstr("COWPointer tests ok!\n"); + return true; + } +}; class VectorTester { public: @@ -220,9 +214,9 @@ int test_templates() { stringTester.test(); VectorTester vectorTester; vectorTester.test(); - // SharedPtrTester sharedPtrTester; - // sharedPtrTester.test(); - // COWTester cowTester; - // cowTester.test(); + SharedPtrTester sharedPtrTester; + sharedPtrTester.test(); + COWTester cowTester; + cowTester.test(); return 0; }