mirror of
https://github.com/usatiuk/ficus.git
synced 2025-10-29 00:27:52 +01:00
hopefully not broken linked list queue
This commit is contained in:
@@ -5,20 +5,67 @@
|
||||
#ifndef OS2_LISTQUEUE_HPP
|
||||
#define OS2_LISTQUEUE_HPP
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
#include "serial.hpp"
|
||||
|
||||
template<typename T>
|
||||
class ListQueue {
|
||||
public:
|
||||
ListQueue() {
|
||||
}
|
||||
|
||||
private:
|
||||
struct Node {
|
||||
T val;
|
||||
Node *next;
|
||||
};
|
||||
Node *head;
|
||||
Node *tail;
|
||||
|
||||
Node *head = nullptr;
|
||||
Node *tail = nullptr;
|
||||
|
||||
public:
|
||||
ListQueue() = default;
|
||||
|
||||
template<class... Args>
|
||||
void emplace_front(Args &&...args) {
|
||||
emplace_front(new Node{std::forward<Args>(args)..., nullptr});
|
||||
}
|
||||
|
||||
void emplace_front(Node *new_node) {
|
||||
if (head) {
|
||||
assert(tail != nullptr);
|
||||
head->next = new_node;
|
||||
head = new_node;
|
||||
} else {
|
||||
head = new_node;
|
||||
tail = new_node;
|
||||
}
|
||||
}
|
||||
|
||||
T &back() {
|
||||
if (tail != nullptr) return tail->val;
|
||||
|
||||
assert(false);
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
if (!head) return;
|
||||
|
||||
if (tail == head) {
|
||||
delete tail;
|
||||
tail = nullptr;
|
||||
head = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
auto old_tail = tail;
|
||||
tail = tail->next;
|
||||
delete old_tail;
|
||||
}
|
||||
|
||||
bool empty() {
|
||||
assert((tail == nullptr) == (head == nullptr));
|
||||
return head == nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,39 @@
|
||||
|
||||
class SharedPtrTester;
|
||||
|
||||
template<typename T>
|
||||
class UniquePtr {
|
||||
public:
|
||||
UniquePtr() = default;
|
||||
|
||||
template<class... Args>
|
||||
explicit UniquePtr(Args &&...args) : ptr(new T(std::forward<Args>(args)...)) {}
|
||||
|
||||
explicit UniquePtr(T *data) : ptr(data) {}
|
||||
|
||||
~UniquePtr() {
|
||||
if (ptr == nullptr) return;
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
UniquePtr(UniquePtr const &other) = delete;
|
||||
UniquePtr &operator=(UniquePtr other) = delete;
|
||||
|
||||
UniquePtr(UniquePtr &&other) {
|
||||
ptr = other.ptr;
|
||||
other.ptr = nullptr;
|
||||
}
|
||||
|
||||
T *operator->() const { return ptr; }
|
||||
|
||||
T &operator*() const { return *ptr; }
|
||||
|
||||
T *get() const noexcept { return ptr; }
|
||||
|
||||
private:
|
||||
T *ptr = nullptr;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class SharedPtr {
|
||||
friend SharedPtrTester;
|
||||
@@ -14,7 +47,7 @@ class SharedPtr {
|
||||
public:
|
||||
SharedPtr() = default;
|
||||
|
||||
SharedPtr(T *data) : ptr(data), uses(new int(1)) {}
|
||||
explicit SharedPtr(T *data) : ptr(data), uses(new int(1)) {}
|
||||
|
||||
~SharedPtr() {
|
||||
if (ptr == nullptr || uses == nullptr) return;
|
||||
@@ -48,7 +81,7 @@ public:
|
||||
|
||||
T *get() const noexcept { return ptr; }
|
||||
|
||||
int useCount() const { return *uses; }
|
||||
[[nodiscard]] int useCount() const { return *uses; }
|
||||
|
||||
private:
|
||||
T *ptr = nullptr;
|
||||
@@ -72,9 +105,9 @@ private:
|
||||
public:
|
||||
COWPointer() = default;
|
||||
|
||||
COWPointer(T *data) : ptr(data) {}
|
||||
explicit COWPointer(T *data) : ptr(data) {}
|
||||
|
||||
COWPointer(SharedPtr<T> data) : ptr(std::move(data)) {}
|
||||
explicit COWPointer(SharedPtr<T> data) : ptr(std::move(data)) {}
|
||||
|
||||
COWPointer(COWPointer &&other) = default;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "TestTemplates.hpp"
|
||||
|
||||
|
||||
#include "ListQueue.hpp"
|
||||
#include "PointersCollection.hpp"
|
||||
#include "SkipList.hpp"
|
||||
#include "SkipListSet.hpp"
|
||||
@@ -204,6 +205,50 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void test_unique_ptr() {
|
||||
UniquePtr<String> ptr("Hello");
|
||||
assert(*ptr == "Hello");
|
||||
}
|
||||
|
||||
void test_list_queue() {
|
||||
ListQueue<int> lq;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
assert(lq.empty());
|
||||
lq.emplace_front(1);
|
||||
assert(!lq.empty());
|
||||
assert(lq.back() == 1);
|
||||
lq.pop_back();
|
||||
|
||||
assert(lq.empty());
|
||||
lq.emplace_front(2);
|
||||
lq.emplace_front(3);
|
||||
assert(!lq.empty());
|
||||
assert(lq.back() == 2);
|
||||
lq.pop_back();
|
||||
assert(!lq.empty());
|
||||
assert(lq.back() == 3);
|
||||
lq.pop_back();
|
||||
assert(lq.empty());
|
||||
|
||||
assert(lq.empty());
|
||||
lq.emplace_front(2);
|
||||
lq.emplace_front(3);
|
||||
assert(!lq.empty());
|
||||
assert(lq.back() == 2);
|
||||
lq.pop_back();
|
||||
assert(!lq.empty());
|
||||
assert(lq.back() == 3);
|
||||
lq.emplace_front(4);
|
||||
assert(!lq.empty());
|
||||
assert(lq.back() == 3);
|
||||
lq.pop_back();
|
||||
assert(!lq.empty());
|
||||
assert(lq.back() == 4);
|
||||
lq.pop_back();
|
||||
assert(lq.empty());
|
||||
}
|
||||
}
|
||||
|
||||
int test_templates() {
|
||||
|
||||
SkipListTester SLTester;
|
||||
@@ -218,5 +263,7 @@ int test_templates() {
|
||||
sharedPtrTester.test();
|
||||
COWTester cowTester;
|
||||
cowTester.test();
|
||||
test_unique_ptr();
|
||||
test_list_queue();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user