1 | // This is a test for a hack in Clang that works around a problem introduced by |
2 | // DR583: it's no longer possible to compare a pointer against nullptr_t, but |
3 | // we still want to permit those comparisons within less<> and friends. |
4 | |
5 | // RUN: %clang_cc1 -verify %s -std=c++14 |
6 | |
7 | namespace std { |
8 | template<typename T = void> struct less {}; |
9 | template<typename T = void> struct less_equal {}; |
10 | template<typename T = void> struct greater {}; |
11 | template<typename T = void> struct greater_equal {}; |
12 | |
13 | template<> struct less<> { |
14 | template <class T1, class T2> |
15 | auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t < u)) |
16 | -> decltype(t < u) { |
17 | return t < u; |
18 | } |
19 | }; |
20 | |
21 | template<> struct less_equal<> { |
22 | template <class T1, class T2> |
23 | auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t <= u)) |
24 | -> decltype(t <= u) { |
25 | return t <= u; |
26 | } |
27 | }; |
28 | |
29 | template<> struct greater<> { |
30 | template <class T1, class T2> |
31 | auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t > u)) |
32 | -> decltype(t > u) { |
33 | return t > u; |
34 | } |
35 | }; |
36 | |
37 | template<> struct greater_equal<> { |
38 | template <class T1, class T2> |
39 | auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t >= u)) |
40 | -> decltype(t >= u) { |
41 | return t >= u; |
42 | } |
43 | }; |
44 | |
45 | template<typename = void> struct unrelated; |
46 | template<> struct unrelated<> { |
47 | template <class T1, class T2> |
48 | auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t < u)) // expected-note {{substitution failure}} |
49 | -> decltype(t < u) { |
50 | return t < u; |
51 | } |
52 | }; |
53 | }; |
54 | |
55 | void test(int *p) { |
56 | using namespace std; |
57 | less<>()(p, nullptr); |
58 | less<>()(nullptr, p); |
59 | less_equal<>()(p, nullptr); |
60 | less_equal<>()(nullptr, p); |
61 | greater<>()(p, nullptr); |
62 | greater<>()(nullptr, p); |
63 | greater_equal<>()(p, nullptr); |
64 | greater_equal<>()(nullptr, p); |
65 | |
66 | unrelated<>()(p, nullptr); // expected-error {{no matching function}} |
67 | } |
68 | |