#include <utility>
#include <queue>
#include <mutex>
#include <memory>
#include <iostream>
#include <condition_variable>
template<typename T>
class Node {
public:
Node() = default;
~Node() = default;
Node(const Node<T>& other) = delete;
Node<T>& operator=(const Node<T>& other) = delete;
Node(std::shared_ptr<T> data_, std::unique_ptr<Node<T>>&& next_ = nullptr)
:data{ data_ },
next{ std::move(next) }
{
//
}
Node(Node<T>&& other)
:data{ std::move(other.data) },
next{ std::move(other.next) }
{
//move-constructor.
}
Node<T>& operator=(Node<T>&& other)
{
this->data = std::move(other.data);
this->next = std::move(other.next);
(other.next).reset(nullptr);
return *this;
}
std::shared_ptr<T> data{ nullptr };
std::unique_ptr<Node<T>> next{ nullptr };
};
//先进先出(FIFO)
template<typename T>
class Queue {
public:
//注意在默认构造函数的情况下:
//创建了一个 empty的 node. 此时首尾都指向这个node.
Queue()
:head{ new Node<T>{} },
tail{ head.get() }
{
//default constructor.
}
template<typename ...Types>
Queue(Types&&... args);
Queue(const Queue<T>&) = delete;
Queue<T>& operator=(const Queue<T>&) = delete;
void push(const T& value);
void push(T&& value);
bool try_pop(T& value);
std::shared_ptr<T> try_pop();
bool wait_pop(T& value);
std::shared_ptr<T> wait_pop();
bool empty();
private:
//用于构造函数.
template<typename Ty, typename ...Types>
void initialList(Ty&& value, Types&&... args);
template<typename Ty>
void initialList(Ty&& value);
inline Node<T>* getTail()
{
std::lock_guard<std::mutex> lock(this->tailM);
return (this->tail);
}
mutable std::mutex headM{};
mutable std::mutex tailM{};
mutable std::condition_variable conVar{};
std::unique_ptr<Node<T>> head{nullptr}; //队列头部.
Node<T>* tail{}; //队列尾部.
};
template<typename T>
template<typename ...Types>
Queue<T>::Queue(Types&&... args)
:head{ new Node<T>{} },
tail{head.get()}
{
std::lock(this->headM, this->tailM);
std::lock_guard<std::mutex>(this->headM, std::adopt_lock);
std::lock_guard<std::mutex>(this->tailM, std::adopt_lock);
this->initialList(std::forward<Types>(args)...);
}
template<typename T>
template<typename Ty>
void Queue<T>::initialList(Ty&& value)
{
std::shared_ptr<T> nodeData{ std::make_shared<T>(std::forward<Ty>(value)) };
std::unique_ptr<Node<T>> node{ new Node<T>{} };
(this->tail)->data = nodeData;
Node<T>* newTail = node.get();
(this->tail)->next = std::move(node);
(this->tail) = newTail;
newTail = nullptr;
}
template<typename T>
template<typename Ty, typename ...Types>
void Queue<T>::initialList(Ty&& value, Types&&... args)
{
//向queue中插入数据.
this->initialList(std::forward<Ty>(value));
this->initialList(std::forward<Types>(args)...);
}
//删除顶部元素并把被删除的值保存到value中.
template<typename T>
bool Queue<T>::try_pop(T& value)
{
std::lock(this->headM, this->tailM);
std::lock_guard<std::mutex> lockOne{ this->headM, std::adopt_lock };
if ((this->head).get() == this->getTail()) {
return false;
}
std::unique_ptr<Node<T>> oldHead{ std::move(this->head) };
value = std::move(*(oldHead->data));
this->head = std::move(oldHead->next);
return true;
return oldHead;
}
//删除顶部元素并返回被删除的值.
template<typename T>
std::shared_ptr<T> Queue<T>::try_pop()
{
std::lock(this->headM);
std::lock_guard<std::mutex> lockOne(this->headM, std::adopt_lock);
if ((this->head).get() == this->getTail());
std::unique_ptr<Node<T>> oldHead{ std::move(this->head) };
std::shared_ptr<T> nodeData{ std::move(oldHead->data) };
this->head = std::move(oldHead->next);
return nodeData;
}
template<typename T>
bool Queue<T>::empty()
{
std::lock_guard<std::mutex>(this->headM);
if ((this->head).get() == (this->getTail())) {
return true;
}
return false;
}
template<typename T>
bool Queue<T>::wait_pop(T& value)
{
std::shared_ptr<T> ptrValue{ this->wait_pop() };
if (ptrValue == nullptr) {
return false;
} else {
value = std::move(*ptrValue);
return true;
}
}
template<typename T>
void Queue<T>::push(const T& value)
{
std::shared_ptr<T> nodeData{ std::make_shared<T>(value) };
std::unique_ptr<Node<T>> node{ new Node<T>{} };
{
std::lock_guard<std::mutex> lockGuard(this->tailM);
(this->tail)->data = nodeData;
Node<T>* newTail = node.get();
(this->tail)->next = std::move(node);
this->tail = newTail;
newTail = nullptr;
}
(this->conVar).notify_one();
}
template<typename T>
void Queue<T>::push(T&& value)
{
std::shared_ptr<T> nodeData{ std::make_shared<T>(std::move(value)) };
std::unique_ptr<Node<T>> node{ new Node<T>{} };
{
std::lock_guard<std::mutex> lockGuard{ this->tailM };
(this->tail)->data = nodeData;
Node<T>* newTail = node.get();
(this->tail)->next = std::move(node);
this->tail = newTail;
newTail = nullptr;
}
(this->conVar).notify_one();
}
template<typename T>
std::shared_ptr<T> Queue<T>::wait_pop()
{
std::unique_ptr<std::mutex> uniqueLck(this->headM);
(this->conVar).wait(this->headM, [] {return ((this->head.get() == this->getTal()) ? false, true); });
std::shared_ptr<T> value{ std::move((this->head)->data) };
this->head = std::move((this->head)->next);
return value;
}
int main()
{
Queue<int> que{ 1, 2, 3, 4 };
std::cout << que.empty() << std::endl;
que.push(20);
return 0;
}