[RFC] Minimize functor copy in algos
François Dumont
frs.dumont@gmail.com
Mon May 25 19:54:26 GMT 2026
In my attempt to rewrite predefined ops was also an attempt to improve
how the functor were passed within implementation details of the
different algos.
https://gcc.gnu.org/pipermail/libstdc++/2024-October/059677.html
As it seems to be a hot subject lately I rebased it and proposing it here.
Even if Nathan Myers approach to work on 1 algo at a time is also a good
approach.
There are still some occasions where the functor is passed by copy, when
building __gnu_cxx::_ops functors, I'm going to have a look at it.
Let me know if I should leave it to Nathan Myers.
François
-------------- next part --------------
diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index 1a03db66112..89c4bc3240c 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -195,10 +195,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @} group utilities
#define _GLIBCXX_FWDREF(_Tp) _Tp&&
+#define _GLIBCXX_CP_FWDREF(_Tp) _Tp&&
#define _GLIBCXX_MOVE(__val) std::move(__val)
#define _GLIBCXX_FORWARD(_Tp, __val) std::forward<_Tp>(__val)
#else
#define _GLIBCXX_FWDREF(_Tp) const _Tp&
+#define _GLIBCXX_CP_FWDREF(_Tp) _Tp
#define _GLIBCXX_MOVE(__val) (__val)
#define _GLIBCXX_FORWARD(_Tp, __val) (__val)
#endif
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index adf9b9e0f28..3dd5861b4c3 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -86,7 +86,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX20_CONSTEXPR
void
__move_median_to_first(_Iterator __result, _Iterator __a, _Iterator __b,
- _Iterator __c, _Compare __comp)
+ _Iterator __c, _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
if (__comp(*__a, *__b))
{
@@ -110,7 +110,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX20_CONSTEXPR
inline _InputIterator
__find_if_not(_InputIterator __first, _InputIterator __last,
- _Predicate __pred)
+ _GLIBCXX_CP_FWDREF(_Predicate) __pred)
{
return std::__find_if(__first, __last,
__gnu_cxx::__ops::not1(__pred));
@@ -122,7 +122,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _InputIterator, typename _Predicate, typename _Distance>
_GLIBCXX20_CONSTEXPR
_InputIterator
- __find_if_not_n(_InputIterator __first, _Distance& __len, _Predicate __pred)
+ __find_if_not_n(_InputIterator __first, _Distance& __len,
+ _GLIBCXX_CP_FWDREF(_Predicate) __pred)
{
for (; __len; --__len, (void) ++__first)
if (!__pred(*__first))
@@ -152,7 +153,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX20_CONSTEXPR
_ForwardIterator
__search_n_aux(_ForwardIterator __first, _ForwardIterator __last,
- _Integer __count, _UnaryPredicate __unary_pred,
+ _Integer __count,
+ _GLIBCXX_CP_FWDREF(_UnaryPredicate) __unary_pred,
std::forward_iterator_tag)
{
__first = std::__find_if(__first, __last, __unary_pred);
@@ -185,7 +187,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX20_CONSTEXPR
_RandomAccessIter
__search_n_aux(_RandomAccessIter __first, _RandomAccessIter __last,
- _Integer __count, _UnaryPredicate __unary_pred,
+ _Integer __count,
+ _GLIBCXX_CP_FWDREF(_UnaryPredicate) __unary_pred,
std::random_access_iterator_tag)
{
typedef typename std::iterator_traits<_RandomAccessIter>::difference_type
@@ -217,15 +220,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_ForwardIterator
__search_n(_ForwardIterator __first, _ForwardIterator __last,
_Integer __count,
- _UnaryPredicate __unary_pred)
+ _GLIBCXX_CP_FWDREF(_UnaryPredicate) __unary_pred)
{
if (__count <= 0)
return __first;
if (__count == 1)
- return std::__find_if(__first, __last, __unary_pred);
+ return std::__find_if(__first, __last,
+ _GLIBCXX_FORWARD(_UnaryPredicate, __unary_pred));
- return std::__search_n_aux(__first, __last, __count, __unary_pred,
+ return std::__search_n_aux(__first, __last, __count,
+ _GLIBCXX_FORWARD(_UnaryPredicate, __unary_pred),
std::__iter_concept_or_category(__first));
}
@@ -237,7 +242,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2,
forward_iterator_tag, forward_iterator_tag,
- _BinaryPredicate __comp)
+ _GLIBCXX_CP_FWDREF(_BinaryPredicate) __comp)
{
if (__first2 == __last2)
return __last1;
@@ -268,7 +273,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_BidirectionalIterator2 __first2,
_BidirectionalIterator2 __last2,
bidirectional_iterator_tag, bidirectional_iterator_tag,
- _BinaryPredicate __comp)
+ _GLIBCXX_CP_FWDREF(_BinaryPredicate) __comp)
{
// concept requirements
__glibcxx_function_requires(_BidirectionalIteratorConcept<
@@ -283,7 +288,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_RevIterator2 __rlast2(__first2);
_RevIterator1 __rresult = std::__search(_RevIterator1(__last1), __rlast1,
_RevIterator2(__last2), __rlast2,
- __comp);
+ _GLIBCXX_FORWARD(_BinaryPredicate, __comp));
if (__rresult == __rlast1)
return __last1;
@@ -390,7 +395,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return std::__find_end(__first1, __last1, __first2, __last2,
std::__iter_concept_or_category(__first1),
std::__iter_concept_or_category(__first2),
- __comp);
+ _GLIBCXX_MOVE(__comp));
}
#if __cplusplus >= 201103L
@@ -410,7 +415,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
- { return __last == std::find_if_not(__first, __last, __pred); }
+ { return __last == std::find_if_not(__first, __last, std::move(__pred)); }
/**
* @brief Checks that a predicate is false for all the elements
@@ -428,7 +433,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
- { return __last == _GLIBCXX_STD_A::find_if(__first, __last, __pred); }
+ {
+ return
+ __last == _GLIBCXX_STD_A::find_if(__first, __last, std::move(__pred));
+ }
/**
* @brief Checks that a predicate is true for at least one element
@@ -447,7 +455,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
inline bool
any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
- { return !std::none_of(__first, __last, __pred); }
+ { return !std::none_of(__first, __last, std::move(__pred)); }
/**
* @brief Find the first element in a sequence for which a
@@ -470,7 +478,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
typename iterator_traits<_InputIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__find_if_not(__first, __last, __pred);
+ return std::__find_if_not(__first, __last, std::move(__pred));
}
/**
@@ -493,7 +501,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__first == __last)
return true;
++__first;
- return std::none_of(__first, __last, __pred);
+ return std::none_of(__first, __last, std::move(__pred));
}
/**
@@ -540,14 +548,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
return __first;
}
-#endif
+#endif // C++11
template<typename _InputIterator, typename _OutputIterator,
typename _Predicate>
_GLIBCXX20_CONSTEXPR
_OutputIterator
__remove_copy_if(_InputIterator __first, _InputIterator __last,
- _OutputIterator __result, _Predicate __pred)
+ _OutputIterator __result,
+ _GLIBCXX_CP_FWDREF(_Predicate) __pred)
{
for (; __first != __last; ++__first)
if (!__pred(*__first))
@@ -620,7 +629,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename iterator_traits<_InputIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__remove_copy_if(__first, __last, __result, __pred);
+ return std::__remove_copy_if(__first, __last, __result,
+ _GLIBCXX_MOVE(__pred));
}
#if __cplusplus >= 201103L
@@ -811,14 +821,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__remove_if(__first, __last, __pred);
+ return std::__remove_if(__first, __last,
+ _GLIBCXX_MOVE(__pred));
}
template<typename _ForwardIterator, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_ForwardIterator
__adjacent_find(_ForwardIterator __first, _ForwardIterator __last,
- _BinaryPredicate __binary_pred)
+ _GLIBCXX_CP_FWDREF(_BinaryPredicate) __binary_pred)
{
if (__first == __last)
return __last;
@@ -836,7 +847,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX20_CONSTEXPR
_ForwardIterator
__unique(_ForwardIterator __first, _ForwardIterator __last,
- _BinaryPredicate __binary_pred)
+ _GLIBCXX_CP_FWDREF(_BinaryPredicate) __binary_pred)
{
// Skip the beginning, if already unique.
__first = std::__adjacent_find(__first, __last, __binary_pred);
@@ -910,7 +921,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__unique(__first, __last, __binary_pred);
+ return std::__unique(__first, __last,
+ _GLIBCXX_MOVE(__binary_pred));
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -923,7 +935,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX20_CONSTEXPR
_OutputIterator
__unique_copy(_ForwardIterator __first, _ForwardIterator __last,
- _OutputIterator __result, _BinaryPredicate __binary_pred,
+ _OutputIterator __result,
+ _GLIBCXX_CP_FWDREF(_BinaryPredicate) __binary_pred,
forward_iterator_tag)
{
_ForwardIterator __prev = __first;
@@ -944,7 +957,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX20_CONSTEXPR
_OutputIterator
__unique_copy_1(_InputIterator __first, _InputIterator __last,
- _OutputIterator __result, _BinaryPredicate __binary_pred,
+ _OutputIterator __result,
+ _GLIBCXX_CP_FWDREF(_BinaryPredicate) __binary_pred,
__false_type)
{
typedef typename iterator_traits<_InputIterator>::value_type _Val;
@@ -965,7 +979,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _BinaryPredicate>
_ForwardIterator
__unique_copy_1(_InputIterator __first, _InputIterator __last,
- _ForwardIterator __result, _BinaryPredicate __binary_pred,
+ _ForwardIterator __result,
+ _GLIBCXX_CP_FWDREF(_BinaryPredicate) __binary_pred,
__true_type)
{
*__result = *__first;
@@ -1386,7 +1401,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_GLIBCXX20_CONSTEXPR
_ForwardIterator
__partition(_ForwardIterator __first, _ForwardIterator __last,
- _Predicate __pred, forward_iterator_tag)
+ _GLIBCXX_CP_FWDREF(_Predicate) __pred, forward_iterator_tag)
{
if (__first == __last)
return __first;
@@ -1412,7 +1427,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_GLIBCXX20_CONSTEXPR
_BidirectionalIterator
__partition(_BidirectionalIterator __first, _BidirectionalIterator __last,
- _Predicate __pred, bidirectional_iterator_tag)
+ _GLIBCXX_CP_FWDREF(_Predicate) __pred, bidirectional_iterator_tag)
{
while (true)
{
@@ -1451,7 +1466,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_ForwardIterator
__stable_partition_adaptive(_ForwardIterator __first,
_ForwardIterator __last,
- _Predicate __pred, _Distance __len,
+ _GLIBCXX_CP_FWDREF(_Predicate) __pred,
+ _Distance __len,
_Pointer __buffer,
_Distance __buffer_size)
{
@@ -1500,7 +1516,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
if (__right_len)
__right_split =
- std::__stable_partition_adaptive(__right_split, __last, __pred,
+ std::__stable_partition_adaptive(__right_split, __last,
+ _GLIBCXX_FORWARD(_Predicate, __pred),
__right_len,
__buffer, __buffer_size);
@@ -1511,7 +1528,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_GLIBCXX26_CONSTEXPR
_ForwardIterator
__stable_partition(_ForwardIterator __first, _ForwardIterator __last,
- _Predicate __pred)
+ _GLIBCXX_CP_FWDREF(_Predicate) __pred)
{
__first = std::__find_if_not(__first, __last, __pred);
@@ -1540,7 +1557,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_Temporary_buffer<_ForwardIterator, _ValueType>
__buf(__first, __len);
return
- std::__stable_partition_adaptive(__first, __last, __pred,
+ std::__stable_partition_adaptive(__first, __last,
+ _GLIBCXX_FORWARD(_Predicate, __pred),
__len,
__buf.begin(),
_DistanceType(__buf.size()));
@@ -1576,7 +1594,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__stable_partition(__first, __last, __pred);
+ return std::__stable_partition(__first, __last,
+ _GLIBCXX_MOVE(__pred));
}
#endif // HOSTED
@@ -1588,7 +1607,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
void
__heap_select(_RandomAccessIterator __first,
_RandomAccessIterator __middle,
- _RandomAccessIterator __last, _Compare __comp)
+ _RandomAccessIterator __last,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
std::__make_heap(__first, __middle, __comp);
for (_RandomAccessIterator __i = __middle; __i < __last; ++__i)
@@ -1605,7 +1625,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__partial_sort_copy(_InputIterator __first, _InputIterator __last,
_RandomAccessIterator __result_first,
_RandomAccessIterator __result_last,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
typedef typename iterator_traits<_InputIterator>::value_type
_InputValueType;
@@ -1632,7 +1652,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_InputValueType(*__first), __comp);
++__first;
}
- std::__sort_heap(__result_first, __result_real_last, __comp);
+ std::__sort_heap(__result_first, __result_real_last,
+ _GLIBCXX_FORWARD(_Compare, __comp));
return __result_real_last;
}
@@ -1738,7 +1759,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
return std::__partial_sort_copy(__first, __last,
__result_first, __result_last,
- __comp);
+ _GLIBCXX_MOVE(__comp));
}
/// @cond undocumented
@@ -1748,7 +1769,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_GLIBCXX20_CONSTEXPR
void
__unguarded_linear_insert(_RandomAccessIterator __last,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
typename iterator_traits<_RandomAccessIterator>::value_type
__val = _GLIBCXX_MOVE(*__last);
@@ -1768,7 +1789,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_GLIBCXX20_CONSTEXPR
void
__insertion_sort(_RandomAccessIterator __first,
- _RandomAccessIterator __last, _Compare __comp)
+ _RandomAccessIterator __last,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
if (__first == __last)
return;
@@ -1794,7 +1816,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_GLIBCXX20_CONSTEXPR
inline void
__unguarded_insertion_sort(_RandomAccessIterator __first,
- _RandomAccessIterator __last, _Compare __comp)
+ _RandomAccessIterator __last,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
for (_RandomAccessIterator __i = __first; __i != __last; ++__i)
std::__unguarded_linear_insert(__i, __comp);
@@ -1811,7 +1834,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_GLIBCXX20_CONSTEXPR
void
__final_insertion_sort(_RandomAccessIterator __first,
- _RandomAccessIterator __last, _Compare __comp)
+ _RandomAccessIterator __last,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
typename iterator_traits<_RandomAccessIterator>::difference_type
__threshold = _S_threshold;
@@ -1820,10 +1844,11 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
{
std::__insertion_sort(__first, __first + __threshold, __comp);
std::__unguarded_insertion_sort(__first + __threshold, __last,
- __comp);
+ _GLIBCXX_FORWARD(_Compare, __comp));
}
else
- std::__insertion_sort(__first, __last, __comp);
+ std::__insertion_sort(__first, __last,
+ _GLIBCXX_FORWARD(_Compare, __comp));
}
/// This is a helper function...
@@ -1832,7 +1857,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_RandomAccessIterator
__unguarded_partition(_RandomAccessIterator __first,
_RandomAccessIterator __last,
- _RandomAccessIterator __pivot, _Compare __comp)
+ _RandomAccessIterator __pivot,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
while (true)
{
@@ -1853,7 +1879,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_GLIBCXX20_CONSTEXPR
inline _RandomAccessIterator
__unguarded_partition_pivot(_RandomAccessIterator __first,
- _RandomAccessIterator __last, _Compare __comp)
+ _RandomAccessIterator __last,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
typedef iterator_traits<_RandomAccessIterator> _IterTraits;
typedef typename _IterTraits::difference_type _Dist;
@@ -1862,7 +1889,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_RandomAccessIterator __second = __first + _Dist(1);
std::__move_median_to_first(__first, __second, __mid, __last - _Dist(1),
__comp);
- return std::__unguarded_partition(__second, __last, __first, __comp);
+ return std::__unguarded_partition(__second, __last, __first,
+ _GLIBCXX_FORWARD(_Compare, __comp));
}
template<typename _RandomAccessIterator, typename _Compare>
@@ -1871,10 +1899,10 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__partial_sort(_RandomAccessIterator __first,
_RandomAccessIterator __middle,
_RandomAccessIterator __last,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
std::__heap_select(__first, __middle, __last, __comp);
- std::__sort_heap(__first, __middle, __comp);
+ std::__sort_heap(__first, __middle, _GLIBCXX_FORWARD(_Compare, __comp));
}
/// This is a helper function for the sort routine.
@@ -1883,13 +1911,14 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
void
__introsort_loop(_RandomAccessIterator __first,
_RandomAccessIterator __last,
- _Size __depth_limit, _Compare __comp)
+ _Size __depth_limit, _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
while (__last - __first > int(_S_threshold))
{
if (__depth_limit == 0)
{
- std::__partial_sort(__first, __last, __last, __comp);
+ std::__partial_sort(__first, __last, __last,
+ _GLIBCXX_FORWARD(_Compare, __comp));
return;
}
--__depth_limit;
@@ -1906,14 +1935,15 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_GLIBCXX20_CONSTEXPR
inline void
__sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
if (__first != __last)
{
std::__introsort_loop(__first, __last,
std::__lg(__last - __first) * 2,
__comp);
- std::__final_insertion_sort(__first, __last, __comp);
+ std::__final_insertion_sort(__first, __last,
+ _GLIBCXX_FORWARD(_Compare, __comp));
}
}
@@ -1922,7 +1952,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
void
__introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth,
_RandomAccessIterator __last, _Size __depth_limit,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
_RandomAccessIterator __after_nth = __nth;
++__after_nth;
@@ -1931,7 +1961,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
{
if (__depth_limit == 0)
{
- std::__heap_select(__first, __after_nth, __last, __comp);
+ std::__heap_select(__first, __after_nth, __last,
+ _GLIBCXX_FORWARD(_Compare, __comp));
// Place the nth largest element in its final position.
std::iter_swap(__first, __nth);
return;
@@ -1944,7 +1975,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
else
__last = __cut;
}
- std::__insertion_sort(__first, __last, __comp);
+ std::__insertion_sort(__first, __last,
+ _GLIBCXX_FORWARD(_Compare, __comp));
}
/// @endcond
@@ -1981,14 +2013,16 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__glibcxx_requires_partitioned_lower_pred(__first, __last,
__val, __comp);
- return std::__lower_bound(__first, __last, __val, __comp);
+ return std::__lower_bound(__first, __last, __val,
+ _GLIBCXX_MOVE(__comp));
}
template<typename _ForwardIterator, typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
_ForwardIterator
__upper_bound(_ForwardIterator __first, _ForwardIterator __last,
- const _Tp& __val, _Compare __comp)
+ _GLIBCXX_FWDREF(_Tp) __val,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
typedef typename iterator_traits<_ForwardIterator>::difference_type
_DistanceType;
@@ -2067,14 +2101,16 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__glibcxx_requires_partitioned_upper_pred(__first, __last,
__val, __comp);
- return std::__upper_bound(__first, __last, __val, __comp);
+ return std::__upper_bound(__first, __last, __val,
+ _GLIBCXX_MOVE(__comp));
}
template<typename _ForwardIterator, typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
pair<_ForwardIterator, _ForwardIterator>
__equal_range(_ForwardIterator __first, _ForwardIterator __last,
- const _Tp& __val, _Compare __comp)
+ const _Tp& __val,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
typedef typename iterator_traits<_ForwardIterator>::difference_type
_DistanceType;
@@ -2100,7 +2136,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
= std::__lower_bound(__first, __middle, __val, __comp);
std::advance(__first, __len);
_ForwardIterator __right
- = std::__upper_bound(++__middle, __first, __val, __comp);
+ = std::__upper_bound(++__middle, __first, __val,
+ _GLIBCXX_FORWARD(_Compare, __comp));
return pair<_ForwardIterator, _ForwardIterator>(__left, __right);
}
}
@@ -2177,7 +2214,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__glibcxx_requires_partitioned_upper_pred(__first, __last,
__val, __comp);
- return std::__equal_range(__first, __last, __val, __comp);
+ return std::__equal_range(__first, __last, __val,
+ _GLIBCXX_MOVE(__comp));
}
/**
@@ -2253,7 +2291,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
void
__move_merge_adaptive(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
- _OutputIterator __result, _Compare __comp)
+ _OutputIterator __result,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
while (__first1 != __last1 && __first2 != __last2)
{
@@ -2282,7 +2321,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_BidirectionalIterator2 __first2,
_BidirectionalIterator2 __last2,
_BidirectionalIterator3 __result,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
if (__first1 == __last1)
{
@@ -2362,19 +2401,21 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_BidirectionalIterator __middle,
_BidirectionalIterator __last,
_Distance __len1, _Distance __len2,
- _Pointer __buffer, _Compare __comp)
+ _Pointer __buffer, _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
if (__len1 <= __len2)
{
_Pointer __buffer_end = _GLIBCXX_MOVE3(__first, __middle, __buffer);
std::__move_merge_adaptive(__buffer, __buffer_end, __middle, __last,
- __first, __comp);
+ __first,
+ _GLIBCXX_FORWARD(_Compare, __comp));
}
else
{
_Pointer __buffer_end = _GLIBCXX_MOVE3(__middle, __last, __buffer);
std::__move_merge_adaptive_backward(__first, __middle, __buffer,
- __buffer_end, __last, __comp);
+ __buffer_end, __last,
+ _GLIBCXX_FORWARD(_Compare, __comp));
}
}
@@ -2386,11 +2427,12 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_BidirectionalIterator __last,
_Distance __len1, _Distance __len2,
_Pointer __buffer, _Distance __buffer_size,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
if (__len1 <= __buffer_size || __len2 <= __buffer_size)
std::__merge_adaptive(__first, __middle, __last,
- __len1, __len2, __buffer, __comp);
+ __len1, __len2, __buffer,
+ _GLIBCXX_FORWARD(_Compare, __comp));
else
{
_BidirectionalIterator __first_cut = __first;
@@ -2424,7 +2466,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
std::__merge_adaptive_resize(__new_middle, __second_cut, __last,
_Distance(__len1 - __len11),
_Distance(__len2 - __len22),
- __buffer, __buffer_size, __comp);
+ __buffer, __buffer_size,
+ _GLIBCXX_FORWARD(_Compare, __comp));
}
}
@@ -2437,7 +2480,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_BidirectionalIterator __middle,
_BidirectionalIterator __last,
_Distance __len1, _Distance __len2,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
if (__len1 == 0 || __len2 == 0)
return;
@@ -2475,7 +2518,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
std::__merge_without_buffer(__first, __first_cut, __new_middle,
__len11, __len22, __comp);
std::__merge_without_buffer(__new_middle, __second_cut, __last,
- __len1 - __len11, __len2 - __len22, __comp);
+ __len1 - __len11, __len2 - __len22,
+ _GLIBCXX_FORWARD(_Compare, __comp));
}
template<typename _BidirectionalIterator, typename _Compare>
@@ -2484,7 +2528,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__inplace_merge(_BidirectionalIterator __first,
_BidirectionalIterator __middle,
_BidirectionalIterator __last,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
typedef typename iterator_traits<_BidirectionalIterator>::value_type
_ValueType;
@@ -2511,17 +2555,20 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
if (__builtin_expect(__buf.size() == __buf._M_requested_size(), true))
std::__merge_adaptive
- (__first, __middle, __last, __len1, __len2, __buf.begin(), __comp);
+ (__first, __middle, __last, __len1, __len2, __buf.begin(),
+ _GLIBCXX_FORWARD(_Compare, __comp));
else if (__builtin_expect(__buf.begin() == 0, false))
std::__merge_without_buffer
- (__first, __middle, __last, __len1, __len2, __comp);
+ (__first, __middle, __last, __len1, __len2,
+ _GLIBCXX_FORWARD(_Compare, __comp));
else
std::__merge_adaptive_resize
(__first, __middle, __last, __len1, __len2, __buf.begin(),
- _DistanceType(__buf.size()), __comp);
+ _DistanceType(__buf.size()), _GLIBCXX_FORWARD(_Compare, __comp));
#else
std::__merge_without_buffer
- (__first, __middle, __last, __len1, __len2, __comp);
+ (__first, __middle, __last, __len1, __len2,
+ _GLIBCXX_FORWARD(_Compare, __comp));
#endif
}
@@ -2601,7 +2648,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__glibcxx_requires_sorted_pred(__middle, __last, __comp);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
- std::__inplace_merge(__first, __middle, __last, __comp);
+ std::__inplace_merge(__first, __middle, __last,
+ _GLIBCXX_MOVE(__comp));
}
@@ -2611,7 +2659,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_OutputIterator
__move_merge(_InputIterator __first1, _InputIterator __last1,
_InputIterator __first2, _InputIterator __last2,
- _OutputIterator __result, _Compare __comp)
+ _OutputIterator __result, _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
while (__first1 != __last1 && __first2 != __last2)
{
@@ -2638,7 +2686,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__merge_sort_loop(_RandomAccessIterator1 __first,
_RandomAccessIterator1 __last,
_RandomAccessIterator2 __result, _Distance __step_size,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
const _Distance __two_step = 2 * __step_size;
@@ -2653,7 +2701,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__step_size = std::min(_Distance(__last - __first), __step_size);
std::__move_merge(__first, __first + __step_size,
- __first + __step_size, __last, __result, __comp);
+ __first + __step_size, __last, __result,
+ _GLIBCXX_FORWARD(_Compare, __comp));
}
template<typename _RandomAccessIterator, typename _Distance,
@@ -2662,14 +2711,16 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
void
__chunk_insertion_sort(_RandomAccessIterator __first,
_RandomAccessIterator __last,
- _Distance __chunk_size, _Compare __comp)
+ _Distance __chunk_size,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
while (__last - __first >= __chunk_size)
{
std::__insertion_sort(__first, __first + __chunk_size, __comp);
__first += __chunk_size;
}
- std::__insertion_sort(__first, __last, __comp);
+ std::__insertion_sort(__first, __last,
+ _GLIBCXX_FORWARD(_Compare, __comp));
}
enum { _S_chunk_size = 7 };
@@ -2678,7 +2729,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
void
__merge_sort_with_buffer(_RandomAccessIterator __first,
_RandomAccessIterator __last,
- _Pointer __buffer, _Compare __comp)
+ _Pointer __buffer,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::difference_type
_Distance;
@@ -2705,14 +2757,15 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__stable_sort_adaptive(_RandomAccessIterator __first,
_RandomAccessIterator __middle,
_RandomAccessIterator __last,
- _Pointer __buffer, _Compare __comp)
+ _Pointer __buffer,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
std::__merge_sort_with_buffer(__first, __middle, __buffer, __comp);
std::__merge_sort_with_buffer(__middle, __last, __buffer, __comp);
std::__merge_adaptive(__first, __middle, __last,
__middle - __first, __last - __middle,
- __buffer, __comp);
+ __buffer, _GLIBCXX_FORWARD(_Compare, __comp));
}
template<typename _RandomAccessIterator, typename _Pointer,
@@ -2721,7 +2774,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__stable_sort_adaptive_resize(_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Pointer __buffer, _Distance __buffer_size,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
const _Distance __len = (__last - __first + 1) / 2;
const _RandomAccessIterator __middle = __first + __len;
@@ -2735,11 +2788,11 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_Distance(__middle - __first),
_Distance(__last - __middle),
__buffer, __buffer_size,
- __comp);
+ _GLIBCXX_FORWARD(_Compare, __comp));
}
else
std::__stable_sort_adaptive(__first, __middle, __last,
- __buffer, __comp);
+ __buffer, _GLIBCXX_FORWARD(_Compare, __comp));
}
/// This is a helper function for the stable sorting routines.
@@ -2747,11 +2800,13 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_GLIBCXX26_CONSTEXPR
void
__inplace_stable_sort(_RandomAccessIterator __first,
- _RandomAccessIterator __last, _Compare __comp)
+ _RandomAccessIterator __last,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
if (__last - __first < 15)
{
- std::__insertion_sort(__first, __last, __comp);
+ std::__insertion_sort(__first, __last,
+ _GLIBCXX_FORWARD(_Compare, __comp));
return;
}
_RandomAccessIterator __middle = __first + (__last - __first) / 2;
@@ -2760,7 +2815,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
std::__merge_without_buffer(__first, __middle, __last,
__middle - __first,
__last - __middle,
- __comp);
+ _GLIBCXX_FORWARD(_Compare, __comp));
}
// stable_sort
@@ -2776,7 +2831,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
bool
__includes(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
while (__first1 != __last1 && __first2 != __last2)
{
@@ -2875,7 +2930,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp);
__glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp);
- return std::__includes(__first1, __last1, __first2, __last2, __comp);
+ return std::__includes(__first1, __last1, __first2, __last2,
+ _GLIBCXX_MOVE(__comp));
}
// nth_element
@@ -2892,7 +2948,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_GLIBCXX20_CONSTEXPR
bool
__next_permutation(_BidirectionalIterator __first,
- _BidirectionalIterator __last, _Compare __comp)
+ _BidirectionalIterator __last,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
if (__first == __last)
return false;
@@ -2985,14 +3042,16 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
- return std::__next_permutation(__first, __last, __comp);
+ return std::__next_permutation
+ (__first, __last, _GLIBCXX_MOVE(__comp));
}
template<typename _BidirectionalIterator, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
__prev_permutation(_BidirectionalIterator __first,
- _BidirectionalIterator __last, _Compare __comp)
+ _BidirectionalIterator __last,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
if (__first == __last)
return false;
@@ -3086,7 +3145,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
- return std::__prev_permutation(__first, __last, __comp);
+ return std::__prev_permutation(__first, __last,
+ _GLIBCXX_MOVE(__comp));
}
// replace
@@ -3098,7 +3158,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_OutputIterator
__replace_copy_if(_InputIterator __first, _InputIterator __last,
_OutputIterator __result,
- _Predicate __pred, const _Tp& __new_value)
+ _GLIBCXX_CP_FWDREF(_Predicate) __pred,
+ const _Tp& __new_value)
{
for (; __first != __last; ++__first, (void)++__result)
if (__pred(*__first))
@@ -3173,8 +3234,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
typename iterator_traits<_InputIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__replace_copy_if(__first, __last, __result, __pred,
- __new_value);
+ return std::__replace_copy_if(__first, __last, __result,
+ _GLIBCXX_MOVE(__pred), __new_value);
}
#if __cplusplus >= 201103L
@@ -3205,13 +3266,15 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
inline bool
is_sorted(_ForwardIterator __first, _ForwardIterator __last,
_Compare __comp)
- { return std::is_sorted_until(__first, __last, __comp) == __last; }
+ {
+ return std::is_sorted_until(__first, __last, std::move(__comp)) == __last;
+ }
template<typename _ForwardIterator, typename _Compare>
_GLIBCXX20_CONSTEXPR
_ForwardIterator
__is_sorted_until(_ForwardIterator __first, _ForwardIterator __last,
- _Compare __comp)
+ _Compare&& __comp)
{
if (__first == __last)
return __last;
@@ -3270,7 +3333,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
- return std::__is_sorted_until(__first, __last, __comp);
+ return std::__is_sorted_until(__first, __last,
+ std::move(__comp));
}
/**
@@ -3315,7 +3379,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
_GLIBCXX14_CONSTEXPR
pair<_ForwardIterator, _ForwardIterator>
__minmax_element(_ForwardIterator __first, _ForwardIterator __last,
- _Compare __comp)
+ _Compare&& __comp)
{
_ForwardIterator __next = __first;
if (__first == __last
@@ -3423,7 +3487,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
- return std::__minmax_element(__first, __last, __comp);
+ return std::__minmax_element(__first, __last,
+ std::move(__comp));
}
template<typename _Tp>
@@ -3445,7 +3510,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
{
__glibcxx_requires_irreflexive_pred(__l.begin(), __l.end(), __comp);
pair<const _Tp*, const _Tp*> __p =
- std::__minmax_element(__l.begin(), __l.end(), __comp);
+ std::__minmax_element(__l.begin(), __l.end(),
+ std::move(__comp));
return std::make_pair(*__p.first, *__p.second);
}
@@ -3478,7 +3544,8 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
typename iterator_traits<_ForwardIterator2>::value_type>)
__glibcxx_requires_valid_range(__first1, __last1);
- return std::__is_permutation(__first1, __last1, __first2, __pred);
+ return std::__is_permutation(__first1, __last1, __first2,
+ std::move(__pred));
}
#if __glibcxx_robust_nonmodifying_seq_ops // C++ >= 14
@@ -3490,7 +3557,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
bool
__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2,
- _BinaryPredicate __pred)
+ _BinaryPredicate&& __pred)
{
using _Cat1 = decltype(std::__iter_concept_or_category<_ForwardIterator1>());
using _Cat2 = decltype(std::__iter_concept_or_category<_ForwardIterator2>());
@@ -3593,7 +3660,7 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
__glibcxx_requires_valid_range(__first2, __last2);
return std::__is_permutation(__first1, __last1, __first2, __last2,
- __pred);
+ std::move(__pred));
}
#endif // __glibcxx_robust_nonmodifying_seq_ops
@@ -3896,7 +3963,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
typename iterator_traits<_InputIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__find_if(__first, __last, __pred);
+ return std::__find_if(__first, __last,
+ _GLIBCXX_MOVE(__pred));
}
/**
@@ -4028,7 +4096,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__adjacent_find(__first, __last, __binary_pred);
+ return std::__adjacent_find(__first, __last,
+ _GLIBCXX_MOVE(__binary_pred));
}
/**
@@ -4075,7 +4144,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
typename iterator_traits<_InputIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__count_if(__first, __last, __pred);
+ return std::__count_if(__first, __last,
+ _GLIBCXX_MOVE(__pred));
}
/**
@@ -4485,7 +4555,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
if (__first == __last)
return __result;
- return std::__unique_copy(__first, __last, __result, __binary_pred,
+ return std::__unique_copy(__first, __last, __result,
+ _GLIBCXX_MOVE(__binary_pred),
std::__iter_concept_or_category(__first));
}
@@ -4631,7 +4702,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
typename iterator_traits<_ForwardIterator>::value_type>)
__glibcxx_requires_valid_range(__first, __last);
- return std::__partition(__first, __last, __pred,
+ return std::__partition(__first, __last, _GLIBCXX_MOVE(__pred),
std::__iterator_category(__first));
}
@@ -4708,7 +4779,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__glibcxx_requires_valid_range(__middle, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
- std::__partial_sort(__first, __middle, __last, __comp);
+ std::__partial_sort(__first, __middle, __last,
+ _GLIBCXX_MOVE(__comp));
}
/**
@@ -4785,7 +4857,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
std::__introselect(__first, __nth, __last,
std::__lg(__last - __first) * 2,
- __comp);
+ _GLIBCXX_MOVE(__comp));
}
/**
@@ -4846,7 +4918,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
- std::__sort(__first, __last, __comp);
+ std::__sort(__first, __last, _GLIBCXX_MOVE(__comp));
}
template<typename _InputIterator1, typename _InputIterator2,
@@ -4855,7 +4927,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
_OutputIterator
__merge(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
- _OutputIterator __result, _Compare __comp)
+ _OutputIterator __result, _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
while (__first1 != __last1 && __first2 != __last2)
{
@@ -4967,15 +5039,16 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp);
__glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp);
- return _GLIBCXX_STD_A::__merge(__first1, __last1, __first2, __last2,
- __result, __comp);
+ return _GLIBCXX_STD_A::__merge(__first1, __last1,
+ __first2, __last2, __result,
+ _GLIBCXX_MOVE(__comp));
}
template<typename _RandomAccessIterator, typename _Compare>
_GLIBCXX26_CONSTEXPR
inline void
__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
@@ -4988,7 +5061,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
#if _GLIBCXX_HOSTED
# if __glibcxx_constexpr_algorithms >= 202306L // >= C++26
if consteval {
- return std::__inplace_stable_sort(__first, __last, __comp);
+ return std::__inplace_stable_sort(__first, __last,
+ std::forward<_Compare>(__comp));
}
# endif
@@ -5000,14 +5074,18 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
if (__builtin_expect(__buf._M_requested_size() == __buf.size(), true))
std::__stable_sort_adaptive(__first,
__first + _DistanceType(__buf.size()),
- __last, __buf.begin(), __comp);
+ __last, __buf.begin(),
+ _GLIBCXX_FORWARD(_Compare, __comp));
else if (__builtin_expect(__buf.begin() == 0, false))
- std::__inplace_stable_sort(__first, __last, __comp);
+ std::__inplace_stable_sort(__first, __last,
+ _GLIBCXX_FORWARD(_Compare, __comp));
else
std::__stable_sort_adaptive_resize(__first, __last, __buf.begin(),
- _DistanceType(__buf.size()), __comp);
+ _DistanceType(__buf.size()),
+ _GLIBCXX_FORWARD(_Compare, __comp));
#else
- std::__inplace_stable_sort(__first, __last, __comp);
+ std::__inplace_stable_sort
+ (__first, __last, _GLIBCXX_FORWARD(_Compare, __comp));
#endif
}
@@ -5076,7 +5154,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
- _GLIBCXX_STD_A::__stable_sort(__first, __last, __comp);
+ _GLIBCXX_STD_A::__stable_sort(__first, __last,
+ _GLIBCXX_MOVE(__comp));
}
template<typename _InputIterator1, typename _InputIterator2,
@@ -5085,7 +5164,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
_OutputIterator
__set_union(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
- _OutputIterator __result, _Compare __comp)
+ _OutputIterator __result, _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
while (__first1 != __last1 && __first2 != __last2)
{
@@ -5206,8 +5285,9 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__glibcxx_requires_irreflexive_pred2(__first1, __last1, __comp);
__glibcxx_requires_irreflexive_pred2(__first2, __last2, __comp);
- return _GLIBCXX_STD_A::__set_union(__first1, __last1, __first2, __last2,
- __result, __comp);
+ return _GLIBCXX_STD_A::__set_union(__first1, __last1,
+ __first2, __last2, __result,
+ _GLIBCXX_MOVE(__comp));
}
template<typename _InputIterator1, typename _InputIterator2,
@@ -5216,7 +5296,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
_OutputIterator
__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
- _OutputIterator __result, _Compare __comp)
+ _OutputIterator __result,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
while (__first1 != __last1 && __first2 != __last2)
if (__comp(*__first1, *__first2))
@@ -5327,7 +5408,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
return _GLIBCXX_STD_A::
__set_intersection(__first1, __last1, __first2, __last2,
- __result, __comp);
+ __result, _GLIBCXX_MOVE(__comp));
}
template<typename _InputIterator1, typename _InputIterator2,
@@ -5336,7 +5417,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
_OutputIterator
__set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
- _OutputIterator __result, _Compare __comp)
+ _OutputIterator __result, _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
while (__first1 != __last1 && __first2 != __last2)
if (__comp(*__first1, *__first2))
@@ -5453,7 +5534,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
return _GLIBCXX_STD_A::
__set_difference(__first1, __last1, __first2, __last2, __result,
- __comp);
+ _GLIBCXX_MOVE(__comp));
}
template<typename _InputIterator1, typename _InputIterator2,
@@ -5466,7 +5547,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
_InputIterator2 __first2,
_InputIterator2 __last2,
_OutputIterator __result,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
while (__first1 != __last1 && __first2 != __last2)
if (__comp(*__first1, *__first2))
@@ -5589,14 +5670,14 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
return _GLIBCXX_STD_A::
__set_symmetric_difference(__first1, __last1, __first2, __last2,
- __result, __comp);
+ __result, _GLIBCXX_MOVE(__comp));
}
template<typename _ForwardIterator, typename _Compare>
_GLIBCXX14_CONSTEXPR
_ForwardIterator
__min_element(_ForwardIterator __first, _ForwardIterator __last,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
if (__first == __last)
return __first;
@@ -5653,14 +5734,15 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
- return _GLIBCXX_STD_A::__min_element(__first, __last, __comp);
+ return _GLIBCXX_STD_A::__min_element(__first, __last,
+ _GLIBCXX_MOVE(__comp));
}
template<typename _ForwardIterator, typename _Compare>
_GLIBCXX14_CONSTEXPR
_ForwardIterator
__max_element(_ForwardIterator __first, _ForwardIterator __last,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
if (__first == __last) return __first;
_ForwardIterator __result = __first;
@@ -5716,7 +5798,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
- return _GLIBCXX_STD_A::__max_element(__first, __last, __comp);
+ return _GLIBCXX_STD_A::__max_element(__first, __last,
+ _GLIBCXX_MOVE(__comp));
}
#if __cplusplus >= 201103L
@@ -5737,7 +5820,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
min(initializer_list<_Tp> __l, _Compare __comp)
{
__glibcxx_requires_irreflexive_pred(__l.begin(), __l.end(), __comp);
- return *_GLIBCXX_STD_A::__min_element(__l.begin(), __l.end(), __comp);
+ return *_GLIBCXX_STD_A::__min_element(__l.begin(), __l.end(),
+ std::move(__comp));
}
template<typename _Tp>
@@ -5756,7 +5840,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
max(initializer_list<_Tp> __l, _Compare __comp)
{
__glibcxx_requires_irreflexive_pred(__l.begin(), __l.end(), __comp);
- return *_GLIBCXX_STD_A::__max_element(__l.begin(), __l.end(), __comp);
+ return *_GLIBCXX_STD_A::__max_element(__l.begin(), __l.end(),
+ std::move(__comp));
}
#endif // C++11
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index 1350736a8d8..b4f682f2afd 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -1327,7 +1327,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
bool
__lexicographical_compare_impl(_II1 __first1, _II1 __last1,
_II2 __first2, _II2 __last2,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
typedef __decltype(std::__iter_concept_or_category<_II1>()) _Category1;
typedef __decltype(std::__iter_concept_or_category<_II2>()) _Category2;
@@ -1500,7 +1500,8 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
_GLIBCXX20_CONSTEXPR
_ForwardIterator
__lower_bound(_ForwardIterator __first, _ForwardIterator __last,
- const _Tp& __val, _Compare __comp)
+ _GLIBCXX_FWDREF(_Tp) __val,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
typedef typename iterator_traits<_ForwardIterator>::difference_type
_DistanceType;
@@ -1670,7 +1671,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
_GLIBCXX20_CONSTEXPR
inline bool
__equal4(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2,
- _BinaryPredicate __binary_pred)
+ _BinaryPredicate&& __binary_pred)
{
using _RATag = random_access_iterator_tag;
using _Cat1 = decltype(std::__iter_concept_or_category<_II1>());
@@ -1681,7 +1682,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
if ((__last1 - __first1) != (__last2 - __first2))
return false;
return _GLIBCXX_STD_A::equal(__first1, __last1, __first2,
- __binary_pred);
+ std::forward<_BinaryPredicate>(__binary_pred));
}
else
{
@@ -1755,7 +1756,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__glibcxx_requires_valid_range(__first2, __last2);
return _GLIBCXX_STD_A::__equal4(__first1, __last1, __first2, __last2,
- __binary_pred);
+ std::move(__binary_pred));
}
#endif // __glibcxx_robust_nonmodifying_seq_ops
@@ -1822,7 +1823,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__glibcxx_requires_valid_range(__first2, __last2);
return std::__lexicographical_compare_impl
- (__first1, __last1, __first2, __last2, __comp);
+ (__first1, __last1, __first2, __last2, _GLIBCXX_MOVE(__comp));
}
#if __cpp_lib_three_way_comparison
@@ -1928,7 +1929,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
_GLIBCXX20_CONSTEXPR
pair<_InputIterator1, _InputIterator2>
__mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
- _InputIterator2 __first2, _BinaryPredicate __binary_pred)
+ _InputIterator2 __first2,
+ _GLIBCXX_CP_FWDREF(_BinaryPredicate) __binary_pred)
{
while (__first1 != __last1 && __binary_pred(*__first1, *__first2))
{
@@ -1998,7 +2000,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__glibcxx_requires_valid_range(__first1, __last1);
return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2,
- __binary_pred);
+ _GLIBCXX_MOVE(__binary_pred));
}
#if __glibcxx_robust_nonmodifying_seq_ops // C++ >= 14
@@ -2008,7 +2010,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
pair<_InputIterator1, _InputIterator2>
__mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
- _BinaryPredicate __binary_pred)
+ _BinaryPredicate&& __binary_pred)
{
while (__first1 != __last1 && __first2 != __last2
&& __binary_pred(*__first1, *__first2))
@@ -2084,7 +2086,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__glibcxx_requires_valid_range(__first2, __last2);
return _GLIBCXX_STD_A::__mismatch(__first1, __last1, __first2, __last2,
- __binary_pred);
+ _GLIBCXX_MOVE(__binary_pred));
}
#endif // __glibcxx_robust_nonmodifying_seq_ops
@@ -2094,7 +2096,8 @@ _GLIBCXX_END_NAMESPACE_ALGO
template<typename _Iterator, typename _Predicate>
_GLIBCXX20_CONSTEXPR
inline _Iterator
- __find_if(_Iterator __first, _Iterator __last, _Predicate __pred)
+ __find_if(_Iterator __first, _Iterator __last,
+ _GLIBCXX_CP_FWDREF(_Predicate) __pred)
{
#pragma GCC unroll 4
while (__first != __last && !__pred(*__first))
@@ -2105,7 +2108,8 @@ _GLIBCXX_END_NAMESPACE_ALGO
template<typename _InputIterator, typename _Predicate>
_GLIBCXX20_CONSTEXPR
typename iterator_traits<_InputIterator>::difference_type
- __count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
+ __count_if(_InputIterator __first, _InputIterator __last,
+ _GLIBCXX_CP_FWDREF(_Predicate) __pred)
{
typename iterator_traits<_InputIterator>::difference_type __n = 0;
for (; __first != __last; ++__first)
@@ -2118,7 +2122,7 @@ _GLIBCXX_END_NAMESPACE_ALGO
_GLIBCXX20_CONSTEXPR
_ForwardIterator
__remove_if(_ForwardIterator __first, _ForwardIterator __last,
- _Predicate __pred)
+ _GLIBCXX_CP_FWDREF(_Predicate) __pred)
{
__first = std::__find_if(__first, __last, __pred);
if (__first == __last)
@@ -2140,7 +2144,7 @@ _GLIBCXX_END_NAMESPACE_ALGO
_ForwardIterator1
__search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2,
- _BinaryPredicate __predicate)
+ _GLIBCXX_CP_FWDREF(_BinaryPredicate) __predicate)
{
// Test for empty ranges
if (__first1 == __last1 || __first2 == __last2)
@@ -2290,7 +2294,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
__glibcxx_requires_valid_range(__first1, __last1);
__glibcxx_requires_valid_range(__first2, __last2);
- return std::__search(__first1, __last1, __first2, __last2, __predicate);
+ return std::__search(__first1, __last1, __first2, __last2,
+ _GLIBCXX_MOVE(__predicate));
}
_GLIBCXX_END_NAMESPACE_ALGO
diff --git a/libstdc++-v3/include/bits/stl_heap.h b/libstdc++-v3/include/bits/stl_heap.h
index 8c5c5df5266..53de394a555 100644
--- a/libstdc++-v3/include/bits/stl_heap.h
+++ b/libstdc++-v3/include/bits/stl_heap.h
@@ -74,7 +74,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX20_CONSTEXPR
_Distance
__is_heap_until(_RandomAccessIterator __first, _Distance __n,
- _Compare& __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
#if __cplusplus >= 201103L
using _IterTraits = iterator_traits<_RandomAccessIterator>;
@@ -109,10 +109,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Distance>
_GLIBCXX20_CONSTEXPR
inline bool
- __is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n)
+ __is_heap(_RandomAccessIterator __first,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp,
+ _Distance __n)
{
typename iterator_traits<_RandomAccessIterator>::difference_type __d(__n);
- return std::__is_heap_until(__first, __d, __comp) == __n;
+ return std::__is_heap_until
+ (__first, __d, _GLIBCXX_FORWARD(_Compare, __comp)) == __n;
}
template<typename _RandomAccessIterator>
@@ -125,9 +128,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX20_CONSTEXPR
inline bool
__is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _Compare __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
- return std::__is_heap(__first, _GLIBCXX_MOVE(__comp),
+ return std::__is_heap(__first, _GLIBCXX_FORWARD(_Compare, __comp),
std::distance(__first, __last));
}
@@ -139,8 +142,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX20_CONSTEXPR
void
__push_heap(_RandomAccessIterator __first,
- _Distance __holeIndex, _Distance __topIndex, _Tp __value,
- _Compare& __comp)
+ _Distance __holeIndex, _Distance __topIndex,
+ _GLIBCXX_CP_FWDREF(_Tp) __value,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
_Distance __parent = (__holeIndex - 1) / 2;
while (__holeIndex > __topIndex && __comp(*(__first + __parent), __value))
@@ -149,7 +153,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__holeIndex = __parent;
__parent = (__holeIndex - 1) / 2;
}
- *(__first + __holeIndex) = _GLIBCXX_MOVE(__value);
+ *(__first + __holeIndex) = _GLIBCXX_FORWARD(_Tp, __value);
}
/**
@@ -218,7 +222,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_ValueType __value = _GLIBCXX_MOVE(*(__last - _DistanceType(1)));
std::__push_heap(__first, _DistanceType((__last - __first) - 1),
- _DistanceType(0), _GLIBCXX_MOVE(__value), __comp);
+ _DistanceType(0), _GLIBCXX_MOVE(__value),
+ _GLIBCXX_MOVE(__comp));
}
template<typename _RandomAccessIterator, typename _Distance,
@@ -226,7 +231,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX20_CONSTEXPR
void
__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
- _Distance __len, _Tp __value, _Compare __comp)
+ _Distance __len,
+ _GLIBCXX_CP_FWDREF(_Tp) __value,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
const _Distance __topIndex = __holeIndex;
_Distance __secondChild = __holeIndex;
@@ -247,14 +254,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__holeIndex = __secondChild - 1;
}
std::__push_heap(__first, __holeIndex, __topIndex,
- _GLIBCXX_MOVE(__value), __comp);
+ _GLIBCXX_FORWARD(_Tp, __value),
+ _GLIBCXX_MOVE(__comp));
}
template<typename _RandomAccessIterator, typename _Compare>
_GLIBCXX20_CONSTEXPR
inline void
__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _RandomAccessIterator __result, _Compare& __comp)
+ _RandomAccessIterator __result,
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
@@ -265,7 +274,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*__result = _GLIBCXX_MOVE(*__first);
std::__adjust_heap(__first, _DistanceType(0),
_DistanceType(__last - __first),
- _GLIBCXX_MOVE(__value), __comp);
+ _GLIBCXX_MOVE(__value), _GLIBCXX_FORWARD(_Compare, __comp));
}
/**
@@ -330,7 +339,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__last - __first > 1)
{
--__last;
- std::__pop_heap(__first, __last, __last, __comp);
+ std::__pop_heap(__first, __last, __last, _GLIBCXX_MOVE(__comp));
}
}
@@ -338,7 +347,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX20_CONSTEXPR
void
__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _Compare& __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
_ValueType;
@@ -408,14 +417,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__glibcxx_requires_valid_range(__first, __last);
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
- std::__make_heap(__first, __last, __comp);
+ std::__make_heap(__first, __last, _GLIBCXX_MOVE(__comp));
}
template<typename _RandomAccessIterator, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _Compare& __comp)
+ _GLIBCXX_CP_FWDREF(_Compare) __comp)
{
while (__last - __first > 1)
{
@@ -473,7 +482,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
__glibcxx_requires_heap_pred(__first, __last, __comp);
- std::__sort_heap(__first, __last, __comp);
+ std::__sort_heap(__first, __last, _GLIBCXX_MOVE(__comp));
}
#if __cplusplus >= 201103L
@@ -530,7 +539,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __first
+ std::__is_heap_until(__first, std::distance(__first, __last),
- __comp);
+ std::move(__comp));
}
/**
@@ -567,9 +576,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__glibcxx_requires_irreflexive_pred(__first, __last, __comp);
const auto __dist = std::distance(__first, __last);
- return std::__is_heap_until(__first, __dist, __comp) == __dist;
+ return std::__is_heap_until(__first, __dist,
+ std::move(__comp)) == __dist;
}
-#endif
+#endif // C++11
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/src/c++17/memory_resource.cc b/libstdc++-v3/src/c++17/memory_resource.cc
index d8b36554e9f..15e59d36e90 100644
--- a/libstdc++-v3/src/c++17/memory_resource.cc
+++ b/libstdc++-v3/src/c++17/memory_resource.cc
@@ -26,6 +26,7 @@
#include <algorithm> // lower_bound, rotate
#include <atomic>
#include <bit> // has_single_bit, bit_ceil, bit_width
+#include <functional> // less_equal
#include <new>
#include <bits/move.h> // std::__exchange
#if ATOMIC_POINTER_LOCK_FREE != 2
diff --git a/libstdc++-v3/testsuite/25_algorithms/inplace_merge/1.cc b/libstdc++-v3/testsuite/25_algorithms/inplace_merge/1.cc
index 2908ec9a3d0..a83a6765bd4 100644
--- a/libstdc++-v3/testsuite/25_algorithms/inplace_merge/1.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/inplace_merge/1.cc
@@ -21,6 +21,7 @@
// { dg-require-effective-target hosted }
#include <algorithm>
+#include <vector>
#include <testsuite_hooks.h>
#include <testsuite_iterators.h>
#include <testsuite_new_operators.h>
@@ -119,6 +120,17 @@ test4()
}
}
+bool bs[] = { false, false, true, false, true, true };
+std::vector<bool> v(6);
+
+void
+test5()
+{
+ v.assign(bs, bs + 6);
+ inplace_merge(v.begin(), v.begin() + 3, v.end());
+ VERIFY( !v[0] && !v[1] && !v[2] && v[3] && v[4] && v[5] );
+}
+
int
main()
{
@@ -129,14 +141,17 @@ main()
__gnu_test::set_new_limit(sizeof(S) * 4);
test3();
test4();
+ test5();
__gnu_test::set_new_limit(sizeof(S));
test3();
test4();
+ test5();
__gnu_test::set_new_limit(0);
test3();
test4();
+ test5();
return 0;
}
diff --git a/libstdc++-v3/testsuite/25_algorithms/stable_sort/1.cc b/libstdc++-v3/testsuite/25_algorithms/stable_sort/1.cc
index 11cf0c70108..595dc186fa0 100644
--- a/libstdc++-v3/testsuite/25_algorithms/stable_sort/1.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/stable_sort/1.cc
@@ -84,6 +84,26 @@ test3()
VERIFY(array[i].j == i % 2);
}
+struct NotConstLess
+{
+ bool
+ operator()(S& s1, S& s2)
+ { return s1.i < s2.i; }
+};
+
+void
+test4()
+{
+#if __cplusplus >= 201103L
+ NotConstLess less;
+ S array[] = { -1, -2, 1, 2, -3 ,-5 ,3 , -4, 5, 4 };
+ test_container<S, random_access_iterator_wrapper> con(array,array + 10);
+ stable_sort(con.begin(), con.end(), less);
+ for(int i = 0; i < 10; ++i)
+ VERIFY(array[i].j == i % 2);
+#endif
+}
+
int
main()
{
@@ -91,13 +111,17 @@ main()
test2();
test3();
+ test4();
__gnu_test::set_new_limit(sizeof(S) * 5);
test3();
+ test4();
__gnu_test::set_new_limit(sizeof(S));
test3();
+ test4();
__gnu_test::set_new_limit(0);
test3();
+ test4();
}
More information about the Libstdc++
mailing list