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
|
#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
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user