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 | 04333f9bda707d53a3ddf582f477baaaaeed016b (patch) | |
| tree | ace78e65ba083ac681fc0bf7cce8e765b4f0ce20 /libcxx/include/__hash_table | |
| parent | c0431fd02d24b86e3b2a9d029cb44e93aaf77efe (diff) | |
| download | bcm5719-llvm-04333f9bda707d53a3ddf582f477baaaaeed016b.tar.gz bcm5719-llvm-04333f9bda707d53a3ddf582f477baaaaeed016b.zip | |
Diagnose non-const-callable hash functions and comparators
llvm-svn: 291969
Diffstat (limited to 'libcxx/include/__hash_table')
| -rw-r--r-- | libcxx/include/__hash_table | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table index e082e6c812f..6d6a6a1aa33 100644 --- a/libcxx/include/__hash_table +++ b/libcxx/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); |

