#include <iostream>

struct copy_me
{
	int i;

	copy_me(int i) : i(i) { std::cout << "ctor" << std::endl; }
	copy_me(const copy_me& r) : i(r.i) { std::cout << "copy ctor" << std::endl; }
	copy_me(copy_me&& r) : i(r.i) { std::cout << "move ctor" << std::endl; }
	~copy_me() { std::cout << "dtor" << std::endl; }

	copy_me& operator =(const copy_me& r) { i = r.i; std::cout << "copy assgn" << std::endl; return *this; }
	copy_me& operator =(copy_me&& r) { i = r.i; std::cout << "move assgn" << std::endl; return *this; }
};

copy_me copy_elision()
{
	copy_me test(10);
	
	int abc = std::rand();
	
	while (abc < 10)
		abc += 1 + abc * abc;

	std::cout << "abc: " << abc << std::endl;

	return test;
}

copy_me maybe_move()
{
	int abc = std::rand();
	
	while (abc < 10)
		abc += 1 + abc * abc;

	std::cout << "abc: " << abc << std::endl;

	copy_me test(abc);

	std::cout << abc * abc << std::endl;

	return test;
}

copy_me move()
{
	copy_me test(10);
	
	int abc = std::rand();
	
	while (abc < 10)
		abc += 1 + abc * abc;

	std::cout << "abc: " << abc << std::endl;

	return std::move(test);
}

int main()
{
	std::cout << "== Init: Elision ==" << std::endl;
	copy_me ce = copy_elision();

	std::cout << "== Assignment: Elision ==" << std::endl;
	ce = copy_elision();

	std::cout << "== Init: Move? ==" << std::endl;
	copy_me mamo = maybe_move();

	std::cout << "== Assignment: Move? ==" << std::endl;
	mamo = maybe_move();

	std::cout << "== Init: Move ==" << std::endl;
	copy_me mo = move();

	std::cout << "== Assignment: Move ==" << std::endl;
	mo = move();

	std::cout << "== End ==" << std::endl;

	return 0;
}