[PATCH] D42344: [libc++] Use multi-key tree search for {map, set}::{count, equal_range}
N via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sat Jan 20 19:49:24 PST 2018
ng created this revision.
ng added a reviewer: mclow.lists.
Herald added a reviewer: EricWF.
As described in http://bugs.llvm.org/show_bug.cgi?id=30959, the current implementation of std::{map, key}::{count, equal_range} in libcxx is non-conforming. Quoting ISO/IEC 14882:2014 section 23.2.4:
> The phrase “equivalence of keys” means the equivalence relation imposed by the comparison and not the
> operator== on keys. That is, two keys k1 and k2 are considered to be equivalent if for the comparison
> object comp, comp(k1, k2) == false && comp(k2, k1) == false.
In the same section, the requirements table states the following:
> a.equal_range(k) equivalent to make_pair(a.lower_bound(k), a.upper_bound(k))
> a.count(k) returns the number of elements with key equivalent to k
The behaviour of libstdc++ seems to conform to the standard here.
Repository:
rCXX libc++
https://reviews.llvm.org/D42344
Files:
include/map
include/set
Index: include/map
===================================================================
--- include/map
+++ include/map
@@ -1223,12 +1223,12 @@
_LIBCPP_INLINE_VISIBILITY
size_type count(const key_type& __k) const
- {return __tree_.__count_unique(__k);}
+ {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) const {return __tree_.__count_unique(__k);}
+ count(const _K2& __k) const {return __tree_.__count_multi(__k);}
#endif
_LIBCPP_INLINE_VISIBILITY
iterator lower_bound(const key_type& __k)
@@ -1267,19 +1267,19 @@
_LIBCPP_INLINE_VISIBILITY
pair<iterator,iterator> equal_range(const key_type& __k)
- {return __tree_.__equal_range_unique(__k);}
+ {return __tree_.__equal_range_multi(__k);}
_LIBCPP_INLINE_VISIBILITY
pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
- {return __tree_.__equal_range_unique(__k);}
+ {return __tree_.__equal_range_multi(__k);}
#if _LIBCPP_STD_VER > 11
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
- equal_range(const _K2& __k) {return __tree_.__equal_range_unique(__k);}
+ equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);}
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
- equal_range(const _K2& __k) const {return __tree_.__equal_range_unique(__k);}
+ equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
#endif
private:
Index: include/set
===================================================================
--- include/set
+++ include/set
@@ -663,12 +663,12 @@
_LIBCPP_INLINE_VISIBILITY
size_type count(const key_type& __k) const
- {return __tree_.__count_unique(__k);}
+ {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) const {return __tree_.__count_unique(__k);}
+ count(const _K2& __k) const {return __tree_.__count_multi(__k);}
#endif
_LIBCPP_INLINE_VISIBILITY
iterator lower_bound(const key_type& __k)
@@ -707,19 +707,19 @@
_LIBCPP_INLINE_VISIBILITY
pair<iterator,iterator> equal_range(const key_type& __k)
- {return __tree_.__equal_range_unique(__k);}
+ {return __tree_.__equal_range_multi(__k);}
_LIBCPP_INLINE_VISIBILITY
pair<const_iterator,const_iterator> equal_range(const key_type& __k) const
- {return __tree_.__equal_range_unique(__k);}
+ {return __tree_.__equal_range_multi(__k);}
#if _LIBCPP_STD_VER > 11
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type
- equal_range(const _K2& __k) {return __tree_.__equal_range_unique(__k);}
+ equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);}
template <typename _K2>
_LIBCPP_INLINE_VISIBILITY
typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type
- equal_range(const _K2& __k) const {return __tree_.__equal_range_unique(__k);}
+ equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);}
#endif
};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D42344.130792.patch
Type: text/x-patch
Size: 3742 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180121/a71f5b8b/attachment-0001.bin>
More information about the cfe-commits
mailing list