#include <iostream>
using namespace std;

template<class T>
struct inspect_t
{
	T* data;
	inspect_t(T* v):data(v) {}
};

template<class T>
inline inspect_t<T> inspect(T* v)
{
	return inspect_t<T>(v);
}

template<class C, class R, class T>
basic_ostream<C,R>& operator << (basic_ostream<C,R>& out, const inspect_t<T>& t)
{
	static const char *hexdigit = "0123456789ABCDEF";
	char *ptr = static_cast<char *>(static_cast<void *>(t.data));
	for(size_t i = 0; i < sizeof(T); i++)
	{
		int value = (static_cast<int>(ptr[i]))&0xFF;
		out << hexdigit[value/16] << hexdigit[value%16];
	}
	return out;
}

struct Father
{
	virtual void one() {}
	virtual void two() {}
};

struct Mother
{
	virtual void three() {}
	virtual void four() {}
};

struct Child: public Father, public Mother
{
	void five() {}
	void six() {}
};

typedef int (*SimpleFP_t)();
typedef void (Father::*FatherMFP_t)();
typedef void (Mother::*MotherMFP_t)();
typedef void (Child::*ChildMFP_t)();

int main()
{
	cout << "Ordinary case:" << endl;
	int i = 0x12345678;
	cout << inspect(&i) << endl;
	double d = 3.141592653589793;
	cout << inspect(&d) << endl;

	cout << "Simple pointer:" << endl;
	int *p = &i;
	cout << inspect(&p) << endl;
	
	cout << "Simple function pointer:" << endl;
	SimpleFP_t fp = main;
	cout << inspect(&fp) << endl;

	FatherMFP_t ffp;
	MotherMFP_t mfp;
	ChildMFP_t cfp;
	cout << "Parent's member function pointer:" << endl;
	ffp = &Father::one;   cout << inspect(&ffp) << endl;
	ffp = &Father::two;   cout << inspect(&ffp) << endl;
	mfp = &Mother::three; cout << inspect(&mfp) << endl;
	mfp = &Mother::four;  cout << inspect(&mfp) << endl;

	cout << "Child's member function pointer, in Child's view:" << endl;
	cfp = &Child::one;   cout << inspect(&cfp) << endl;
	cfp = &Child::two;   cout << inspect(&cfp) << endl;
	cfp = &Child::three; cout << inspect(&cfp) << endl;
	cfp = &Child::four;  cout << inspect(&cfp) << endl;
	cfp = &Child::five;  cout << inspect(&cfp) << endl;
	cfp = &Child::six;   cout << inspect(&cfp) << endl;

	cout << "Child's member function pointer, in Parent's view:" << endl;
	ffp = &Child::one;   cout << inspect(&ffp) << endl;
	ffp = &Child::two;   cout << inspect(&ffp) << endl;
	mfp = &Child::three; cout << inspect(&mfp) << endl;
	mfp = &Child::four;  cout << inspect(&mfp) << endl;

	return 0;
}
 