EricWF updated this revision to Diff 33179.
EricWF added a comment.

Remove all functions in the dylib and make them inline.


http://reviews.llvm.org/D12354

Files:
  include/__debug
  include/algorithm
  include/regex
  src/debug.cpp
  test/libcxx/algorithms/debug_less.pass.cpp
  test/support/debug_mode.h

Index: test/support/debug_mode.h
===================================================================
--- /dev/null
+++ test/support/debug_mode.h
@@ -0,0 +1,34 @@
+#ifndef SUPPORT_DEBUG_MODE_H
+#define SUPPORT_DEBUG_MODE_H
+
+#ifndef _LIBCPP_DEBUG
+#error _LIBCPP_DEBUG must be defined before including the header
+#endif
+#ifdef _LIBCPP_CONFIG
+#error debug_mode.h must be included before any libc++ files
+#endif
+
+#include <__debug>
+#include <cstdlib>
+
+typedef std::__debug_assertion_handler_t DebugHandlerT;
+typedef std::__debug_assertion_info DebugInfo;
+
+inline DebugHandlerT getDebugHandler(DebugHandlerT new_h = nullptr) {
+    return std::__debug_assertion_handler(new_h);
+}
+
+void exitZeroHandler(DebugInfo const&) {
+    std::exit(0);
+}
+
+struct DebugException {
+    DebugInfo info;
+    DebugException(DebugInfo xinfo) : info(xinfo) {}
+};
+
+inline void throwingDebugHandler(DebugInfo const& info) {
+    throw DebugException(info);
+}
+
+#endif // SUPPORT_DEBUG_MODE_H
Index: test/libcxx/algorithms/debug_less.pass.cpp
===================================================================
--- /dev/null
+++ test/libcxx/algorithms/debug_less.pass.cpp
@@ -0,0 +1,164 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// <algorithm>
+
+// template <class _Compare> struct __debug_less
+
+// __debug_less checks that a comparator actually provides a strict-weak ordering.
+
+#define _LIBCPP_DEBUG 0
+#include "debug_mode.h"
+
+#include <algorithm>
+#include <cassert>
+
+template <int ID>
+struct MyType {
+    int value;
+    explicit MyType(int xvalue = 0) : value(xvalue) {}
+};
+
+template <int ID1, int ID2>
+bool operator<(MyType<ID1> const& LHS, MyType<ID2> const& RHS) {
+    return LHS.value < RHS.value;
+}
+
+struct CompareBase {
+    static int called;
+    static void reset() {
+        called = 0;
+    }
+};
+
+int CompareBase::called = 0;
+
+template <class ValueType>
+struct GoodComparator : public CompareBase {
+    bool operator()(ValueType const& lhs, ValueType const& rhs) const {
+        ++CompareBase::called;
+        return lhs < rhs;
+    }
+};
+
+template <class ValueType>
+struct BadComparator : public CompareBase {
+    bool operator()(ValueType const&, ValueType const&) const {
+        ++CompareBase::called;
+        return true;
+    }
+};
+
+template <class T1, class T2>
+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 <class T1, class T2>
+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<MT0> C;
+        typedef __debug_less<C> 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<MT0, MT1> C;
+        typedef __debug_less<C> 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<MT0, MT1> C;
+        typedef __debug_less<C> 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<MT0> C;
+        typedef __debug_less<C> D;
+        C c;
+        D d(c);
+
+        try {
+            d(one, two);
+            assert(false);
+        } catch (DebugException const&) {
+        }
+
+        assert(called == 2);
+        called = 0;
+    }
+}
+
+int main() {
+    getDebugHandler(&throwingDebugHandler);
+    test_passing();
+    test_failing();
+}
\ No newline at end of file
Index: src/debug.cpp
===================================================================
--- src/debug.cpp
+++ src/debug.cpp
@@ -14,9 +14,11 @@
 #include "algorithm"
 #include "__hash_table"
 #include "mutex"
+#include "cstdlib"
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+
 _LIBCPP_FUNC_VIS
 __libcpp_db*
 __get_db()
