#ifndef hp_h #define hp_h #include "hazard_pointer.h" template class stack { public: ~stack() { while (pop()); } void push(T t) { node *new_node = new node(head.load(std::memory_order_relaxed), std::move(t)); while (!head.compare_exchange_weak(new_node->next, new_node, std::memory_order_release, std::memory_order_relaxed)); } std::optional pop() { as::hazard_pointer hp = as::make_hazard_pointer(); node *current; while (true) { current = hp.protect(head); if (!current) return std::nullopt; if (head.compare_exchange_weak(current, current->next, std::memory_order_acquire, std::memory_order_relaxed)) { break; } } T result = std::move(current->data); current->retire(); return result; } private: struct node: public as::hazard_pointer_obj_base { node *next; T data; node(node *n, T t): next(n), data(std::move(t)) {} }; std::atomic head{nullptr}; }; #endif // hp_h