#include <iostream>

/* A "hygenic" C macro */
#define swap(a,b,t) do { t temp = a; a = b; b = temp; } while(0)

/* C/C++ type-checked inline function */
inline void swap2i(int* a, int* b) { int temp = *a; *a = *b; *b = temp; }
inline void swap2s(char** a, char** b) { char* temp = *a; *a = *b; *b = temp; }

inline void swap3s(char*& a, char*& b) { char* temp = a; a = b; b = temp; }

/* C++ template solution */
template<class T> void swap3(T& a, T& b) { T temp = a; a = b; b = temp; }

int main()
{
	int x = 5;
	int y = 10;
	char* a = "hello";
	char* b = "world";

	std::cout << "Before: x=" << x << " y=" << y << std::endl;
	if (x < 10)
	  swap(x,y,int);
	else 
          x = 6;

	std::cout << "After: x=" << x << " y=" << y << std::endl << std::endl;

	std::cout << "Before: x=" << x << " y=" << y << std::endl;
	swap2i(&x,&y);
	std::cout << "After: x=" << x << " y=" << y << std::endl << std::endl;

	std::cout << "Before: x=" << x << " y=" << y << std::endl;
	swap3(x,y);
	std::cout << "After: x=" << x << " y=" << y << std::endl << std::endl;

	std::cout << "Before: a=" << a << " b=" << b << std::endl;
	swap(a,b,char*);
	std::cout << "After: a=" << a << " b=" << b << std::endl << std::endl;

	std::cout << "Before: a=" << a << " b=" << b << std::endl;
	swap2s(&a, &b);
	std::cout << "After: a=" << a << " b=" << b << std::endl << std::endl;

	std::cout << "Before: a=" << a << " b=" << b << std::endl;
	swap3(a,b);
	std::cout << "After: a=" << a << " b=" << b << std::endl;
}
