#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
using namespace std::chrono;

struct wallet {
    mutex m;
    uint64_t money = 0;
    operator uint64_t() const { return money; }

    wallet& operator++() {
        m.lock();
        ++money;
        m.unlock();

        // {
        //     scoped_lock lck{m};
        //     ++money;
        // }

        return *this;
    }
};

void f(wallet& sum, uint64_t count) {
    while (count--) {
        ++sum;
    }
}

int main() {
    constexpr uint64_t count = 1'000'000;
    wallet sum;

    auto time0 = high_resolution_clock::now();

    thread t1 { f, ref(sum), count };
    thread t2 { f, ref(sum), count };
    t1.join();
    t2.join();

    // {
    //     jthread t1 { f, ref(sum), count };
    //     jthread t2 { f, ref(sum), count };
    // }

    auto time1 = high_resolution_clock::now();
    auto dt = duration_cast<microseconds>(time1 - time0);
    cout << "elapsed: " << dt.count() << " microsec\n";
    cout << "result: " << sum << '\n';
}

/*

Lecture outline:

1. std::thread and std::mutex

2. std::scoped_lock

3. std::jthread
 
*/
