comparison gcc/testsuite/g++.dg/torture/pr91606.C @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
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 }