Clang Project

clang_source_code/test/SemaCXX/libstdcxx_libcxx_less_hack.cpp
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
7namespace 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
55void 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