Author: marshall Date: Sun Aug 24 18:54:16 2014 New Revision: 216353 URL: http://llvm.org/viewvc/llvm-project?rev=216353&view=rev Log: Fix bug 20740 - std::set/std::map don't support heterogeneous lookup for count(). Thanks to Jim Porter for the bug report
Modified: libcxx/trunk/include/map libcxx/trunk/include/set libcxx/trunk/test/containers/associative/map/map.ops/count.pass.cpp libcxx/trunk/test/containers/associative/multimap/multimap.ops/count.pass.cpp libcxx/trunk/test/containers/associative/multiset/count.pass.cpp libcxx/trunk/test/containers/associative/set/count.pass.cpp Modified: libcxx/trunk/include/map URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/map?rev=216353&r1=216352&r2=216353&view=diff ============================================================================== --- libcxx/trunk/include/map (original) +++ libcxx/trunk/include/map Sun Aug 24 18:54:16 2014 @@ -159,7 +159,7 @@ public: template<typename K> const_iterator find(const K& x) const; // C++14 template<typename K> - size_type count(const K& x) const; + size_type count(const K& x) const; // C++14 size_type count(const key_type& k) const; iterator lower_bound(const key_type& k); @@ -353,7 +353,7 @@ public: template<typename K> const_iterator find(const K& x) const; // C++14 template<typename K> - size_type count(const K& x) const; + size_type count(const K& x) const; // C++14 size_type count(const key_type& k) const; iterator lower_bound(const key_type& k); @@ -1104,6 +1104,12 @@ public: _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __tree_.__count_unique(__k);} +#if _LIBCPP_STD_VER > 11 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type + count(const _K2& __k) {return __tree_.__count_unique(__k);} +#endif _LIBCPP_INLINE_VISIBILITY iterator lower_bound(const key_type& __k) {return __tree_.lower_bound(__k);} @@ -1834,6 +1840,12 @@ public: _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __tree_.__count_multi(__k);} +#if _LIBCPP_STD_VER > 11 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type + count(const _K2& __k) {return __tree_.__count_multi(__k);} +#endif _LIBCPP_INLINE_VISIBILITY iterator lower_bound(const key_type& __k) {return __tree_.lower_bound(__k);} Modified: libcxx/trunk/include/set URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/set?rev=216353&r1=216352&r2=216353&view=diff ============================================================================== --- libcxx/trunk/include/set (original) +++ libcxx/trunk/include/set Sun Aug 24 18:54:16 2014 @@ -663,6 +663,12 @@ public: _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __tree_.__count_unique(__k);} +#if _LIBCPP_STD_VER > 11 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type + count(const _K2& __k) {return __tree_.__count_unique(__k);} +#endif _LIBCPP_INLINE_VISIBILITY iterator lower_bound(const key_type& __k) {return __tree_.lower_bound(__k);} @@ -1066,6 +1072,12 @@ public: _LIBCPP_INLINE_VISIBILITY size_type count(const key_type& __k) const {return __tree_.__count_multi(__k);} +#if _LIBCPP_STD_VER > 11 + template <typename _K2> + _LIBCPP_INLINE_VISIBILITY + typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type + count(const _K2& __k) {return __tree_.__count_multi(__k);} +#endif _LIBCPP_INLINE_VISIBILITY iterator lower_bound(const key_type& __k) Modified: libcxx/trunk/test/containers/associative/map/map.ops/count.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/associative/map/map.ops/count.pass.cpp?rev=216353&r1=216352&r2=216353&view=diff ============================================================================== --- libcxx/trunk/test/containers/associative/map/map.ops/count.pass.cpp (original) +++ libcxx/trunk/test/containers/associative/map/map.ops/count.pass.cpp Sun Aug 24 18:54:16 2014 @@ -17,6 +17,7 @@ #include <cassert> #include "min_allocator.h" +#include "private_constructor.hpp" int main() { @@ -96,4 +97,77 @@ int main() } } #endif +#if _LIBCPP_STD_VER > 11 + { + typedef std::pair<const int, double> V; + typedef std::map<int, double, std::less <>> M; + typedef M::size_type R; + + V ar[] = + { + V(5, 5), + V(6, 6), + V(7, 7), + V(8, 8), + V(9, 9), + V(10, 10), + V(11, 11), + V(12, 12) + }; + const M m(ar, ar+sizeof(ar)/sizeof(ar[0])); + R r = m.count(5); + assert(r == 1); + r = m.count(6); + assert(r == 1); + r = m.count(7); + assert(r == 1); + r = m.count(8); + assert(r == 1); + r = m.count(9); + assert(r == 1); + r = m.count(10); + assert(r == 1); + r = m.count(11); + assert(r == 1); + r = m.count(12); + assert(r == 1); + r = m.count(4); + assert(r == 0); + } + + { + typedef PrivateConstructor PC; + typedef std::map<PC, double, std::less<>> M; + typedef M::size_type R; + + M m; + m [ PC::make(5) ] = 5; + m [ PC::make(6) ] = 6; + m [ PC::make(7) ] = 7; + m [ PC::make(8) ] = 8; + m [ PC::make(9) ] = 9; + m [ PC::make(10) ] = 10; + m [ PC::make(11) ] = 11; + m [ PC::make(12) ] = 12; + + R r = m.count(5); + assert(r == 1); + r = m.count(6); + assert(r == 1); + r = m.count(7); + assert(r == 1); + r = m.count(8); + assert(r == 1); + r = m.count(9); + assert(r == 1); + r = m.count(10); + assert(r == 1); + r = m.count(11); + assert(r == 1); + r = m.count(12); + assert(r == 1); + r = m.count(4); + assert(r == 0); + } +#endif } Modified: libcxx/trunk/test/containers/associative/multimap/multimap.ops/count.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/associative/multimap/multimap.ops/count.pass.cpp?rev=216353&r1=216352&r2=216353&view=diff ============================================================================== --- libcxx/trunk/test/containers/associative/multimap/multimap.ops/count.pass.cpp (original) +++ libcxx/trunk/test/containers/associative/multimap/multimap.ops/count.pass.cpp Sun Aug 24 18:54:16 2014 @@ -17,6 +17,7 @@ #include <cassert> #include "min_allocator.h" +#include "private_constructor.hpp" int main() { @@ -89,4 +90,70 @@ int main() } } #endif + +#if _LIBCPP_STD_VER > 11 + { + typedef std::multimap<int, double, std::less<>> M; + typedef M::size_type R; + V ar[] = + { + V(5, 1), + V(5, 2), + V(5, 3), + V(7, 1), + V(7, 2), + V(7, 3), + V(9, 1), + V(9, 2), + V(9, 3) + }; + const M m(ar, ar+sizeof(ar)/sizeof(ar[0])); + R r = m.count(4); + assert(r == 0); + r = m.count(5); + assert(r == 3); + r = m.count(6); + assert(r == 0); + r = m.count(7); + assert(r == 3); + r = m.count(8); + assert(r == 0); + r = m.count(9); + assert(r == 3); + r = m.count(10); + assert(r == 0); + } + + { + typedef PrivateConstructor PC; + typedef std::multimap<PC, double, std::less<>> M; + typedef M::size_type R; + + M m; + m.insert ( std::make_pair<PC, double> ( PC::make(5), 1 )); + m.insert ( std::make_pair<PC, double> ( PC::make(5), 2 )); + m.insert ( std::make_pair<PC, double> ( PC::make(5), 3 )); + m.insert ( std::make_pair<PC, double> ( PC::make(7), 1 )); + m.insert ( std::make_pair<PC, double> ( PC::make(7), 2 )); + m.insert ( std::make_pair<PC, double> ( PC::make(7), 3 )); + m.insert ( std::make_pair<PC, double> ( PC::make(9), 1 )); + m.insert ( std::make_pair<PC, double> ( PC::make(9), 2 )); + m.insert ( std::make_pair<PC, double> ( PC::make(9), 3 )); + + R r = m.count(4); + assert(r == 0); + r = m.count(5); + assert(r == 3); + r = m.count(6); + assert(r == 0); + r = m.count(7); + assert(r == 3); + r = m.count(8); + assert(r == 0); + r = m.count(9); + assert(r == 3); + r = m.count(10); + assert(r == 0); + } +#endif } Modified: libcxx/trunk/test/containers/associative/multiset/count.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/associative/multiset/count.pass.cpp?rev=216353&r1=216352&r2=216353&view=diff ============================================================================== --- libcxx/trunk/test/containers/associative/multiset/count.pass.cpp (original) +++ libcxx/trunk/test/containers/associative/multiset/count.pass.cpp Sun Aug 24 18:54:16 2014 @@ -17,6 +17,7 @@ #include <cassert> #include "min_allocator.h" +#include "private_constructor.hpp" int main() { @@ -90,4 +91,70 @@ int main() } } #endif +#if _LIBCPP_STD_VER > 11 + { + typedef int V; + typedef std::multiset<int, std::less<>> M; + typedef M::size_type R; + V ar[] = + { + 5, + 5, + 5, + 5, + 7, + 7, + 7, + 9, + 9 + }; + const M m(ar, ar+sizeof(ar)/sizeof(ar[0])); + R r = m.count(4); + assert(r == 0); + r = m.count(5); + assert(r == 4); + r = m.count(6); + assert(r == 0); + r = m.count(7); + assert(r == 3); + r = m.count(8); + assert(r == 0); + r = m.count(9); + assert(r == 2); + r = m.count(10); + assert(r == 0); + } + + { + typedef PrivateConstructor V; + typedef std::multiset<V, std::less<>> M; + typedef M::size_type R; + + M m; + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 9 )); + m.insert ( V::make ( 9 )); + + R r = m.count(4); + assert(r == 0); + r = m.count(5); + assert(r == 4); + r = m.count(6); + assert(r == 0); + r = m.count(7); + assert(r == 3); + r = m.count(8); + assert(r == 0); + r = m.count(9); + assert(r == 2); + r = m.count(10); + assert(r == 0); + } +#endif } Modified: libcxx/trunk/test/containers/associative/set/count.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/associative/set/count.pass.cpp?rev=216353&r1=216352&r2=216353&view=diff ============================================================================== --- libcxx/trunk/test/containers/associative/set/count.pass.cpp (original) +++ libcxx/trunk/test/containers/associative/set/count.pass.cpp Sun Aug 24 18:54:16 2014 @@ -17,6 +17,7 @@ #include <cassert> #include "min_allocator.h" +#include "private_constructor.hpp" int main() { @@ -92,4 +93,76 @@ int main() assert(r == 0); } #endif +#if _LIBCPP_STD_VER > 11 + { + typedef int V; + typedef std::set<int, std::less<>> M; + typedef M::size_type R; + V ar[] = + { + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12 + }; + const M m(ar, ar+sizeof(ar)/sizeof(ar[0])); + R r = m.count(5); + assert(r == 1); + r = m.count(6); + assert(r == 1); + r = m.count(7); + assert(r == 1); + r = m.count(8); + assert(r == 1); + r = m.count(9); + assert(r == 1); + r = m.count(10); + assert(r == 1); + r = m.count(11); + assert(r == 1); + r = m.count(12); + assert(r == 1); + r = m.count(4); + assert(r == 0); + } + { + typedef PrivateConstructor V; + typedef std::set<V, std::less<>> M; + typedef M::size_type R; + + M m; + m.insert ( V::make ( 5 )); + m.insert ( V::make ( 6 )); + m.insert ( V::make ( 7 )); + m.insert ( V::make ( 8 )); + m.insert ( V::make ( 9 )); + m.insert ( V::make ( 10 )); + m.insert ( V::make ( 11 )); + m.insert ( V::make ( 12 )); + + R r = m.count(5); + assert(r == 1); + r = m.count(6); + assert(r == 1); + r = m.count(7); + assert(r == 1); + r = m.count(8); + assert(r == 1); + r = m.count(9); + assert(r == 1); + r = m.count(10); + assert(r == 1); + r = m.count(11); + assert(r == 1); + r = m.count(12); + assert(r == 1); + r = m.count(4); + assert(r == 0); + } +#endif + } _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits