#include #include template class lock_free_queue { private: struct node { std::shared_ptr data; node* next; node() : next(nullptr) {} }; std::atomic head; std::atomic tail; node* pop_head() { node* const old_head = head.load(); if (old_head == tail.load()) { return nullptr; } head.store(old_head->next); return old_head; } public: lock_free_queue() : head(new node), tail(head.load()) {} lock_free_queue(const lock_free_queue& other) = delete; lock_free_queue& operator=(const lock_free_queue& other) = delete; ~lock_free_queue() { while (node* const old_head = head.load()) { head.store(old_head->next); delete old_head; } } std::shared_ptr pop() { node* old_head = pop_head(); if (!old_head) { return std::shared_ptr(); } std::shared_ptr const res(old_head->data); delete old_head; return res; } void push(T new_value) { std::shared_ptr new_data(std::make_shared(new_value)); node* p = new node; node* const old_tail = tail.load(); old_tail->data.swap(new_data); old_tail->next = p; tail.store(p); } };