#pragma once
#include <algorithm>
#include <cstddef>
#include <stdexcept>
template<typename T>
class Queue {
public:
explicit Queue(const size_t capacity = 4) : capacity(capacity), size(0),
data(new std::byte[capacity * sizeof(T)]) {
}
virtual ~Queue() {
for (size_t i = 0; i < size; i++) {
reinterpret_cast<T*>(data)[i].~T();
}
delete[] data;
}
void Push(const T&value) {
std::unique_lock lock(mutex);
if (capacity <= size) {
capacity *= 2;
auto* newData = new std::byte[sizeof(T) * capacity];
for (size_t i = 0; i < size; i++) {
new (newData + i * sizeof(T)) T(std::move(reinterpret_cast<T*>(data)[i]));
reinterpret_cast<T*>(data)[i].~T();
}
delete[] data;
data = newData;
}
new(data + size * sizeof(T)) T(value);
size++;
}
void Pop(T&value) {
std::unique_lock lock(mutex);
if (size == 0) {
throw std::out_of_range("Queue::Pop() when size = 0");
}
size--;
value = std::move(*reinterpret_cast<T *>(data + sizeof(T)));
}
T Pop() {
std::unique_lock lock(mutex);
if (size == 0) {
throw std::out_of_range("Queue::Pop() when size = 0");
}
size--;
return std::move(*reinterpret_cast<T *>(data + sizeof(T) * size));
}
void Clear() {
std::unique_lock lock(mutex);
for (size_t i = 0; i < size; i++) {
reinterpret_cast<T*>(data + i * sizeof(T))->~T();
}
size = 0;
}
[[nodiscard]] size_t Size() const {
return size;
}
[[nodiscard]] size_t Capacity() const {
return capacity;
}
[[nodiscard]] bool Empty() const {
return size == 0;
}
private:
std::byte* data;
size_t size;
size_t capacity;
std::mutex mutex;
};
C++ 线程安全队列
最新推荐文章于 2024-09-09 06:45:00 发布