diff options
author | Eric Fiselier <eric@efcs.ca> | 2017-01-13 22:42:53 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2017-01-13 22:42:53 +0000 |
commit | eaf292013defd65d96984e12733f67cb35e05561 (patch) | |
tree | a9f7c6d2edf5fef3c8482c51aa58759159aeb2b3 /include/__hash_table | |
parent | ebaf7dab14c3bf1c4f995d9ad1199b6c2784a8ca (diff) | |
download | external_libcxx-eaf292013defd65d96984e12733f67cb35e05561.tar.gz external_libcxx-eaf292013defd65d96984e12733f67cb35e05561.tar.bz2 external_libcxx-eaf292013defd65d96984e12733f67cb35e05561.zip |
Diagnose non-const-callable hash functions and comparators
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@291969 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/__hash_table')
-rw-r--r-- | include/__hash_table | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/include/__hash_table b/include/__hash_table index e082e6c81..6d6a6a1aa 100644 --- a/include/__hash_table +++ b/include/__hash_table @@ -18,6 +18,7 @@ #include <algorithm> #include <cmath> #include <utility> +#include <type_traits> #include <__undef_min_max> @@ -38,6 +39,15 @@ template <class _Key, class _Tp> struct __hash_value_type; #endif +template <class _Key, class _Cp, class _Hash, + bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value> +class __unordered_map_hasher; + +template <class _Key, class _Cp, class _Pred, + bool = is_empty<_Pred>::value && !__libcpp_is_final<_Pred>::value + > +class __unordered_map_equal; + #ifndef _LIBCPP_CXX03_LANG template <class _Tp> struct __is_hash_value_type_imp : false_type {}; @@ -856,6 +866,29 @@ public: template <class> friend class __hash_map_node_destructor; }; + +#ifndef _LIBCPP_CXX03_LANG +template <class _Key, class _Hash, class _Equal, class _Alloc> +struct __diagnose_hash_table_helper { + static constexpr bool __trigger_diagnostics() + _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value, + "the specified hash functor does not provide a const call operator") + _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value, + "the specified comparator type does not provide a const call operator") + { return true; } +}; + +template <class _Key, class _Value, class _Hash, class _Equal, class _Alloc> +struct __diagnose_hash_table_helper< + __hash_value_type<_Key, _Value>, + __unordered_map_hasher<_Key, __hash_value_type<_Key, _Value>, _Hash>, + __unordered_map_equal<_Key, __hash_value_type<_Key, _Value>, _Equal>, + _Alloc> +: __diagnose_hash_table_helper<_Key, _Hash, _Equal, _Alloc> +{ +}; +#endif // _LIBCPP_CXX03_LANG + template <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table { @@ -1453,6 +1486,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() "Predicate must be copy-constructible."); static_assert((is_copy_constructible<hasher>::value), "Hasher must be copy-constructible."); +#ifndef _LIBCPP_CXX03_LANG + static_assert(__diagnose_hash_table_helper<_Tp, _Hash, _Equal, _Alloc>::__trigger_diagnostics(), ""); +#endif __deallocate_node(__p1_.first().__next_); #if _LIBCPP_DEBUG_LEVEL >= 2 __get_db()->__erase_c(this); |