145
|
1 /* { dg-do run } */
|
|
2 /* { dg-additional-options "-fstrict-aliasing" } */
|
|
3
|
|
4 #include <cstdlib>
|
|
5 #include <array>
|
|
6 #include <type_traits>
|
|
7
|
|
8 template <typename T1, typename T2>
|
|
9 struct variant
|
|
10 {
|
|
11 constexpr variant(T1 arg)
|
|
12 : f1(arg),
|
|
13 index(0)
|
|
14 {}
|
|
15
|
|
16 constexpr variant(T2 arg)
|
|
17 : f2(arg),
|
|
18 index(1)
|
|
19 {}
|
|
20
|
|
21 union
|
|
22 {
|
|
23 T1 f1;
|
|
24 T2 f2;
|
|
25 };
|
|
26 std::size_t index = 0;
|
|
27 };
|
|
28
|
|
29 template <typename T1, typename T2>
|
|
30 constexpr const T1* get_if(const variant<T1, T2>* v)
|
|
31 {
|
|
32 if (v->index != 0)
|
|
33 {
|
|
34 return nullptr;
|
|
35 }
|
|
36 return &v->f1;
|
|
37 }
|
|
38
|
|
39 template <typename T2, typename T1>
|
|
40 constexpr const T2* get_if(const variant<T1, T2>* v)
|
|
41 {
|
|
42 if (v->index != 1)
|
|
43 {
|
|
44 return nullptr;
|
|
45 }
|
|
46 return &v->f2;
|
|
47 }
|
|
48
|
|
49 template <typename T, size_t N>
|
|
50 struct my_array
|
|
51 {
|
|
52 constexpr const T* begin() const
|
|
53 {
|
|
54 return data;
|
|
55 }
|
|
56
|
|
57 constexpr const T* end() const
|
|
58 {
|
|
59 return data + N;
|
|
60 }
|
|
61
|
|
62 T data[N];
|
|
63 };
|
|
64
|
|
65 template <typename ...Ts>
|
|
66 constexpr auto get_array_of_variants(Ts ...ptrs)
|
|
67 {
|
|
68 return std::array<variant<std::decay_t<Ts>...>, sizeof...(Ts)>{ ptrs... };
|
|
69 }
|
|
70
|
|
71 template <typename T>
|
|
72 constexpr auto get_member_functions();
|
|
73
|
|
74 template <typename Member, typename Class>
|
|
75 constexpr int getFuncId(Member (Class::*memFuncPtr))
|
|
76 {
|
|
77 int idx = 0u;
|
|
78 for (auto &anyFunc : get_member_functions<Class>())
|
|
79 {
|
|
80 if (auto *specificFunc = get_if<Member (Class::*)>(&anyFunc))
|
|
81 {
|
|
82 if (*specificFunc == memFuncPtr)
|
|
83 {
|
|
84 return idx;
|
|
85 }
|
|
86 }
|
|
87 ++idx;
|
|
88 }
|
|
89 std::abort();
|
|
90 }
|
|
91
|
|
92 struct MyStruct
|
|
93 {
|
|
94 void fun1(int /*a*/) {}
|
|
95
|
|
96 int fun2(char /*b*/, short /*c*/, bool /*d*/) { return 0; }
|
|
97
|
|
98 };
|
|
99
|
|
100 template <>
|
|
101 constexpr auto get_member_functions<MyStruct>()
|
|
102 {
|
|
103 return get_array_of_variants(&MyStruct::fun1, &MyStruct::fun2);
|
|
104 }
|
|
105
|
|
106 int main()
|
|
107 {
|
|
108 return getFuncId(&MyStruct::fun1);
|
|
109 }
|