Add _LIBCPP_DIAGNOSE_WARNING and _LIBCPP_DIAGNOSE_ERROR macros.

Clang recently added a `diagnose_if(cond, msg, type)` attribute
which can be used to generate diagnostics when `cond` is a constant
expression that evaluates to true. Otherwise no attribute has no
effect.

This patch adds _LIBCPP_DIAGNOSE_ERROR/WARNING macros which
use this new attribute. Additionally this patch implements
a diagnostic message when a non-const-callable comparator is
given to a container.

Note: For now the warning version of the diagnostic is useless
within libc++ since warning diagnostics are suppressed by the
system header pragma. I'm going to work on fixing this.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@291961 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/__tree b/include/__tree
index dd32f70..3bc0207 100644
--- a/include/__tree
+++ b/include/__tree
@@ -41,6 +41,10 @@
 struct __value_type;
 #endif
 
+template <class _Key, class _CP, class _Compare,
+    bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value>
+class __map_value_compare;
+
 template <class _Allocator> class __map_node_destructor;
 template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_iterator;
 template <class _TreeIterator> class _LIBCPP_TEMPLATE_VIS __map_const_iterator;
@@ -955,6 +959,30 @@
 
 };
 
+#ifndef _LIBCPP_CXX03_LANG
+template <class _Tp, class _Compare, class _Allocator>
+struct __diagnose_tree_helper {
+  static constexpr bool __trigger_diagnostics()
+      _LIBCPP_DIAGNOSE_WARNING(!__is_const_comparable<_Compare, _Tp>::value,
+            "the specified comparator type does not provide a const call operator")
+  { return true; }
+};
+
+template <class _Key, class _Value, class _KeyComp, class _Alloc>
+struct __diagnose_tree_helper<
+    __value_type<_Key, _Value>,
+    __map_value_compare<_Key, __value_type<_Key, _Value>, _KeyComp>,
+    _Alloc
+>
+{
+  static constexpr bool __trigger_diagnostics()
+      _LIBCPP_DIAGNOSE_WARNING(!__is_const_comparable<_KeyComp, _Key>::value,
+            "the specified comparator type does not provide a const call operator")
+  { return true; }
+};
+
+#endif
+
 template <class _Tp, class _Compare, class _Allocator>
 class __tree
 {
@@ -1787,7 +1815,11 @@
 {
     static_assert((is_copy_constructible<value_compare>::value),
                  "Comparator must be copy-constructible.");
-    destroy(__root());
+#ifndef _LIBCPP_CXX03_LANG
+    static_assert((__diagnose_tree_helper<_Tp, _Compare, _Allocator>::
+                     __trigger_diagnostics()), "");
+#endif
+  destroy(__root());
 }
 
 template <class _Tp, class _Compare, class _Allocator>