Skip to content

Commit 5386aa2

Browse files
author
Arthur O'Dwyer
committed
[libc++] [P0879] constexpr heap and partial_sort algorithms
Now the only ones we're still missing from P0879 are `sort` and `nth_element`. Differential Revision: https://reviews.llvm.org/D93512
1 parent bc8d8e6 commit 5386aa2

File tree

13 files changed

+549
-588
lines changed

13 files changed

+549
-588
lines changed

libcxx/include/algorithm

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -367,20 +367,20 @@ template <class RandomAccessIterator, class Compare>
367367
stable_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
368368
369369
template <class RandomAccessIterator>
370-
void
370+
constexpr void // constexpr in C++20
371371
partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last);
372372
373373
template <class RandomAccessIterator, class Compare>
374-
void
374+
constexpr void // constexpr in C++20
375375
partial_sort(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp);
376376
377377
template <class InputIterator, class RandomAccessIterator>
378-
RandomAccessIterator
378+
constexpr RandomAccessIterator // constexpr in C++20
379379
partial_sort_copy(InputIterator first, InputIterator last,
380380
RandomAccessIterator result_first, RandomAccessIterator result_last);
381381
382382
template <class InputIterator, class RandomAccessIterator, class Compare>
383-
RandomAccessIterator
383+
constexpr RandomAccessIterator // constexpr in C++20
384384
partial_sort_copy(InputIterator first, InputIterator last,
385385
RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp);
386386
@@ -491,35 +491,35 @@ template <class InputIterator1, class InputIterator2, class OutputIterator, clas
491491
InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);
492492
493493
template <class RandomAccessIterator>
494-
void
494+
constexpr void // constexpr in C++20
495495
push_heap(RandomAccessIterator first, RandomAccessIterator last);
496496
497497
template <class RandomAccessIterator, class Compare>
498-
void
498+
constexpr void // constexpr in C++20
499499
push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
500500
501501
template <class RandomAccessIterator>
502-
void
502+
constexpr void // constexpr in C++20
503503
pop_heap(RandomAccessIterator first, RandomAccessIterator last);
504504
505505
template <class RandomAccessIterator, class Compare>
506-
void
506+
constexpr void // constexpr in C++20
507507
pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
508508
509509
template <class RandomAccessIterator>
510-
void
510+
constexpr void // constexpr in C++20
511511
make_heap(RandomAccessIterator first, RandomAccessIterator last);
512512
513513
template <class RandomAccessIterator, class Compare>
514-
void
514+
constexpr void // constexpr in C++20
515515
make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
516516
517517
template <class RandomAccessIterator>
518-
void
518+
constexpr void // constexpr in C++20
519519
sort_heap(RandomAccessIterator first, RandomAccessIterator last);
520520
521521
template <class RandomAccessIterator, class Compare>
522-
void
522+
constexpr void // constexpr in C++20
523523
sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
524524
525525
template <class RandomAccessIterator>
@@ -5000,7 +5000,7 @@ is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
50005000
// push_heap
50015001

50025002
template <class _Compare, class _RandomAccessIterator>
5003-
void
5003+
_LIBCPP_CONSTEXPR_AFTER_CXX11 void
50045004
__sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
50055005
typename iterator_traits<_RandomAccessIterator>::difference_type __len)
50065006
{
@@ -5027,7 +5027,7 @@ __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare
50275027
}
50285028

50295029
template <class _RandomAccessIterator, class _Compare>
5030-
inline _LIBCPP_INLINE_VISIBILITY
5030+
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
50315031
void
50325032
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
50335033
{
@@ -5036,7 +5036,7 @@ push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare
50365036
}
50375037

