hopefully not broken linked list queue

This commit is contained in:
2023-10-22 16:49:31 +02:00
parent b0ebd1d019
commit a7cf6d5b7b
3 changed files with 137 additions and 10 deletions

View File

@@ -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;
}
};

View File

@@ -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;

View File

@@ -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;
}