Skip to content

Commit 2d2cb77

Browse files
committed
[ADT] Implement llvm::bsearch() with std::partition_point()
Summary: Delete the begin-end form because the standard std::partition_point can be easily used as a replacement. The ranges-style llvm::bsearch will be renamed to llvm::partition_point in the next clean-up patch. The name "bsearch" doesn't meet people's expectation because in C: > If two or more members compare equal, which member is returned is unspecified. Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D63718 llvm-svn: 364719
1 parent 725a8a5 commit 2d2cb77

File tree

4 files changed

+11
-53
lines changed

4 files changed

+11
-53
lines changed

clang-tools-extra/clangd/index/dex/PostingList.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ class ChunkIterator : public Iterator {
5050
return;
5151
advanceToChunk(ID);
5252
// Try to find ID within current chunk.
53-
CurrentID = llvm::bsearch(CurrentID, DecompressedChunk.end(),
54-
[&](const DocID D) { return D >= ID; });
53+
CurrentID = std::partition_point(CurrentID, DecompressedChunk.end(),
54+
[&](const DocID D) { return D < ID; });
5555
normalizeCursor();
5656
}
5757

@@ -103,8 +103,8 @@ class ChunkIterator : public Iterator {
103103
if ((CurrentChunk != Chunks.end() - 1) &&
104104
((CurrentChunk + 1)->Head <= ID)) {
105105
CurrentChunk =
106-
llvm::bsearch(CurrentChunk + 1, Chunks.end(),
107-
[&](const Chunk &C) { return C.Head >= ID; });
106+
std::partition_point(CurrentChunk + 1, Chunks.end(),
107+
[&](const Chunk &C) { return C.Head < ID; });
108108
--CurrentChunk;
109109
DecompressedChunk = CurrentChunk->decompress();
110110
CurrentID = DecompressedChunk.begin();

llvm/include/llvm/ADT/STLExtras.h

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,44 +1322,13 @@ void stable_sort(R &&Range, Compare C) {
13221322
std::stable_sort(adl_begin(Range), adl_end(Range), C);
13231323
}
13241324

1325-
/// Binary search for the first index where a predicate is true.
1326-
/// Returns the first I in [Lo, Hi) where C(I) is true, or Hi if it never is.
1327-
/// Requires that C is always false below some limit, and always true above it.
1328-
///
1329-
/// Example:
1330-
/// size_t DawnModernEra = bsearch(1776, 2050, [](size_t Year){
1331-
/// return Presidents.for(Year).twitterHandle() != None;
1332-
/// });
1333-
///
1334-
/// Note the return value differs from std::binary_search!
1335-
template <typename Predicate>
1336-
size_t bsearch(size_t Lo, size_t Hi, Predicate P) {
1337-
while (Lo != Hi) {
1338-
assert(Hi > Lo);
1339-
size_t Mid = Lo + (Hi - Lo) / 2;
1340-
if (P(Mid))
1341-
Hi = Mid;
1342-
else
1343-
Lo = Mid + 1;
1344-
}
1345-
return Hi;
1346-
}
1347-
1348-
/// Binary search for the first iterator where a predicate is true.
1349-
/// Returns the first I in [Lo, Hi) where C(*I) is true, or Hi if it never is.
1350-
/// Requires that C is always false below some limit, and always true above it.
1351-
template <typename It, typename Predicate,
1352-
typename Val = decltype(*std::declval<It>())>
1353-
It bsearch(It Lo, It Hi, Predicate P) {
1354-
return std::lower_bound(Lo, Hi, 0u,
1355-
[&](const Val &V, unsigned) { return !P(V); });
1356-
}
1357-
13581325
/// Binary search for the first iterator in a range where a predicate is true.
13591326
/// Requires that C is always false below some limit, and always true above it.
1360-
template <typename R, typename Predicate>
1327+
template <typename R, typename Predicate,
1328+
typename Val = decltype(*adl_begin(std::declval<R>()))>
13611329
auto bsearch(R &&Range, Predicate P) -> decltype(adl_begin(Range)) {
1362-
return bsearch(adl_begin(Range), adl_end(Range), P);
1330+
return std::partition_point(adl_begin(Range), adl_end(Range),
1331+
[&](const Val &V) { return !P(V); });
13631332
}
13641333

13651334
/// Wrapper function around std::equal to detect if all elements

llvm/include/llvm/CodeGen/SlotIndexes.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -492,8 +492,9 @@ class raw_ostream;
492492
/// Move iterator to the next IdxMBBPair where the SlotIndex is greater or
493493
/// equal to \p To.
494494
MBBIndexIterator advanceMBBIndex(MBBIndexIterator I, SlotIndex To) const {
495-
return llvm::bsearch(I, idx2MBBMap.end(),
496-
[=](const IdxMBBPair &IM) { return To <= IM.first; });
495+
return std::partition_point(
496+
I, idx2MBBMap.end(),
497+
[=](const IdxMBBPair &IM) { return IM.first < To; });
497498
}
498499

499500
/// Get an iterator pointing to the IdxMBBPair with the biggest SlotIndex

llvm/unittests/ADT/STLExtrasTest.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -470,19 +470,7 @@ TEST(STLExtrasTest, to_address) {
470470
}
471471

472472
TEST(STLExtrasTest, bsearch) {
473-
// Integer version.
474-
EXPECT_EQ(7u, bsearch(5, 10, [](unsigned X) { return X >= 7; }));
475-
EXPECT_EQ(5u, bsearch(5, 10, [](unsigned X) { return X >= 1; }));
476-
EXPECT_EQ(10u, bsearch(5, 10, [](unsigned X) { return X >= 50; }));
477-
478-
// Iterator version.
479473
std::vector<int> V = {1, 3, 5, 7, 9};
480-
EXPECT_EQ(V.begin() + 3,
481-
bsearch(V.begin(), V.end(), [](unsigned X) { return X >= 7; }));
482-
EXPECT_EQ(V.begin(),
483-
bsearch(V.begin(), V.end(), [](unsigned X) { return X >= 1; }));
484-
EXPECT_EQ(V.end(),
485-
bsearch(V.begin(), V.end(), [](unsigned X) { return X >= 50; }));
486474

487475
// Range version.
488476
EXPECT_EQ(V.begin() + 3, bsearch(V, [](unsigned X) { return X >= 7; }));

0 commit comments

Comments
 (0)