blob: 134182c77410744c6c7056d0d6e270dbde5b8e30 (
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
110
111
112
113
114
|
// P0847R7
// { dg-do compile { target c++23 } }
// basic use cases and calling
// non-trailing return
// definitions
struct S0 {
void f0(this S0) {}
void f1(this S0&) {}
void f2(this S0&&) {}
void f3(this S0 const&) {}
void f4(this S0 const&&) {}
template<typename Self>
void d0(this Self&&) {}
void d1(this auto&&) {}
};
// declarations
struct S1 {
void f0(this S1);
void f1(this S1&);
void f2(this S1&&);
void f3(this S1 const&);
void f4(this S1 const&&);
template<typename Self>
void d0(this Self&&);
void d1(this auto&&);
};
// out of line definitions
void S1::f0(this S1) {}
void S1::f1(this S1&) {}
void S1::f2(this S1&&) {}
void S1::f3(this S1 const&) {}
void S1::f4(this S1 const&&) {}
template<typename Self>
void S1::d0(this Self&&) {}
void S1::d1(this auto&&) {}
// trailing return
// definitions
struct S2 {
auto f0(this S2) -> void {}
auto f1(this S2&) -> void {}
auto f2(this S2&&) -> void {}
auto f3(this S2 const&) -> void {}
auto f4(this S2 const&&) -> void {}
template<typename Self>
auto d0(this Self&&) -> void {}
auto d1(this auto&&) -> void {}
};
// declarations
struct S3 {
auto f0(this S3) -> void;
auto f1(this S3&) -> void;
auto f2(this S3&&) -> void;
auto f3(this S3 const&) -> void;
auto f4(this S3 const&&) -> void;
template<typename Self>
auto d0(this Self&&) -> void;
auto d1(this auto&&) -> void;
};
// out of line definitions
auto S3::f0(this S3) -> void {}
auto S3::f1(this S3&) -> void {}
auto S3::f2(this S3&&) -> void {}
auto S3::f3(this S3 const&) -> void {}
auto S3::f4(this S3 const&&) -> void {}
template<typename Self>
auto S3::d0(this Self&&) -> void {}
auto S3::d1(this auto&&) -> void {}
template<typename T>
void call_with_qualification()
{
T obj{};
// by value should take any qualification (f0)
T{}.f0();
obj.f0();
static_cast<T&&>(obj).f0();
static_cast<T const&>(obj).f0();
static_cast<T const&&>(obj).f0();
// specific qualification (f1 - f4)
T{}.f2();
T{}.f3();
T{}.f4();
obj.f1();
obj.f3();
static_cast<T&&>(obj).f2();
static_cast<T&&>(obj).f3();
static_cast<T&&>(obj).f4();
static_cast<T const&>(obj).f3();
static_cast<T const&&>(obj).f4();
// deduced should (obviously) take any qualification (d0, d1)
T{}.d0();
obj.d0();
static_cast<T&&>(obj).d0();
static_cast<T const&>(obj).d0();
static_cast<T const&&>(obj).d0();
T{}.d1();
obj.d1();
static_cast<T&&>(obj).d1();
static_cast<T const&>(obj).d1();
static_cast<T const&&>(obj).d1();
}
void perform_calls()
{
call_with_qualification<S0>();
call_with_qualification<S1>();
call_with_qualification<S2>();
call_with_qualification<S3>();
}
|