Index: include/regex
===================================================================
--- include/regex
+++ include/regex
@@ -1294,7 +1294,7 @@
         __consume_input,  // -999
         __begin_marked_expr, // -998
         __end_marked_expr,   // -997
-        __pop_state,           // -996
+        __pop_state,           // -9L
         __accept_and_consume,  // -995
         __accept_but_not_consume,  // -994
         __reject,                  // -993
Index: include/algorithm
===================================================================
--- include/algorithm
+++ include/algorithm
@@ -738,6 +738,17 @@
 
 #ifdef _LIBCPP_DEBUG
 
+template <class _Compare, class _LHS, class _RHS, class = void>
+struct __debug_is_comparable : false_type {};
+
+template <class _Compare, class _LHS, class _RHS>
+struct __debug_is_comparable<_Compare, _LHS, _RHS,
+    typename __void_t<decltype(
+        _VSTD::declval<_Compare>()(_VSTD::declval<_LHS>(), _VSTD::declval<_RHS>())
+    )>::type
+> : true_type {};
+
+
 template <class _Compare>
 struct __debug_less
 {
@@ -746,11 +757,22 @@
     template <class _Tp, class _Up>
     bool operator()(const _Tp& __x, const _Up& __y)
     {
+        typedef typename __debug_is_comparable<_Compare, _Up const&, _Tp const&>::type
+            _CanCompare;
         bool __r = __comp_(__x, __y);
         if (__r)
-            _LIBCPP_ASSERT(!__comp_(__y, __x), "Comparator does not induce a strict weak ordering");
+            __do_compare_assert(__y, __x, _CanCompare());
         return __r;
     }
+
+    template <class _LHS, class _RHS>
+    void __do_compare_assert(_LHS const&, _RHS const&, false_type) {}
+
+    template <class _LHS, class _RHS>
+    void __do_compare_assert(_LHS const& __l, _RHS const& __r, true_type) {
+        _LIBCPP_ASSERT(!__comp_(__l, __r), "Comparator does not induce a strict weak ordering");
+    }
+
 };
 
 #endif  // _LIBCPP_DEBUG
Index: include/__debug
===================================================================
--- include/__debug
+++ include/__debug
@@ -18,12 +18,52 @@
 #endif
 
 #if _LIBCPP_DEBUG_LEVEL >= 1
-#   include <cstdlib>
-#   include <cstdio>
 #   include <cstddef>
+#   include <cstdio>
+#   include <cstdlib>
 #   ifndef _LIBCPP_ASSERT
-#      define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (_VSTD::fprintf(stderr, "%s\n", m), _VSTD::abort()))
+#      define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (_VSTD::__debug_assert(__FILE__, __func__, __LINE__, m)))
 #   endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+struct __debug_assertion_info {
+    const char* __file_;
+    const char* __func_;
+    unsigned long __line_;
+    const char* __msg_;
+
+    _LIBCPP_INLINE_VISIBILITY
+    void __print() const {
+        _VSTD::fprintf(stderr, "%s:%lu: %s: %s\n", __file_, __line_, __func_, __msg_);
+    }
+};
+
+typedef void (*__debug_assertion_handler_t)(__debug_assertion_info const&);
+
+inline void __default_debug_handler(__debug_assertion_info const& __info) {
+    __info.__print();
+    _VSTD::abort();
+}
+
+inline __debug_assertion_handler_t
+__debug_assertion_handler(__debug_assertion_handler_t __new_handle = nullptr) {
+    static __debug_assertion_handler_t __handle_ = &__default_debug_handler;
+    __debug_assertion_handler_t __old = __handle_;
+    if (__new_handle) __handle_ = __new_handle;
+    return __old;
+}
+
+_LIBCPP_INLINE_VISIBILITY
+inline void __debug_assert(const char* __file, const char* __func,
+                          unsigned long __line, const char* __msg)
+{
+    __debug_assertion_info __info = {__file, __func, __line, __msg};
+    __debug_assertion_handler()(__info);
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
 #endif
 
 #ifndef _LIBCPP_ASSERT
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to