• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 struct 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 
26 template <int ID>
27 struct MyType {
28     int value;
MyTypeMyType29     explicit MyType(int xvalue = 0) : value(xvalue) {}
30 };
31 
32 template <int ID1, int ID2>
operator <(MyType<ID1> const & LHS,MyType<ID2> const & RHS)33 bool operator<(MyType<ID1> const& LHS, MyType<ID2> const& RHS) {
34     return LHS.value < RHS.value;
35 }
36 
37 struct CompareBase {
38     static int called;
resetCompareBase39     static void reset() {
40         called = 0;
41     }
42 };
43 
44 int CompareBase::called = 0;
45 
46 template <class ValueType>
47 struct GoodComparator : public CompareBase {
operator ()GoodComparator48     bool operator()(ValueType const& lhs, ValueType const& rhs) const {
49         ++CompareBase::called;
50         return lhs < rhs;
51     }
52 };
53 
54 template <class ValueType>
55 struct BadComparator : public CompareBase {
operator ()BadComparator56     bool operator()(ValueType const&, ValueType const&) const {
57         ++CompareBase::called;
58         return true;
59     }
60 };
61 
62 template <class T1, class T2>
63 struct TwoWayHomoComparator : public CompareBase {
operator ()TwoWayHomoComparator64     bool operator()(T1 const& lhs, T2 const& rhs) const {
65         ++CompareBase::called;
66         return lhs < rhs;
67     }
68 
operator ()TwoWayHomoComparator69     bool operator()(T2 const& lhs, T1 const& rhs) const {
70         ++CompareBase::called;
71         return lhs < rhs;
72     }
73 };
74 
75 template <class T1, class T2>
76 struct OneWayHomoComparator : public CompareBase {
operator ()OneWayHomoComparator77     bool operator()(T1 const& lhs, T2 const& rhs) const {
78         ++CompareBase::called;
79         return lhs < rhs;
80     }
81 };
82 
83 using std::__debug_less;
84 
85 typedef MyType<0> MT0;
86 typedef MyType<1> MT1;
87 
test_passing()88 void 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 
test_failing()141 void 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 
main()164 int main() {
165     test_passing();
166     test_failing();
167 }