#include <atomic>
#include <string>
#include <iostream>

using namespace std;

class Stack {
public:
    Stack() : head_(nullptr) {}
    Stack(const Stack& ) = delete; //zabronione kopiowanie
    Stack& operator=(const Stack& ) = delete; //zabronione przypisywanie
    ~Stack() {
        for(Node* current = head_.load(); current != nullptr; current = head_.load() ) {
            Node* next = current->next;
            head_.compare_exchange_weak(current, next);
            cout << "D-tor delete" << current->value << endl;
            delete current;
        }
    }
    struct Node {
        string value;
        Node* next;
    };
    void push(string val) { //add element to stack
        Node* current_head = head_.load();
        Node* new_node = new Node {val, current_head};

        while (! head_.compare_exchange_weak(current_head, new_node))
            new_node->next = current_head;
    }
    string pop() { //remove element from stack. If stack is empty return empty string
        string out;
        Node* current_head = head_.load();
        if(!current_head)
            return out;

        Node* new_head = current_head->next;
        while (! head_.compare_exchange_weak(current_head,new_head)) {
            if(current_head) {//not null
                new_head = current_head->next;
            }
        }
        out = current_head->value;
        cout << "pop delete" << current_head->value << endl;
        delete current_head;
        return out;
    }

private:
    std::atomic<Node*> head_;
};

int main() {
    Stack s;
    s.push("A");
    s.push("B");
    cout << s.pop() << endl;
    cout << s.pop() << endl;
    cout << s.pop() << endl;
    return 0;
}
