1 #include <iostream>
2 #include <typeinfo>
3 #include <string>
4 #include <fstream>
5 #include <sstream>
6 #include <stdint.h>
7 #include <pthread.h>
8 #include <unistd.h>
9 #include <string.h>
10 #include <vector>
11 #include <map>
12 #include <set>
13
14 using namespace std;
15
16 template<typename T>
17 struct type_to_pointer { typedef T* type; };
18 template <typename T>
19 struct type_to_pointer<T*> { typedef T* type; };
20 template <typename T>
21 struct type_to_pointer<const T*> { typedef T* type; };
22 template <typename T>
23 struct type_to_pointer<T*const> { typedef T* type; };
24 template <typename T>
25 struct type_to_pointer<const T *const> { typedef T* type; };
26 template <typename T>
27 struct type_to_pointer<T**> { typedef T* type; };
28 template <typename T>
29 struct type_to_pointer<const T**> { typedef T* type; };
30 template <typename T>
31 struct type_to_pointer<T**const> { typedef T* type; };
32 template <typename T>
33 struct type_to_pointer<T&> { typedef T* type; };
34 template <typename T>
35 struct type_to_pointer<T&&> { typedef T* type; };
36 template <typename T>
37 struct type_to_pointer<const T&> { typedef T* type; };
38 template <typename T, int N>
39 struct type_to_pointer<T[N]> { typedef T* type; };
40 template <typename T, int N>
41 struct type_to_pointer<const T[N]> { typedef T* type; };
42 template <typename T, int N>
43 struct type_to_pointer<T*[N]> { typedef T* type; };
44 template <typename T, int N>
45 struct type_to_pointer<const T*[N]> { typedef T* type; };
46 template <typename T, int N>
47 struct type_to_pointer<const T *const[N]> { typedef T* type; };
48
49 template <typename FromType, typename ToType = void>
50 void type_printer() {
51 cout << __PRETTY_FUNCTION__ << endl;
52 }
53
54 #define TYPE_PRINT(var) type_printer<decltype(var), type_to_pointer<decltype(var)>::type>()
55 #define CONST_CAST_TO_POINTER(var) const_cast<typename type_to_pointer<decltype(var)>::type>(var)
56
57 int main(int argc, char* argv[]) {
58 int x1 = 0;
59 TYPE_PRINT(x1);
60
61 const int& x2 = x1;
62 TYPE_PRINT(x2);
63
64 const int* x3 = &x1;
65 TYPE_PRINT(x3);
66 TYPE_PRINT(CONST_CAST_TO_POINTER(x3));
67
68 const int *const x4 = &x1;
69 TYPE_PRINT(x4);
70 TYPE_PRINT(CONST_CAST_TO_POINTER(x4));
71
72 int& x5 = x1;
73 TYPE_PRINT(x5);
74
75 int *const x6 = &x1;
76 TYPE_PRINT(x6);
77 TYPE_PRINT(CONST_CAST_TO_POINTER(x6));
78
79 int* x7 = &x1;
80 TYPE_PRINT(x7);
81
82 int&& x8 = 0;
83 TYPE_PRINT(x8);
84
85 int x9[2] = {1, 2};
86 TYPE_PRINT(x9);
87
88 const int x10[2] = {1, 2};
89 TYPE_PRINT(x10);
90
91 int* x11[2] = {NULL, NULL};
92 TYPE_PRINT(x11);
93
94 const int* x12[2] = {NULL, NULL};
95 TYPE_PRINT(x12);
96
97 const int *const x13[2] = {NULL, NULL};
98 TYPE_PRINT(x13);
99
100 TYPE_PRINT(argc);
101 TYPE_PRINT(argv);
102 return 0;
103 }