50385038
template <class _RandomAccessIterator>
5039-
inline _LIBCPP_INLINE_VISIBILITY
5039+
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
50405040
void
50415041
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
50425042
{
@@ -5046,7 +5046,7 @@ push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
50465046
// pop_heap
50475047

50485048
template <class _Compare, class _RandomAccessIterator>
5049-
void
5049+
_LIBCPP_CONSTEXPR_AFTER_CXX11 void
50505050
__sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/,
50515051
_Compare __comp,
50525052
typename iterator_traits<_RandomAccessIterator>::difference_type __len,
@@ -5078,7 +5078,7 @@ __sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/,
50785078
value_type __top(_VSTD::move(*__start));
50795079
do
50805080
{
5081-
// we are not in heap-order, swap the parent with it's largest child
5081+
// we are not in heap-order, swap the parent with its largest child
50825082
*__start = _VSTD::move(*__child_i);
50835083
__start = __child_i;
50845084

@@ -5101,7 +5101,7 @@ __sift_down(_RandomAccessIterator __first, _RandomAccessIterator /*__last*/,
51015101
}
51025102

51035103
template <class _Compare, class _RandomAccessIterator>
5104-
inline _LIBCPP_INLINE_VISIBILITY
5104+
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
51055105
void
51065106
__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
51075107
typename iterator_traits<_RandomAccessIterator>::difference_type __len)
@@ -5114,7 +5114,7 @@ __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare
51145114
}
51155115

51165116
template <class _RandomAccessIterator, class _Compare>
5117-
inline _LIBCPP_INLINE_VISIBILITY
5117+
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
51185118
void
51195119
pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
51205120
{
@@ -5123,7 +5123,7 @@ pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare _
51235123
}
51245124

51255125
template <class _RandomAccessIterator>
5126-
inline _LIBCPP_INLINE_VISIBILITY
5126+
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
51275127
void
51285128
pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
51295129
{
@@ -5133,7 +5133,7 @@ pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
51335133
// make_heap
51345134

51355135
template <class _Compare, class _RandomAccessIterator>
5136-
void
5136+
_LIBCPP_CONSTEXPR_AFTER_CXX11 void
51375137
__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
51385138
{
51395139
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
@@ -5149,7 +5149,7 @@ __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compar
51495149
}
51505150

51515151
template <class _RandomAccessIterator, class _Compare>
5152-
inline _LIBCPP_INLINE_VISIBILITY
5152+
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
51535153
void
51545154
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
51555155
{
@@ -5158,7 +5158,7 @@ make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare
51585158
}
51595159

51605160
template <class _RandomAccessIterator>
5161-
inline _LIBCPP_INLINE_VISIBILITY
5161+
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
51625162
void
51635163
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
51645164
{
@@ -5168,7 +5168,7 @@ make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
51685168
// sort_heap
51695169

51705170
template <class _Compare, class _RandomAccessIterator>
5171-
void
5171+
_LIBCPP_CONSTEXPR_AFTER_CXX17 void
51725172
__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
51735173
{
51745174
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
@@ -5177,7 +5177,7 @@ __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compar
51775177
}
51785178

51795179
template <class _RandomAccessIterator, class _Compare>
5180-
inline _LIBCPP_INLINE_VISIBILITY
5180+
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
51815181
void
51825182
sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
51835183
{
@@ -5186,7 +5186,7 @@ sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare
51865186
}
51875187

51885188
template <class _RandomAccessIterator>
5189-
inline _LIBCPP_INLINE_VISIBILITY
5189+
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
51905190
void
51915191
sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
51925192
{
@@ -5196,7 +5196,7 @@ sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
51965196
// partial_sort
51975197

51985198
template <class _Compare, class _RandomAccessIterator>
5199-
void
5199+
_LIBCPP_CONSTEXPR_AFTER_CXX17 void
52005200
__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
52015201
_Compare __comp)
52025202
{
@@ -5214,7 +5214,7 @@ __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _R
52145214
}
52155215

52165216
template <class _RandomAccessIterator, class _Compare>
5217-
inline _LIBCPP_INLINE_VISIBILITY
5217+
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
52185218
void
52195219
partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
52205220
_Compare __comp)
@@ -5224,7 +5224,7 @@ partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Ran
52245224
}
52255225

