aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/torture/pr91606.C
blob: 37a05a5e3a5fa82413d1800a66608c9bc7fbce62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/* { dg-do run } */
/* { dg-additional-options "-fstrict-aliasing" } */

#include <cstdlib>
#include <array>
#include <type_traits>

template <typename T1, typename T2>
struct variant
{
  constexpr variant(T1 arg)
      : f1(arg),
      index(0)
  {}

  constexpr variant(T2 arg)
      : f2(arg),
      index(1)
  {}

  union
    {
      T1 f1;
      T2 f2;
    };
  std::size_t index = 0;
};

template <typename T1, typename T2>
constexpr const T1* get_if(const variant<T1, T2>* v)
{
  if (v->index != 0)
    {
      return nullptr;
    }
  return &v->f1;
}

template <typename T2, typename T1>
constexpr const T2* get_if(const variant<T1, T2>* v)
{
  if (v->index != 1)
    {
      return nullptr;
    }
  return &v->f2;
}

template <typename T, size_t N>
struct my_array
{
  constexpr const T* begin() const
    {
      return data;
    }

  constexpr const T* end() const
    {
      return data + N;
    }

  T data[N];
};

template <typename ...Ts>
constexpr auto get_array_of_variants(Ts ...ptrs)
{
  return std::array<variant<std::decay_t<Ts>...>, sizeof...(Ts)>{ ptrs... };
}

template <typename T>
constexpr auto get_member_functions();

template <typename Member, typename Class>
constexpr int getFuncId(Member (Class::*memFuncPtr))
{
  int idx = 0u;
  for (auto &anyFunc : get_member_functions<Class>())
    {
      if (auto *specificFunc = get_if<Member (Class::*)>(&anyFunc))
	{
	  if (*specificFunc == memFuncPtr)
	    {
	      return idx;
	    }
	}
      ++idx;
    }
  std::abort();
}

struct MyStruct
{
  void fun1(int /*a*/) {}

  int fun2(char /*b*/, short /*c*/, bool /*d*/) { return 0; }

};

template <>
constexpr auto get_member_functions<MyStruct>()
{
  return get_array_of_variants(&MyStruct::fun1, &MyStruct::fun2);
}

int main()
{
  return getFuncId(&MyStruct::fun1);
}