//===----------------------------------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // UNSUPPORTED: libcpp-no-exceptions // // template struct __debug_less // __debug_less checks that a comparator actually provides a strict-weak ordering. struct DebugException {}; #define _LIBCPP_DEBUG 0 #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : throw ::DebugException()) #include #include template struct MyType { int value; explicit MyType(int xvalue = 0) : value(xvalue) {} }; template bool operator<(MyType const& LHS, MyType const& RHS) { return LHS.value < RHS.value; } struct CompareBase { static int called; static void reset() { called = 0; } }; int CompareBase::called = 0; template struct GoodComparator : public CompareBase { bool operator()(ValueType const& lhs, ValueType const& rhs) const { ++CompareBase::called; return lhs < rhs; } }; template struct BadComparator : public CompareBase { bool operator()(ValueType const&, ValueType const&) const { ++CompareBase::called; return true; } }; template struct TwoWayHomoComparator : public CompareBase { bool operator()(T1 const& lhs, T2 const& rhs) const { ++CompareBase::called; return lhs < rhs; } bool operator()(T2 const& lhs, T1 const& rhs) const { ++CompareBase::called; return lhs < rhs; } }; template struct OneWayHomoComparator : public CompareBase { bool operator()(T1 const& lhs, T2 const& rhs) const { ++CompareBase::called; return lhs < rhs; } }; using std::__debug_less; typedef MyType<0> MT0; typedef MyType<1> MT1; void test_passing() { int& called = CompareBase::called; called = 0; MT0 one(1); MT0 two(2); MT1 three(3); MT1 four(4); { typedef GoodComparator C; typedef __debug_less D; C c; D d(c); assert(d(one, two) == true); assert(called == 2); called = 0; assert(d(one, one) == false); assert(called == 1); called = 0; assert(d(two, one) == false); assert(called == 1); called = 0; } { typedef TwoWayHomoComparator C; typedef __debug_less D; C c; D d(c); assert(d(one, three) == true); assert(called == 2); called = 0; assert(d(three, one) == false); assert(called == 1); called = 0; } { typedef OneWayHomoComparator C; typedef __debug_less D; C c; D d(c); assert(d(one, three) == true); assert(called == 1); called = 0; } } void test_failing() { int& called = CompareBase::called; called = 0; MT0 one(1); MT0 two(2); { typedef BadComparator C; typedef __debug_less D; C c; D d(c); try { d(one, two); assert(false); } catch (DebugException const&) { } assert(called == 2); called = 0; } } int main() { test_passing(); test_failing(); }