#include <iostream>
#include <string>
#include <vector>

using namespace std;

#define DBG(TEXT) do{cout << "( " << m_name << m_id << " " << #TEXT << " )" << endl;}while(0)

#define USE_MOVE_SEMANTICS

class Foo
{
    string m_name;
	unsigned int m_id;
public:

	// constructor
	Foo(const char *name)
		: m_name(name)
		, m_id(0)
	{
		DBG(constructor);
	}

	// destructor
	~Foo()
	{
		DBG(destructor);
	}

	// copy constructor
	Foo(const Foo &other)
		: m_name(other.m_name)
		, m_id(other.m_id + 1)
	{
		DBG(copy constructor);
	}

	// copy assignment operator
	Foo &operator=(const Foo &other)
	{
		m_name = other.m_name;
		m_id = other.m_id + 1;
		DBG(copy assignment operator);
		return *this;
	}

#ifdef USE_MOVE_SEMANTICS

	// move constructor
	Foo(Foo &&other)
		: m_name(other.m_name)
		, m_id(other.m_id + 1)
	{
		DBG(move constructor);
	}

	// move assignment operator
	Foo &operator=(Foo &&other)
	{
		m_name = other.m_name;
		m_id = other.m_id + 1;
		DBG(move assignment operator);
		return *this;
	}

#endif // USE_MOVE_SEMANTICS

};

int main(void)
{
	vector<Foo> vec;
	vec.reserve(1);

	cout << "Foo a(\"A\");" << endl;
	Foo a("A");

	cout << "vec.push_back(a);" << endl;
	vec.push_back(a); // No reallocation.

	cout << "vec.push_back(Foo(\"B\"));" << endl;
	vec.push_back(Foo("B")); // Reallocate memory and move elements.

	cout << "vec[0] = Foo(\"C\");" << endl;
	vec[0] = Foo("C");

	cout << "return 0;" << endl;
	return 0;
}
