// Tipo para las pruebas: cuenta cuántos objetos viven y cuántas copias y movimientos hubo.
#ifndef TRACKED_H
#define TRACKED_H

#include <utility>

class Tracked {
public:
    struct Counts {
        long live = 0;
        long copies = 0;
        long moves = 0;
    };

    static Counts& counts() {
        static Counts values;
        return values;
    }

    Tracked() { counts().live++; }
    explicit Tracked(int value) : value_(value) { counts().live++; }
    Tracked(const Tracked& other) : value_(other.value_) {
        counts().live++;
        counts().copies++;
    }
    Tracked(Tracked&& other) noexcept : value_(std::exchange(other.value_, 0)) {
        counts().live++;
        counts().moves++;
    }
    Tracked& operator=(const Tracked& other) {
        value_ = other.value_;
        counts().copies++;
        return *this;
    }
    Tracked& operator=(Tracked&& other) noexcept {
        value_ = std::exchange(other.value_, 0);
        counts().moves++;
        return *this;
    }
    ~Tracked() { counts().live--; }

    int value() const { return value_; }
    bool operator==(const Tracked& other) const { return value_ == other.value_; }

private:
    int value_ = 0;
};

#endif
