#include <iomanip>
#include <ios>
#include <iostream>
#include <type_traits>

using namespace std;

#define NEW_SECTION(title) cout << endl\
	<< "-------- " << #title << " --------" << endl << endl;

#define IS_SAME(...) cout << setw(43)\
	<< ("is_same<" + string(#__VA_ARGS__) + ">::value")\
	<< " == " << boolalpha << is_same<__VA_ARGS__>::value << endl

typedef char char_t; // Char type
typedef char* char_ptr; // Char pointer
typedef const char* char_const_ptr; // Char const pointer

int main() {
	IS_SAME( char, char );					// Obviously true
	IS_SAME( char, float );					// Obviously false

	NEW_SECTION(char_t);
	IS_SAME( char, char_t );				// true: OK
	IS_SAME( const char, char_t );			// false: OK
	IS_SAME( char, const char_t );			// false: OK
	IS_SAME( const char, const char_t );	// true: OK

	NEW_SECTION(char_ptr);
	IS_SAME( char*, char_ptr );				// true: OK
	IS_SAME( const char*, char_ptr );		// false: OK
	IS_SAME( char*, const char_ptr );		// false: OK
	IS_SAME( const char*, const char_ptr );	// false: Why?
	IS_SAME( char* const, char_ptr );		// false: OK
	IS_SAME( char* const, const char_ptr );	// true: Why?

	NEW_SECTION(char_const_ptr);
	IS_SAME( char*, char_const_ptr );		// false: OK
	IS_SAME( const char*, char_const_ptr );	// true: OK
	IS_SAME( char* const, char_const_ptr );	// false: OK
	return 0;
}