52265226
template <class _RandomAccessIterator>
5227-
inline _LIBCPP_INLINE_VISIBILITY
5227+
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
52285228
void
52295229
partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
52305230
{
@@ -5235,7 +5235,7 @@ partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Ran
52355235
// partial_sort_copy
52365236

52375237
template <class _Compare, class _InputIterator, class _RandomAccessIterator>
5238-
_RandomAccessIterator
5238+
_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
52395239
__partial_sort_copy(_InputIterator __first, _InputIterator __last,
52405240
_RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
52415241
{
@@ -5258,7 +5258,7 @@ __partial_sort_copy(_InputIterator __first, _InputIterator __last,
52585258
}
52595259

52605260
template <class _InputIterator, class _RandomAccessIterator, class _Compare>
5261-
inline _LIBCPP_INLINE_VISIBILITY
5261+
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
52625262
_RandomAccessIterator
52635263
partial_sort_copy(_InputIterator __first, _InputIterator __last,
52645264
_RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
@@ -5268,7 +5268,7 @@ partial_sort_copy(_InputIterator __first, _InputIterator __last,
52685268
}
52695269

52705270
template <class _InputIterator, class _RandomAccessIterator>
5271-
inline _LIBCPP_INLINE_VISIBILITY
5271+
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
52725272
_RandomAccessIterator
52735273
partial_sort_copy(_InputIterator __first, _InputIterator __last,
52745274
_RandomAccessIterator __result_first, _RandomAccessIterator __result_last)

libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/make.heap/make_heap.pass.cpp

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,43 +10,57 @@
1010

1111
// template<RandomAccessIterator Iter>
1212
// requires ShuffleIterator<Iter> && LessThanComparable<Iter::value_type>
13-
// void
13+
// constexpr void // constexpr in C++20
1414
// make_heap(Iter first, Iter last);
1515

1616
#include <algorithm>
17-
#include <random>
1817
#include <cassert>
1918

2019
#include "test_macros.h"
2120
#include "test_iterators.h"
21+
#include "MoveOnly.h"
2222

23-
std::mt19937 randomness;
24-
25-
void test(int N)
23+
template<class T, class Iter>
24+
TEST_CONSTEXPR_CXX20 bool test()
2625
{
27-
int* ia = new int [N];
28-
for (int i = 0; i < N; ++i)
29-
ia[i] = i;
30-
std::shuffle(ia, ia+N, randomness);
31-
std::make_heap(ia, ia+N);
32-
assert(std::is_heap(ia, ia+N));
33-
34-
typedef random_access_iterator<int *> RI;
35-
std::shuffle(RI(ia), RI(ia+N), randomness);
36-
std::make_heap(RI(ia), RI(ia+N));
37-
assert(std::is_heap(RI(ia), RI(ia+N)));
38-
39-
delete [] ia;
26+
int orig[15] = {3,1,4,1,5, 9,2,6,5,3, 5,8,9,7,9};
27+
T work[15] = {3,1,4,1,5, 9,2,6,5,3, 5,8,9,7,9};
28+
for (int n = 0; n < 15; ++n) {
29+
std::make_heap(Iter(work), Iter(work+n));
30+
assert(std::is_heap(work, work+n));
31+
assert(std::is_permutation(work, work+n, orig));
32+
std::copy(orig, orig+n, work);
33+
}
34+
35+
{
36+
T input[] = {3, 4, 1, 2, 5};
37+
std::make_heap(Iter(input), Iter(input + 5));
38+
assert(std::is_heap(input, input + 5));
39+
std::pop_heap(input, input + 5); assert(input[4] == 5);
40+
std::pop_heap(input, input + 4); assert(input[3] == 4);
41+
std::pop_heap(input, input + 3); assert(input[2] == 3);
42+
std::pop_heap(input, input + 2); assert(input[1] == 2);
43+
std::pop_heap(input, input + 1); assert(input[0] == 1);
44+
}
45+
return true;
4046
}
4147

4248
int main(int, char**)
4349
{
44-
test(0);
45-
test(1);
46-
test(2);
47-
test(3);
48-
test(10);
49-
test(1000);
50-
51-
return 0;
50+
test<int, random_access_iterator<int*> >();
51+
test<int, int*>();
52+
53+
#if TEST_STD_VER >= 11
54+
test<MoveOnly, random_access_iterator<MoveOnly*>>();
55+
test<MoveOnly, MoveOnly*>();
56+
#endif
57+
58+
#if TEST_STD_VER >= 20
59+
static_assert(test<int, random_access_iterator<int*>>());
60+
static_assert(test<int, int*>());
61+
static_assert(test<MoveOnly, random_access_iterator<MoveOnly*>>());
62+
static_assert(test<MoveOnly, MoveOnly*>());
63+
#endif
64+
65+
return 0;
5266
}

0 commit comments

Comments
 (0)