#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
#include <vector>
using namespace std;

class barrier {
public:
    barrier(int n): teller(n) {
    }
    void wait() {
        unique_lock<mutex> lock(m);
        --teller;
        while (teller > 0) {
            c.wait(lock);
        }
        c.notify_one();
    }
private:
    int teller;
    mutex m;
    condition_variable c;
};

void task(int delay, barrier& b, mutex& m) {
    auto id(this_thread::get_id());
    {
        lock_guard<mutex> g(m);
        cout << "Thread " << id << " gestart" << endl;
    }
    this_thread::sleep_for(chrono::seconds(delay));
    {
        lock_guard<mutex> g(m);
        cout << "Thread " << id << " wordt wakker" << endl;
    }
    b.wait();
    {
        lock_guard<mutex> g(m);
        cout << "Thread " << id << " passeert barrier" << endl;
    }
}

int main() {
    int n;
    do {
        cout << "Geef het aantal threads (1..99): ";
        cin >> n;
    } while (n < 1 || n > 99);

    vector<thread> t;
    barrier b(n);
    mutex m;

    for (int i = 0; i < n; ++i) {
        t.push_back(thread(&task, i + 1, ref(b), ref(m))); 
    }

    for (auto& e: t) {
        e.join(); 
    }

    cin.get(); cin.get();
    return 0; 
}
