68 lines · cpp
1// This is a test for a hack in Clang that works around a problem introduced by2// DR583: it's no longer possible to compare a pointer against nullptr_t, but3// we still want to permit those comparisons within less<> and friends.4 5// RUN: %clang_cc1 -verify %s -std=c++146 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