Pointers!

This commit is contained in:
2023-10-21 19:04:49 +02:00
parent a2c05c4b7b
commit 4f975238ea
2 changed files with 160 additions and 163 deletions

View File

@@ -1,108 +1,111 @@
#ifndef POINTERS_H #ifndef POINTERS_H
#define POINTERS_H #define POINTERS_H
namespace SUSTL { #include <utility>
class SharedPtrTester;
template<typename T> #include "kmem.hpp"
class SharedPtr {
friend SharedPtrTester;
public:
SharedPtr() = default;
SharedPtr(T *data) : ptr(data), uses(new int(1)) {} class SharedPtrTester;
~SharedPtr() { template<typename T>
if (ptr == nullptr || uses == nullptr) return; class SharedPtr {
--(*uses); friend SharedPtrTester;
if (*uses == 0) {
delete ptr; public:
delete uses; 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) { SharedPtr(SharedPtr const &other) : ptr(other.ptr), uses(other.uses) {
++(*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<typename T>
class COWPointer {
private:
friend COWTester;
SharedPtr<T> ptr;
void copy() {
if (ptr.get() && ptr.useCount() > 1) {
ptr = SharedPtr<T>(new T(*ptr));
} }
}
SharedPtr(SharedPtr &&other) { public:
uses = other.uses; COWPointer() = default;
ptr = other.ptr;
other.uses = nullptr;
other.ptr = nullptr;
}
SharedPtr &operator=(SharedPtr other) { COWPointer(T *data) : ptr(data) {}
std::swap(ptr, other.ptr);
std::swap(uses, other.uses);
return *this;
}
T *operator->() const { return ptr; } COWPointer(SharedPtr<T> 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: ~COWPointer() = default;
T *ptr = nullptr;
int *uses = nullptr;
};
class COWTester; T *get() const {
return ptr.get();
}
template<typename T> T *getRW() {
class COWPointer { copy();
private: return ptr.get();
friend COWTester; }
SharedPtr<T> ptr;
void copy() { int useCount() { return ptr.useCount(); };
if (ptr.get() && ptr.useCount() > 1) {
ptr = SharedPtr<T>(new T(*ptr));
}
}
public: const T &operator*() const {
COWPointer() = default; return *ptr;
}
COWPointer(T *data) : ptr(data) {} const T *operator->() const {
return ptr.operator->();
}
};
COWPointer(SharedPtr<T> 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 #endif

View File

@@ -5,6 +5,7 @@
#include "TestTemplates.hpp" #include "TestTemplates.hpp"
#include "PointersCollection.hpp"
#include "SkipList.hpp" #include "SkipList.hpp"
#include "SkipListSet.hpp" #include "SkipListSet.hpp"
#include "String.hpp" #include "String.hpp"
@@ -13,82 +14,75 @@
#include "tty.hpp" #include "tty.hpp"
//#include "String.hpp" class SharedPtrTester {
//#include "String.hpp" private:
auto getThingy() {
return SharedPtr<Vector<String>>(
new Vector<String>{"Thingy1", "Thingy2", "Thingy3"});
}
//template<typename T> public:
//std::string toString(const T &x) { bool test() {
// std::ostringstream oss; SharedPtr<Vector<String>> test1(
// oss << x; new Vector<String>{"hello1", "hello2", "hello3"});
// return oss.str(); SharedPtr<Vector<String>> test2(getThingy());
//} assert((*test2 == Vector<String>{"Thingy1", "Thingy2", "Thingy3"}));
// auto test22 = test2;
//class SharedPtrTester { auto test12 = test1;
//private: test12->emplace_back("hello4");
// auto getThingy() { assert((*test1)[3] == "hello4");
// return SharedPtr<Vector<String>>( test22->erase(2);
// new Vector<String>{"Thingy1", "Thingy2", "Thingy3"}); assert(test2->size() == 2);
// } assert((*test2)[1] == "Thingy2");
//
//public: all_tty_putstr("SharedPtr tests ok!\n");
// bool test() { return true;
// SharedPtr<Vector<String>> test1( }
// new Vector<String>{"hello1", "hello2", "hello3"}); };
// SharedPtr<Vector<String>> test2(getThingy());
// assert((*test2 == Vector<String>{"Thingy1", "Thingy2", "Thingy3"})); class COWTester {
// auto test22 = test2; private:
// auto test12 = test1; auto getThingy() const {
// test12->emplace_back("hello4"); return COWPointer<Vector<String>>(
// assert((*test1)[3] == "hello4"); new Vector<String>{"Thingy1", "Thingy2", "Thingy3"});
// test22->erase(2); }
// assert(test2->size() == 2);
// assert((*test2)[1] == "Thingy2"); public:
// return true; bool test() const {
// } COWPointer<Vector<String>> test1(
//}; new Vector<String>{"hello1", "hello2", "hello3"});
// COWPointer<Vector<String>> test2(getThingy());
//class COWTester { assert((*test2.get() == Vector<String>{"Thingy1", "Thingy2", "Thingy3"}));
//private:
// auto getThingy() const { auto test22 = test2;
// return COWPointer<Vector<String>>( auto test12 = test1;
// new Vector<String>{"Thingy1", "Thingy2", "Thingy3"});
// } assert(test12.ptr.get() == test1.ptr.get());
// assert(test22.ptr.get() == test2.ptr.get());
//public: assert((*test2.get() == Vector<String>{"Thingy1", "Thingy2", "Thingy3"}));
// bool test() const { assert((*test22.get() == Vector<String>{"Thingy1", "Thingy2", "Thingy3"}));
// COWPointer<Vector<String>> test1( assert((*test1.get() == Vector<String>{"hello1", "hello2", "hello3"}));
// new Vector<String>{"hello1", "hello2", "hello3"}); assert((*test12.get() == Vector<String>{"hello1", "hello2", "hello3"}));
// COWPointer<Vector<String>> test2(getThingy()); assert(test12.ptr.get() == test1.ptr.get());
// assert((*test2.get() == Vector<String>{"Thingy1", "Thingy2", "Thingy3"})); assert(test22.ptr.get() == test2.ptr.get());
//
// auto test22 = test2; test12.getRW()->emplace_back("hello4");
// auto test12 = test1; assert(test1.get()->size() == 3);
// assert(test12.get()->size() == 4);
// assert(test12.ptr.get() == test1.ptr.get()); assert((*test12.get())[3] == "hello4");
// assert(test22.ptr.get() == test2.ptr.get()); test22.getRW()->erase(2);
// assert((*test2.get() == Vector<String>{"Thingy1", "Thingy2", "Thingy3"})); assert(test2.get()->size() == 3);
// assert((*test22.get() == Vector<String>{"Thingy1", "Thingy2", "Thingy3"})); assert(test22.get()->size() == 2);
// assert((*test1.get() == Vector<String>{"hello1", "hello2", "hello3"})); assert((*test22.get())[1] == "Thingy2");
// assert((*test12.get() == Vector<String>{"hello1", "hello2", "hello3"})); assert((*test2.get())[1] == "Thingy2");
// assert(test12.ptr.get() == test1.ptr.get());
// assert(test22.ptr.get() == test2.ptr.get()); assert(test12.ptr.get() != test1.ptr.get());
// assert(test22.ptr.get() != test2.ptr.get());
// test12.getRW()->emplace_back("hello4");
// assert(test1.get()->size() == 3); all_tty_putstr("COWPointer tests ok!\n");
// assert(test12.get()->size() == 4); return true;
// 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;
// }
//};
class VectorTester { class VectorTester {
public: public:
@@ -220,9 +214,9 @@ int test_templates() {
stringTester.test(); stringTester.test();
VectorTester vectorTester; VectorTester vectorTester;
vectorTester.test(); vectorTester.test();
// SharedPtrTester sharedPtrTester; SharedPtrTester sharedPtrTester;
// sharedPtrTester.test(); sharedPtrTester.test();
// COWTester cowTester; COWTester cowTester;
// cowTester.test(); cowTester.test();
return 0; return 0;
} }