#include <thread>
#include <string>
#include <iostream>
#include <chrono>
#include <vector>
#include <functional>

/*
 * Compile with 'g++ -pthread a.cpp'
 *
 * Modifying an object
 */

using namespace std;

/*
 * This method will push the addition of the last two elements on the vector.
 */
void manipulate(vector<double>& v) {
	int sleep = 2;
	for ( int i = 0; i < 5; i++ )
	{
		double a = 0;

		// Only use the last two elements
		int j = 0;
		for ( auto rit = v.rbegin() ; rit != v.rend(); ++rit )
		{
			if ( j > 1 )
			{
				break;
			}

			a += *rit;
			++j;
		}

		v.push_back( a);
		std::cout << "Updated Vector" << std::endl;

		this_thread::sleep_for(std::chrono::seconds(sleep));
	}
}

void display(vector<double>& v) {
	int sleep = 1;
	for ( int i = 0; i < 10; i++ )
	{
		std::cout << "Vector is now:" << std::endl;

		std::cout << "{";
		for ( int i = 0; i < v.size() ; i++ ) {
			std::cout << v[i] << ", ";
		}
		std::cout << "}" << std::endl;
		this_thread::sleep_for(std::chrono::seconds(sleep));
	}
}


struct my_f {
	vector<double>& v;

	my_f(vector<double>& vv): v(vv) {};
	void my_function() { manipulate(v); };
};

int main() {

	vector<double> v { 1.1, 1.1 };
	thread t {display, ref(v)};

	my_f f{v};	
	thread t2( &my_f::my_function, std::ref(f) );


	// Run the threads
	t.join();
	t2.join();

	return 0;
}
