mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-29 00:27:52 +01:00
Pointers!
This commit is contained in:
@@ -1,108 +1,111 @@
|
||||
#ifndef POINTERS_H
|
||||
#define POINTERS_H
|
||||
|
||||
namespace SUSTL {
|
||||
class SharedPtrTester;
|
||||
#include <utility>
|
||||
|
||||
template<typename T>
|
||||
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<typename T>
|
||||
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<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) {
|
||||
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<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:
|
||||
T *ptr = nullptr;
|
||||
int *uses = nullptr;
|
||||
};
|
||||
~COWPointer() = default;
|
||||
|
||||
class COWTester;
|
||||
T *get() const {
|
||||
return ptr.get();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class COWPointer {
|
||||
private:
|
||||
friend COWTester;
|
||||
SharedPtr<T> ptr;
|
||||
T *getRW() {
|
||||
copy();
|
||||
return ptr.get();
|
||||
}
|
||||
|
||||
void copy() {
|
||||
if (ptr.get() && ptr.useCount() > 1) {
|
||||
ptr = SharedPtr<T>(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<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
|
||||
@@ -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<Vector<String>>(
|
||||
new Vector<String>{"Thingy1", "Thingy2", "Thingy3"});
|
||||
}
|
||||
|
||||
//template<typename T>
|
||||
//std::string toString(const T &x) {
|
||||
// std::ostringstream oss;
|
||||
// oss << x;
|
||||
// return oss.str();
|
||||
//}
|
||||
//
|
||||
//class SharedPtrTester {
|
||||
//private:
|
||||
// auto getThingy() {
|
||||
// return SharedPtr<Vector<String>>(
|
||||
// new Vector<String>{"Thingy1", "Thingy2", "Thingy3"});
|
||||
// }
|
||||
//
|
||||
//public:
|
||||
// bool test() {
|
||||
// SharedPtr<Vector<String>> test1(
|
||||
// new Vector<String>{"hello1", "hello2", "hello3"});
|
||||
// SharedPtr<Vector<String>> test2(getThingy());
|
||||
// assert((*test2 == Vector<String>{"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<Vector<String>>(
|
||||
// new Vector<String>{"Thingy1", "Thingy2", "Thingy3"});
|
||||
// }
|
||||
//
|
||||
//public:
|
||||
// bool test() const {
|
||||
// COWPointer<Vector<String>> test1(
|
||||
// new Vector<String>{"hello1", "hello2", "hello3"});
|
||||
// COWPointer<Vector<String>> test2(getThingy());
|
||||
// assert((*test2.get() == Vector<String>{"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<String>{"Thingy1", "Thingy2", "Thingy3"}));
|
||||
// assert((*test22.get() == Vector<String>{"Thingy1", "Thingy2", "Thingy3"}));
|
||||
// assert((*test1.get() == Vector<String>{"hello1", "hello2", "hello3"}));
|
||||
// assert((*test12.get() == Vector<String>{"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<Vector<String>> test1(
|
||||
new Vector<String>{"hello1", "hello2", "hello3"});
|
||||
SharedPtr<Vector<String>> test2(getThingy());
|
||||
assert((*test2 == Vector<String>{"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<Vector<String>>(
|
||||
new Vector<String>{"Thingy1", "Thingy2", "Thingy3"});
|
||||
}
|
||||
|
||||
public:
|
||||
bool test() const {
|
||||
COWPointer<Vector<String>> test1(
|
||||
new Vector<String>{"hello1", "hello2", "hello3"});
|
||||
COWPointer<Vector<String>> test2(getThingy());
|
||||
assert((*test2.get() == Vector<String>{"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<String>{"Thingy1", "Thingy2", "Thingy3"}));
|
||||
assert((*test22.get() == Vector<String>{"Thingy1", "Thingy2", "Thingy3"}));
|
||||
assert((*test1.get() == Vector<String>{"hello1", "hello2", "hello3"}));
|
||||
assert((*test12.get() == Vector<String>{"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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user