#include <iostream>
#include <omp.h>

class myclass {
    int *_n;
public:
    myclass(int n)  { 
        _n = (int *) malloc(sizeof(int));
        *_n = n;
    }

    myclass() { 
        _n = (int *) malloc(sizeof(int));
        *_n = 0;
    }

    myclass(const myclass & other)
    { 
        _n = (int *) malloc(sizeof(int));
        *_n = *other._n;
    }

    ~myclass() { 
        free(_n);
    }

    void print() { 
        std::cout << omp_get_thread_num() << ": " << *_n << "\n"; 
    }

    void add(int t) { 
        *_n += t; 
    }

    int get() {
        return *_n;
    }
};

myclass x;
#pragma omp threadprivate (x)

int main(int argc, char* argv[])
{
    int arr[4];
    omp_set_num_threads(4);

#pragma omp parallel
    {
        int myid = omp_get_thread_num();
        x.add(myid);
    }

#pragma omp parallel
    {
        int myid = omp_get_thread_num();
        arr[myid] = x.get();
    }

    for(int i = 0; i < 4; i++) {
        if(arr[i] == i)
            std::cout << "PASS" << std::endl;
        else
            std::cout << "FAIL" << std::endl;
    }

    return 0;
}
