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>