diff --git a/libcxx/include/__algorithm/sort.h b/libcxx/include/__algorithm/sort.h --- a/libcxx/include/__algorithm/sort.h +++ b/libcxx/include/__algorithm/sort.h @@ -453,12 +453,12 @@ // sort smaller range with recursive call and larger with tail recursion elimination if (__i - __first < __last - __i) { - _VSTD::__introsort<_Compare>(__first, __i, __comp, __depth); + _VSTD::__introsort<_Compare>(__first, __i, _Comp_ref(__comp), __depth); __first = ++__i; } else { - _VSTD::__introsort<_Compare>(__i + 1, __last, __comp, __depth); + _VSTD::__introsort<_Compare>(__i + 1, __last, _Comp_ref(__comp), __depth); __last = __i; } } @@ -477,8 +477,9 @@ template void __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename __comp_ref_type<_Compare>::type _Comp_ref; difference_type __depth_limit = 2 * __log2i(__last - __first); - __introsort(__first, __last, __comp, __depth_limit); + _VSTD::__introsort<_Compare>(__first, __last, _Comp_ref(__comp), __depth_limit); } template diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/sort/sort_comp.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/sort/sort_comp.pass.cpp --- a/libcxx/test/std/algorithms/alg.sorting/alg.sort/sort/sort_comp.pass.cpp +++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/sort/sort_comp.pass.cpp @@ -30,6 +30,22 @@ {return *x < *y;} }; +#if TEST_STD_VER >= 11 +template +struct test_compare { + bool Compare(const T& x, const T& y) { return x < y; } +}; + +template +struct unique_ptr_less { + explicit unique_ptr_less(std::unique_ptr> cmp) : cmp_(std::move(cmp)) {} + bool operator()(const T& x, const T& y) { return cmp_->Compare(x, y); } + +private: + std::unique_ptr> cmp_; +}; +#endif + int main(int, char**) { { @@ -52,6 +68,13 @@ assert(*v[1] == 1); assert(*v[2] == 2); } + { + auto cmp = std::make_unique>(); + std::vector v(1000); + for (int i = 0; static_cast(i) < v.size(); ++i) + v[i] = i; + std::sort(v.begin(), v.end(), unique_ptr_less(std::move(cmp))); + } #endif return 0;