#include <iostream>
#include <memory>
#include <utility>

struct Trace {
    int value;
    explicit Trace(int initial) : value{initial} {}
    ~Trace() {
        std::cout << "destroy " << value << '\n';
    }
};

void borrow(const Trace& value) {
    std::cout << "borrow " << value.value << '\n';
}

void consume(std::unique_ptr<Trace> owner) {
    if (!owner) {
        std::cout << "empty\n";
        return;
    }
    std::cout << "consume " << owner->value << '\n';
}

int main() {
    auto zero = std::make_unique<Trace>(0);
    borrow(*zero);
    consume(std::move(zero));
    std::cout << "caller empty " << (zero == nullptr) << '\n';
    auto nine = std::make_unique<Trace>(9);
    borrow(*nine);
    consume(std::move(nine));
    std::cout << "caller empty " << (nine == nullptr) << '\n';
    std::unique_ptr<Trace> empty;
    consume(std::move(empty));
    return 0;
}
