Skip to content

Commit b07b5bd

Browse files
committed
[libc++] Test that our algorithms never copy a user-provided comparator.
This is not mandated by the standard, so it goes in libcxx/test/libcxx/. It's certainly arguable that the algorithms changed here (`is_heap`, `is_sorted`, `min`, `max`) are harmless and we should just let them copy their comparators once. But at the same time, it's nice to have all our algorithms be 100% consistent and never copy a comparator, not even once. Differential Revision: https://reviews.llvm.org/D114136
1 parent d8e5a0c commit b07b5bd

File tree

12 files changed

+264
-40
lines changed

12 files changed

+264
-40
lines changed

libcxx/include/__algorithm/binary_search.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
#include <__config>
1313
#include <__algorithm/comp.h>
14-
#include <__algorithm/lower_bound.h>
1514
#include <__algorithm/comp_ref_type.h>
15+
#include <__algorithm/lower_bound.h>
1616
#include <__iterator/iterator_traits.h>
1717

1818
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)

libcxx/include/__algorithm/is_heap.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <__config>
1313
#include <__algorithm/comp.h>
14+
#include <__algorithm/comp_ref_type.h>
1415
#include <__algorithm/is_heap_until.h>
1516
#include <__iterator/iterator_traits.h>
1617

@@ -26,7 +27,8 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2627
bool
2728
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
2829
{
29-
return _VSTD::is_heap_until(__first, __last, __comp) == __last;
30+
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
31+
return _VSTD::__is_heap_until<_Comp_ref>(__first, __last, __comp) == __last;
3032
}
3133

3234
template<class _RandomAccessIterator>

libcxx/include/__algorithm/is_heap_until.h

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <__config>
1313
#include <__algorithm/comp.h>
14+
#include <__algorithm/comp_ref_type.h>
1415
#include <__iterator/iterator_traits.h>
1516

1617
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -19,9 +20,9 @@
1920

2021
_LIBCPP_BEGIN_NAMESPACE_STD
2122

22-
template <class _RandomAccessIterator, class _Compare>
23-
_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
24-
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
23+
template <class _Compare, class _RandomAccessIterator>
24+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
25+
__is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
2526
{
2627
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
2728
difference_type __len = __last - __first;
@@ -46,13 +47,19 @@ is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp
4647
return __last;
4748
}
4849

50+
template <class _RandomAccessIterator, class _Compare>
51+
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
52+
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
53+
{
54+
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
55+
return _VSTD::__is_heap_until<_Comp_ref>(__first, __last, __comp);
56+
}
57+
4958
template<class _RandomAccessIterator>
50-
_LIBCPP_NODISCARD_EXT inline
51-
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
52-
_RandomAccessIterator
59+
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
5360
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
5461
{
55-
return _VSTD::is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
62+
return _VSTD::__is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
5663
}
5764

5865
_LIBCPP_END_NAMESPACE_STD

libcxx/include/__algorithm/is_sorted.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define _LIBCPP___ALGORITHM_IS_SORTED_H
1111

1212
#include <__algorithm/comp.h>
13+
#include <__algorithm/comp_ref_type.h>
1314
#include <__algorithm/is_sorted_until.h>
1415
#include <__config>
1516
#include <__iterator/iterator_traits.h>
@@ -26,7 +27,8 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2627
bool
2728
is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
2829
{
29-
return _VSTD::is_sorted_until(__first, __last, __comp) == __last;
30+
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
31+
return _VSTD::__is_sorted_until<_Comp_ref>(__first, __last, __comp) == __last;
3032
}
3133

3234
template<class _ForwardIterator>

libcxx/include/__algorithm/is_sorted_until.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <__config>
1313
#include <__algorithm/comp.h>
14+
#include <__algorithm/comp_ref_type.h>
1415
#include <__iterator/iterator_traits.h>
1516

1617
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -19,9 +20,9 @@
1920

2021
_LIBCPP_BEGIN_NAMESPACE_STD
2122

