#include <iostream>
#include <iomanip>
#include <chrono>
#include <limits>
#include <omp.h> // OMP functions
#include <mutex>
std::mutex m1;
std::string concatenate( std::string a, std::string b ) { // a is the total
m1.lock();
std::cout << a << " + " << b << " = ";
std::string r = a+b;
std::cout << r << std::endl;
m1.unlock();
return r;
}
#pragma omp declare reduction \
(concatenate:std::string:omp_out=concatenate(omp_out,omp_in)) \
initializer(omp_priv="")
// user defined types are OK too
int main()
{
std::string m;
#pragma omp parallel for reduction(concatenate:m) schedule(static,5)
for ( int i=0; i<50; ++i ) {
std::string s = " ";
s += std::to_string(i);
m = concatenate( m, s );
}
std::cout << m << std::endl;
}