#include <iostream>
#include <string>
using namespace std;

class D1 
{
public:
	int get_d1_id( ) const 
	{
		return 1;
	}
};

class D2 {};
class D12: public D1, public D2 
{
public:
	int get_d12_id( ) const 
	{
		return 2;
	}
};

int main() 
{
	// Examples with built-in types
	printf("static_cast<int>(1.0) = %d\n", static_cast<int>(1.0f));
	printf("static_cast<int>(0xFFFFFFFFU) = %d\n", static_cast<int>(0xFFFFFFFFU));
	printf("static_cast<int>(0xFF11FFFFFFULL) = 0x%X\n", static_cast<int>(0xFF11FFFFFFULL));
	printf("static_cast<float>(5) = %f\n", static_cast<float>(5));
	printf("static_cast<unsigned int>(-1) = %u\n", static_cast<unsigned int>(-1));
	
	// Examples with user defined types
	D1 d1;
	D2 d2;
	D12 d12;
	d1 = d12;	// up-cast: implicit conversion
	d2 = d12;	// up-cast: implicit conversion

	// Examples with pointer types for built-in types
	const char * expression = "Three dollar bill yall$";
	const void * p = static_cast< const void *> (expression);
	expression = static_cast<const char *>(p);		 		 
	const int * piexp = static_cast<const int *>(p);				 

	// Examples with pointer types for user defined types
	D1 * pd1 = &d12;    // up-cast: implicit conversion
	D2 * pd2 = &d12;    // up-cast: implicit conversion
	D12 * pd12 = static_cast<D12*>(pd1); 	// down-cast
	
	// Examples with references types for user defined types
	D1 & rd1 = d12;                         // up-cast: implicit conversion
	D12 & rd12 = static_cast<D12&>(rd1);    // down-cast
	
	// Examples with pointers to member functions
	typedef int (D12::*d12_int_void_cont_mem_fun_ptr)() const;
	typedef int (D1::*d1_int_void_cont_mem_fun_ptr)() const;
	
	d1_int_void_cont_mem_fun_ptr d1_func_ptr = &D1::get_d1_id;
	printf("(d1.*d1_func_ptr)() returns %d\n", (d1.*d1_func_ptr)());
	
	d12_int_void_cont_mem_fun_ptr d12_func_ptr = &D12::get_d12_id;
	printf("(d12.*d12_func_ptr)() returns %d\n", (d12.*d12_func_ptr)());
	
	d12_func_ptr = static_cast<d12_int_void_cont_mem_fun_ptr>(d1_func_ptr);
	printf("(d12.*d12_func_ptr)() returns %d\n", (d12.*d12_func_ptr)());
	
	d1_func_ptr = static_cast<d1_int_void_cont_mem_fun_ptr>(&D12::get_d12_id);
	printf("(d1.*d1_func_ptr)() returns %d\n", (d1.*d1_func_ptr)());
	
	return 0;
}