template class lock_free_stack { private: void increase_head_count(counted_node_ptr& old_counter) { counted_node_ptr new_counter; do { new_counter = old_counter; ++new_counter.external_count; } while (!head.compare_exchange_strong(old_counter, new_counter)); old_counter.external_count = new_counter.external_count; } public: std::shared_ptr pop() { counted_node_ptr old_head = head.load(); for (;;) { increase_head_count(old_head); node* const ptr = old_head.ptr; if (!ptr) { return std::shared_ptr(); } if (head.compare_exchange_strong(old_head, ptr->next)) { std::shared_ptr res; res.swap(ptr->data); int const count_increase = old_head.external_count - 2; if (ptr->internal_count.fetch_add(count_increase) == -count_increase) { delete ptr; } return res; } else if (ptr->internal_count.fetch_sub(1) == 1) { delete ptr; } } } };