22-
template <class _ForwardIterator, class _Compare>
23-
_LIBCPP_NODISCARD_EXT _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
24-
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
23+
template <class _Compare, class _ForwardIterator>
24+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
25+
__is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
2526
{
2627
if (__first != __last)
2728
{
@@ -36,10 +37,16 @@ is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __co
3637
return __last;
3738
}
3839

40+
template <class _ForwardIterator, class _Compare>
41+
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
42+
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
43+
{
44+
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
45+
return _VSTD::__is_sorted_until<_Comp_ref>(__first, __last, __comp);
46+
}
47+
3948
template<class _ForwardIterator>
40-
_LIBCPP_NODISCARD_EXT inline
41-
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
42-
_ForwardIterator
49+
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _ForwardIterator
4350
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
4451
{
4552
return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>());

libcxx/include/__algorithm/max.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <__config>
1313
#include <__algorithm/comp.h>
14+
#include <__algorithm/comp_ref_type.h>
1415
#include <__algorithm/max_element.h>
1516
#include <initializer_list>
1617

@@ -49,7 +50,8 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4950
_Tp
5051
max(initializer_list<_Tp> __t, _Compare __comp)
5152
{
52-
return *_VSTD::max_element(__t.begin(), __t.end(), __comp);
53+
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
54+
return *_VSTD::__max_element<_Comp_ref>(__t.begin(), __t.end(), __comp);
5355
}
5456

5557
template<class _Tp>

libcxx/include/__algorithm/max_element.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <__config>
1313
#include <__algorithm/comp.h>
14+
#include <__algorithm/comp_ref_type.h>
1415
#include <__iterator/iterator_traits.h>
1516

1617
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -19,11 +20,9 @@
1920

2021
_LIBCPP_BEGIN_NAMESPACE_STD
2122

22-
template <class _ForwardIterator, class _Compare>
23-
_LIBCPP_NODISCARD_EXT inline
24-
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
25-
_ForwardIterator
26-
max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
23+
template <class _Compare, class _ForwardIterator>
24+
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
25+
__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
2726
{
2827
static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
2928
"std::max_element requires a ForwardIterator");
@@ -37,11 +36,17 @@ max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
3736
return __first;
3837
}
3938

39+
template <class _ForwardIterator, class _Compare>
40+
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
41+
max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
42+
{
43+
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
44+
return _VSTD::__max_element<_Comp_ref>(__first, __last, __comp);
45+
}
46+
4047

4148
template <class _ForwardIterator>
42-
_LIBCPP_NODISCARD_EXT inline
43-
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
44-
_ForwardIterator
49+
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
4550
max_element(_ForwardIterator __first, _ForwardIterator __last)
4651
{
4752
return _VSTD::max_element(__first, __last,

libcxx/include/__algorithm/min.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <__config>
1313
#include <__algorithm/comp.h>
14+
#include <__algorithm/comp_ref_type.h>
1415
#include <__algorithm/min_element.h>
1516
#include <initializer_list>
1617

@@ -49,7 +50,8 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
4950
_Tp
5051
min(initializer_list<_Tp> __t, _Compare __comp)
5152
{
52-
return *_VSTD::min_element(__t.begin(), __t.end(), __comp);
53+
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
54+
return *_VSTD::__min_element<_Comp_ref>(__t.begin(), __t.end(), __comp);
5355
}
5456

5557
template<class _Tp>

libcxx/include/__algorithm/min_element.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <__config>
1313
#include <__algorithm/comp.h>
14+
#include <__algorithm/comp_ref_type.h>
1415
#include <__iterator/iterator_traits.h>
1516

1617
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -19,11 +20,9 @@
1920

2021
_LIBCPP_BEGIN_NAMESPACE_STD
2122

22-
template <class _ForwardIterator, class _Compare>
23-
_LIBCPP_NODISCARD_EXT inline
24-
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
25-
_ForwardIterator
26-
min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
23+
template <class _Compare, class _ForwardIterator>
24+
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
25+
__min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
2726
{
2827
static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value,
2928
"std::min_element requires a ForwardIterator");
@@ -37,10 +36,16 @@ min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
3736
return __first;
3837
}
3938

39+
template <class _ForwardIterator, class _Compare>
40+
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
41+
min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
42+
{
43+
typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
44+
return _VSTD::__min_element<_Comp_ref>(__first, __last, __comp);
45+
}
46+
4047
template <class _ForwardIterator>
41-
_LIBCPP_NODISCARD_EXT inline
42-
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
43-
_ForwardIterator
48+
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 _ForwardIterator
4449
min_element(_ForwardIterator __first, _ForwardIterator __last)
4550
{
4651
return _VSTD::min_element(__first, __last,

0 commit comments

Comments
 (0)