1//===----------------------------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is dual licensed under the MIT and the University of Illinois Open 6// Source Licenses. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10// UNSUPPORTED: libcpp-no-exceptions 11 12// <algorithm> 13 14// template <class _Compare> struct __debug_less 15 16// __debug_less checks that a comparator actually provides a strict-weak ordering. 17 18struct DebugException {}; 19 20#define _LIBCPP_DEBUG 0 21#define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : throw ::DebugException()) 22 23#include <algorithm> 24#include <cassert> 25 26template <int ID> 27struct MyType { 28 int value; 29 explicit MyType(int xvalue = 0) : value(xvalue) {} 30}; 31 32template <int ID1, int ID2> 33bool operator<(MyType<ID1> const& LHS, MyType<ID2> const& RHS) { 34 return LHS.value < RHS.value; 35} 36 37struct CompareBase { 38 static int called; 39 static void reset() { 40 called = 0; 41 } 42}; 43 44int CompareBase::called = 0; 45 46template <class ValueType> 47struct GoodComparator : public CompareBase { 48 bool operator()(ValueType const& lhs, ValueType const& rhs) const { 49 ++CompareBase::called; 50 return lhs < rhs; 51 } 52}; 53 54template <class ValueType> 55struct BadComparator : public CompareBase { 56 bool operator()(ValueType const&, ValueType const&) const { 57 ++CompareBase::called; 58 return true; 59 } 60}; 61 62template <class T1, class T2> 63struct TwoWayHomoComparator : public CompareBase { 64 bool operator()(T1 const& lhs, T2 const& rhs) const { 65 ++CompareBase::called; 66 return lhs < rhs; 67 } 68 69 bool operator()(T2 const& lhs, T1 const& rhs) const { 70 ++CompareBase::called; 71 return lhs < rhs; 72 } 73}; 74 75template <class T1, class T2> 76struct OneWayHomoComparator : public CompareBase { 77 bool operator()(T1 const& lhs, T2 const& rhs) const { 78 ++CompareBase::called; 79 return lhs < rhs; 80 } 81}; 82 83using std::__debug_less; 84 85typedef MyType<0> MT0; 86typedef MyType<1> MT1; 87 88void test_passing() { 89 int& called = CompareBase::called; 90 called = 0; 91 MT0 one(1); 92 MT0 two(2); 93 MT1 three(3); 94 MT1 four(4); 95 96 { 97 typedef GoodComparator<MT0> C; 98 typedef __debug_less<C> D; 99 100 C c; 101 D d(c); 102 103 assert(d(one, two) == true); 104 assert(called == 2); 105 called = 0; 106 107 assert(d(one, one) == false); 108 assert(called == 1); 109 called = 0; 110 111 assert(d(two, one) == false); 112 assert(called == 1); 113 called = 0; 114 } 115 { 116 typedef TwoWayHomoComparator<MT0, MT1> C; 117 typedef __debug_less<C> D; 118 C c; 119 D d(c); 120 121 assert(d(one, three) == true); 122 assert(called == 2); 123 called = 0; 124 125 assert(d(three, one) == false); 126 assert(called == 1); 127 called = 0; 128 } 129 { 130 typedef OneWayHomoComparator<MT0, MT1> C; 131 typedef __debug_less<C> D; 132 C c; 133 D d(c); 134 135 assert(d(one, three) == true); 136 assert(called == 1); 137 called = 0; 138 } 139} 140 141void test_failing() { 142 int& called = CompareBase::called; 143 called = 0; 144 MT0 one(1); 145 MT0 two(2); 146 147 { 148 typedef BadComparator<MT0> C; 149 typedef __debug_less<C> D; 150 C c; 151 D d(c); 152 153 try { 154 d(one, two); 155 assert(false); 156 } catch (DebugException const&) { 157 } 158 159 assert(called == 2); 160 called = 0; 161 } 162} 163 164int main() { 165 test_passing(); 166 test_failing(); 167} 168