#include <iostream>
#include <vector>
#include <memory>
#include <string>

// ---------- Memento ----------
class Memento {
    friend class Editor; // Friend declaration, allows Editor to access private members
private:
    std::string state_;

    explicit Memento(const std::string& state) : state_(state) {}
    const std::string& getState() const { return state_; }
};

// ---------- Originator: Text Editor ----------
class Editor {
public:
    void type(const std::string& words) {
        content_ += words;
    }

    // Create memento (fixed: use new directly to avoid make_unique friend restrictions)
    std::unique_ptr<Memento> save() const {
        return std::unique_ptr<Memento>(new Memento(content_)); // ✅ allowed
    }

    void restore(const Memento& memento) {
        content_ = memento.getState();
    }

    void print() const {
        std::cout << "Current content: " << content_ << std::endl;
    }

private:
    std::string content_;
};

// ---------- Caretaker: History ----------
class History {
public:
    void push(std::unique_ptr<Memento> memento) {
        mementos_.push_back(std::move(memento));
    }

    const Memento* latest() const {
        return mementos_.empty() ? nullptr : mementos_.back().get();
    }

    void pop() {
        if (!mementos_.empty())
            mementos_.pop_back();
    }

private:
    std::vector<std::unique_ptr<Memento>> mementos_;
};

// ---------- Client Demo ----------
int main() {
    Editor editor;
    History history;

    std::cout << "=== Memento Pattern Demo ===" << std::endl;

    editor.type("Hello");
    editor.print();
    history.push(editor.save());

    editor.type(", world!");
    editor.print();

    std::cout << "Performing undo..." << std::endl;
    const Memento* last = history.latest();
    if (last) {
        editor.restore(*last);
        history.pop();
    }
    editor.print();

    editor.type("Hello, C++!");
    editor.print();
    history.push(editor.save());

    editor.type(" How are you?");
    editor.print();

    std::cout << "Undo again..." << std::endl;
    last = history.latest();
    if (last) {
        editor.restore(*last);
        history.pop();
    }
    editor.print();

    return 0;
}

results matching ""

    No results matching ""