Coverage Report

Created: 2026-09-26 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/AK/BinarySearch.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#pragma once
8
9
#include <AK/Optional.h>
10
#include <AK/StdLibExtras.h>
11
#include <AK/Types.h>
12
13
namespace AK {
14
15
struct DefaultComparator {
16
    template<typename T, typename S>
17
    [[nodiscard]] constexpr int operator()(T& lhs, S& rhs)
18
1.41G
    {
19
1.41G
        if (lhs > rhs)
20
36.2M
            return 1;
21
22
1.37G
        if (lhs < rhs)
23
735M
            return -1;
24
25
643M
        return 0;
26
1.37G
    }
int AK::DefaultComparator::operator()<unsigned long, unsigned long const>(unsigned long&, unsigned long const&)
Line
Count
Source
18
1.41G
    {
19
1.41G
        if (lhs > rhs)
20
36.2M
            return 1;
21
22
1.37G
        if (lhs < rhs)
23
735M
            return -1;
24
25
643M
        return 0;
26
1.37G
    }
int AK::DefaultComparator::operator()<unsigned long const, unsigned long>(unsigned long const&, unsigned long&)
Line
Count
Source
18
15.3k
    {
19
15.3k
        if (lhs > rhs)
20
6.69k
            return 1;
21
22
8.65k
        if (lhs < rhs)
23
8.65k
            return -1;
24
25
0
        return 0;
26
8.65k
    }
Unexecuted instantiation: int AK::DefaultComparator::operator()<unsigned long, unsigned long>(unsigned long&, unsigned long&)
Unexecuted instantiation: int AK::DefaultComparator::operator()<unsigned short, int const>(unsigned short&, int const&)
27
};
28
29
template<typename Container, typename Needle, typename Comparator = DefaultComparator>
30
constexpr auto binary_search(
31
    Container&& haystack,
32
    Needle&& needle,
33
    size_t* nearby_index = nullptr,
34
    Comparator comparator = Comparator {}) -> decltype(&haystack[0])
35
717M
{
36
717M
    if (haystack.size() == 0) {
37
        // FIXME: Refactor the function's API to make it always return a valid index.
38
464
        if (nearby_index)
39
464
            *nearby_index = 0;
40
464
        return nullptr;
41
464
    }
42
43
717M
    size_t low = 0;
44
717M
    size_t high = haystack.size() - 1;
45
1.46G
    while (low != high) {
46
743M
        size_t middle = low + (high - low) / 2;
47
743M
        int comparison = comparator(needle, haystack[middle]);
48
743M
        if (comparison <= 0)
49
689M
            high = middle;
50
54.3M
        else
51
54.3M
            low = middle + 1;
52
743M
    }
53
54
717M
    if (nearby_index)
55
696M
        *nearby_index = high;
56
717M
    if (comparator(needle, haystack[high]) == 0)
57
611M
        return &haystack[high];
58
106M
    return nullptr;
59
717M
}
Unexecuted instantiation: Tables.cpp:decltype (&({parm#1}[0])) AK::binary_search<AK::Span<OpenType::Kern::Format0Pair const> const&, decltype(nullptr), OpenType::Kern::read_glyph_kerning_format0(OpenType::Kern::Format0Table const&, unsigned short, unsigned short)::$_0>(AK::Span<OpenType::Kern::Format0Pair const> const&, decltype(nullptr)&&, unsigned long*, OpenType::Kern::read_glyph_kerning_format0(OpenType::Kern::Format0Table const&, unsigned short, unsigned short)::$_0)
decltype (&({parm#1}[0])) AK::binary_search<AK::Span<unsigned long const>, unsigned long&, AK::DefaultComparator>(AK::Span<unsigned long const>&&, unsigned long&, unsigned long*, AK::DefaultComparator)
Line
Count
Source
35
696M
{
36
696M
    if (haystack.size() == 0) {
37
        // FIXME: Refactor the function's API to make it always return a valid index.
38
464
        if (nearby_index)
39
464
            *nearby_index = 0;
40
464
        return nullptr;
41
464
    }
42
43
696M
    size_t low = 0;
44
696M
    size_t high = haystack.size() - 1;
45
1.41G
    while (low != high) {
46
718M
        size_t middle = low + (high - low) / 2;
47
718M
        int comparison = comparator(needle, haystack[middle]);
48
718M
        if (comparison <= 0)
49
682M
            high = middle;
50
36.2M
        else
51
36.2M
            low = middle + 1;
52
718M
    }
53
54
696M
    if (nearby_index)
55
696M
        *nearby_index = high;
56
696M
    if (comparator(needle, haystack[high]) == 0)
57
605M
        return &haystack[high];
58
91.2M
    return nullptr;
59
696M
}
Decoder.cpp:decltype (&({parm#1}[0])) AK::binary_search<AK::Array<TextCodec::Gb18030RangeEntry, 207ul> const&, unsigned int&, TextCodec::index_gb18030_ranges_code_point(unsigned int)::$_0>(AK::Array<TextCodec::Gb18030RangeEntry, 207ul> const&, unsigned int&, unsigned long*, TextCodec::index_gb18030_ranges_code_point(unsigned int)::$_0)
Line
Count
Source
35
46.4k
{
36
46.4k
    if (haystack.size() == 0) {
37
        // FIXME: Refactor the function's API to make it always return a valid index.
38
0
        if (nearby_index)
39
0
            *nearby_index = 0;
40
0
        return nullptr;
41
0
    }
42
43
46.4k
    size_t low = 0;
44
46.4k
    size_t high = haystack.size() - 1;
45
379k
    while (low != high) {
46
332k
        size_t middle = low + (high - low) / 2;
47
332k
        int comparison = comparator(needle, haystack[middle]);
48
332k
        if (comparison <= 0)
49
32.6k
            high = middle;
50
300k
        else
51
300k
            low = middle + 1;
52
332k
    }
53
54
46.4k
    if (nearby_index)
55
46.4k
        *nearby_index = high;
56
46.4k
    if (comparator(needle, haystack[high]) == 0)
57
524
        return &haystack[high];
58
45.8k
    return nullptr;
59
46.4k
}
Unexecuted instantiation: Encoder.cpp:decltype (&({parm#1}[0])) AK::binary_search<AK::Array<TextCodec::Gb18030RangeEntry, 207ul> const&, unsigned int&, TextCodec::index_gb18030_ranges_pointer(unsigned int)::$_0>(AK::Array<TextCodec::Gb18030RangeEntry, 207ul> const&, unsigned int&, unsigned long*, TextCodec::index_gb18030_ranges_pointer(unsigned int)::$_0)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Unicode::BlockNameData, 353ul> const&, unsigned int&, Unicode::BlockNameComparator>(AK::Array<Unicode::BlockNameData, 353ul> const&, unsigned int&, unsigned long*, Unicode::BlockNameComparator)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Unicode::CodePointName, 39444ul> const&, unsigned int&, Unicode::CodePointNameComparator>(AK::Array<Unicode::CodePointName, 39444ul> const&, unsigned int&, unsigned long*, Unicode::CodePointNameComparator)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Unicode::CodePointAbbreviation, 349ul> const&, unsigned int&, Unicode::CodePointComparator<Unicode::CodePointAbbreviation> >(AK::Array<Unicode::CodePointAbbreviation, 349ul> const&, unsigned int&, unsigned long*, Unicode::CodePointComparator<Unicode::CodePointAbbreviation>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Unicode::CodePointDecompositionRaw, 5982ul> const&, unsigned int&, Unicode::CodePointComparator<Unicode::CodePointDecompositionRaw> >(AK::Array<Unicode::CodePointDecompositionRaw, 5982ul> const&, unsigned int&, unsigned long*, Unicode::CodePointComparator<Unicode::CodePointDecompositionRaw>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Unicode::CodePointCompositionRaw, 961ul> const&, unsigned int&, Unicode::CodePointComparator<Unicode::CodePointCompositionRaw> >(AK::Array<Unicode::CodePointCompositionRaw, 961ul> const&, unsigned int&, unsigned long*, Unicode::CodePointComparator<Unicode::CodePointCompositionRaw>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Unicode::BidiClassData, 41319ul> const&, unsigned int&, Unicode::CodePointBidiClassComparator>(AK::Array<Unicode::BidiClassData, 41319ul> const&, unsigned int&, unsigned long*, Unicode::CodePointBidiClassComparator)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Unicode::HashValuePair<Unicode::Locale>, 3ul> const&, unsigned int&, Unicode::HashValueComparator<Unicode::Locale> >(AK::Array<Unicode::HashValuePair<Unicode::Locale>, 3ul> const&, unsigned int&, unsigned long*, Unicode::HashValueComparator<Unicode::Locale>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Unicode::HashValuePair<Unicode::GeneralCategory>, 80ul> const&, unsigned int&, Unicode::HashValueComparator<Unicode::GeneralCategory> >(AK::Array<Unicode::HashValuePair<Unicode::GeneralCategory>, 80ul> const&, unsigned int&, unsigned long*, Unicode::HashValueComparator<Unicode::GeneralCategory>)
decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Unicode::HashValuePair<Unicode::Property>, 146ul> const&, unsigned int&, Unicode::HashValueComparator<Unicode::Property> >(AK::Array<Unicode::HashValuePair<Unicode::Property>, 146ul> const&, unsigned int&, unsigned long*, Unicode::HashValueComparator<Unicode::Property>)
Line
Count
Source
35
4
{
36
4
    if (haystack.size() == 0) {
37
        // FIXME: Refactor the function's API to make it always return a valid index.
38
0
        if (nearby_index)
39
0
            *nearby_index = 0;
40
0
        return nullptr;
41
0
    }
42
43
4
    size_t low = 0;
44
4
    size_t high = haystack.size() - 1;
45
32
    while (low != high) {
46
28
        size_t middle = low + (high - low) / 2;
47
28
        int comparison = comparator(needle, haystack[middle]);
48
28
        if (comparison <= 0)
49
20
            high = middle;
50
8
        else
51
8
            low = middle + 1;
52
28
    }
53
54
4
    if (nearby_index)
55
0
        *nearby_index = high;
56
4
    if (comparator(needle, haystack[high]) == 0)
57
4
        return &haystack[high];
58
0
    return nullptr;
59
4
}
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Unicode::HashValuePair<Unicode::Script>, 349ul> const&, unsigned int&, Unicode::HashValueComparator<Unicode::Script> >(AK::Array<Unicode::HashValuePair<Unicode::Script>, 349ul> const&, unsigned int&, unsigned long*, Unicode::HashValueComparator<Unicode::Script>)
SourceCode.cpp:decltype (&({parm#1}[0])) AK::binary_search<AK::Span<JS::Position>&, JS::Position const&, JS::SourceCode::range_from_offsets(unsigned int, unsigned int) const::$_0>(AK::Span<JS::Position>&, JS::Position const&, unsigned long*, JS::SourceCode::range_from_offsets(unsigned int, unsigned int) const::$_0)
Line
Count
Source
35
1.71k
{
36
1.71k
    if (haystack.size() == 0) {
37
        // FIXME: Refactor the function's API to make it always return a valid index.
38
0
        if (nearby_index)
39
0
            *nearby_index = 0;
40
0
        return nullptr;
41
0
    }
42
43
1.71k
    size_t low = 0;
44
1.71k
    size_t high = haystack.size() - 1;
45
13.6k
    while (low != high) {
46
11.9k
        size_t middle = low + (high - low) / 2;
47
11.9k
        int comparison = comparator(needle, haystack[middle]);
48
11.9k
        if (comparison <= 0)
49
5.21k
            high = middle;
50
6.69k
        else
51
6.69k
            low = middle + 1;
52
11.9k
    }
53
54
1.71k
    if (nearby_index)
55
1.71k
        *nearby_index = high;
56
1.71k
    if (comparator(needle, haystack[high]) == 0)
57
0
        return &haystack[high];
58
1.71k
    return nullptr;
59
1.71k
}
decltype (&({parm#1}[0])) AK::binary_search<AK::DisjointSpans<unsigned long, AK::Vector<AK::Span<unsigned long>, 4ul> >&, unsigned int&, regex::OpCode_Compare::execute(regex::MatchInput const&, regex::MatchState&) const::{lambda(auto:1, regex::CharRange)#1}>(AK::DisjointSpans<unsigned long, AK::Vector<AK::Span<unsigned long>, 4ul> >&, unsigned int&, unsigned long*, regex::OpCode_Compare::execute(regex::MatchInput const&, regex::MatchState&) const::{lambda(auto:1, regex::CharRange)#1})
Line
Count
Source
35
21.0M
{
36
21.0M
    if (haystack.size() == 0) {
37
        // FIXME: Refactor the function's API to make it always return a valid index.
38
0
        if (nearby_index)
39
0
            *nearby_index = 0;
40
0
        return nullptr;
41
0
    }
42
43
21.0M
    size_t low = 0;
44
21.0M
    size_t high = haystack.size() - 1;
45
42.4M
    while (low != high) {
46
21.3M
        size_t middle = low + (high - low) / 2;
47
21.3M
        int comparison = comparator(needle, haystack[middle]);
48
21.3M
        if (comparison <= 0)
49
6.76M
            high = middle;
50
14.5M
        else
51
14.5M
            low = middle + 1;
52
21.3M
    }
53
54
21.0M
    if (nearby_index)
55
0
        *nearby_index = high;
56
21.0M
    if (comparator(needle, haystack[high]) == 0)
57
6.35M
        return &haystack[high];
58
14.7M
    return nullptr;
59
21.0M
}
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::HourCycleRegion>, 271ul> const&, unsigned int&, Locale::HashValueComparator<Locale::HourCycleRegion> >(AK::Array<Locale::HashValuePair<Locale::HourCycleRegion>, 271ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::HourCycleRegion>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::MinimumDaysRegion>, 49ul> const&, unsigned int&, Locale::HashValueComparator<Locale::MinimumDaysRegion> >(AK::Array<Locale::HashValuePair<Locale::MinimumDaysRegion>, 49ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::MinimumDaysRegion>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::FirstDayRegion>, 150ul> const&, unsigned int&, Locale::HashValueComparator<Locale::FirstDayRegion> >(AK::Array<Locale::HashValuePair<Locale::FirstDayRegion>, 150ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::FirstDayRegion>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::WeekendStartRegion>, 19ul> const&, unsigned int&, Locale::HashValueComparator<Locale::WeekendStartRegion> >(AK::Array<Locale::HashValuePair<Locale::WeekendStartRegion>, 19ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::WeekendStartRegion>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::WeekendEndRegion>, 17ul> const&, unsigned int&, Locale::HashValueComparator<Locale::WeekendEndRegion> >(AK::Array<Locale::HashValuePair<Locale::WeekendEndRegion>, 17ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::WeekendEndRegion>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::Locale>, 517ul> const&, unsigned int&, Locale::HashValueComparator<Locale::Locale> >(AK::Array<Locale::HashValuePair<Locale::Locale>, 517ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::Locale>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::Language>, 668ul> const&, unsigned int&, Locale::HashValueComparator<Locale::Language> >(AK::Array<Locale::HashValuePair<Locale::Language>, 668ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::Language>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<unsigned int>, 433ul> const&, unsigned int&, Locale::HashValueComparator<unsigned int> >(AK::Array<Locale::HashValuePair<unsigned int>, 433ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<unsigned int>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::Territory>, 214ul> const&, unsigned int&, Locale::HashValueComparator<Locale::Territory> >(AK::Array<Locale::HashValuePair<Locale::Territory>, 214ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::Territory>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<unsigned int>, 640ul> const&, unsigned int&, Locale::HashValueComparator<unsigned int> >(AK::Array<Locale::HashValuePair<unsigned int>, 640ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<unsigned int>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::ScriptTag>, 6ul> const&, unsigned int&, Locale::HashValueComparator<Locale::ScriptTag> >(AK::Array<Locale::HashValuePair<Locale::ScriptTag>, 6ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::ScriptTag>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<unsigned int>, 1ul> const&, unsigned int&, Locale::HashValueComparator<unsigned int> >(AK::Array<Locale::HashValuePair<unsigned int>, 1ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<unsigned int>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::Currency>, 306ul> const&, unsigned int&, Locale::HashValueComparator<Locale::Currency> >(AK::Array<Locale::HashValuePair<Locale::Currency>, 306ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::Currency>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::DateField>, 15ul> const&, unsigned int&, Locale::HashValueComparator<Locale::DateField> >(AK::Array<Locale::HashValuePair<Locale::DateField>, 15ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::DateField>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::Key>, 6ul> const&, unsigned int&, Locale::HashValueComparator<Locale::Key> >(AK::Array<Locale::HashValuePair<Locale::Key>, 6ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::Key>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::KeywordHours>, 4ul> const&, unsigned int&, Locale::HashValueComparator<Locale::KeywordHours> >(AK::Array<Locale::HashValuePair<Locale::KeywordHours>, 4ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::KeywordHours>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::KeywordColCaseFirst>, 4ul> const&, unsigned int&, Locale::HashValueComparator<Locale::KeywordColCaseFirst> >(AK::Array<Locale::HashValuePair<Locale::KeywordColCaseFirst>, 4ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::KeywordColCaseFirst>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::KeywordColNumeric>, 4ul> const&, unsigned int&, Locale::HashValueComparator<Locale::KeywordColNumeric> >(AK::Array<Locale::HashValuePair<Locale::KeywordColNumeric>, 4ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::KeywordColNumeric>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::KeywordCalendar>, 21ul> const&, unsigned int&, Locale::HashValueComparator<Locale::KeywordCalendar> >(AK::Array<Locale::HashValuePair<Locale::KeywordCalendar>, 21ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::KeywordCalendar>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::KeywordCollation>, 22ul> const&, unsigned int&, Locale::HashValueComparator<Locale::KeywordCollation> >(AK::Array<Locale::HashValuePair<Locale::KeywordCollation>, 22ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::KeywordCollation>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::KeywordNumbers>, 88ul> const&, unsigned int&, Locale::HashValueComparator<Locale::KeywordNumbers> >(AK::Array<Locale::HashValuePair<Locale::KeywordNumbers>, 88ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::KeywordNumbers>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<unsigned int>, 2ul> const&, unsigned int&, Locale::HashValueComparator<unsigned int> >(AK::Array<Locale::HashValuePair<unsigned int>, 2ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<unsigned int>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<unsigned int>, 144ul> const&, unsigned int&, Locale::HashValueComparator<unsigned int> >(AK::Array<Locale::HashValuePair<unsigned int>, 144ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<unsigned int>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::ListPatternType>, 3ul> const&, unsigned int&, Locale::HashValueComparator<Locale::ListPatternType> >(AK::Array<Locale::HashValuePair<Locale::ListPatternType>, 3ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::ListPatternType>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Locale::HashValuePair<Locale::CharacterOrder>, 2ul> const&, unsigned int&, Locale::HashValueComparator<Locale::CharacterOrder> >(AK::Array<Locale::HashValuePair<Locale::CharacterOrder>, 2ul> const&, unsigned int&, unsigned long*, Locale::HashValueComparator<Locale::CharacterOrder>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Span<unsigned long>&, unsigned long&, AK::DefaultComparator>(AK::Span<unsigned long>&, unsigned long&, unsigned long*, AK::DefaultComparator)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Span<unsigned long>&, unsigned long&, AK::UpperBoundComparator>(AK::Span<unsigned long>&, unsigned long&, unsigned long*, AK::UpperBoundComparator)
GenericTypes.cpp:decltype (&({parm#1}[0])) AK::binary_search<AK::Vector<Audio::SeekPoint, 0ul> const&, unsigned long&, Audio::SeekTable::seek_point_before(unsigned long) const::$_0>(AK::Vector<Audio::SeekPoint, 0ul> const&, unsigned long&, unsigned long*, Audio::SeekTable::seek_point_before(unsigned long) const::$_0)
Line
Count
Source
35
280k
{
36
280k
    if (haystack.size() == 0) {
37
        // FIXME: Refactor the function's API to make it always return a valid index.
38
0
        if (nearby_index)
39
0
            *nearby_index = 0;
40
0
        return nullptr;
41
0
    }
42
43
280k
    size_t low = 0;
44
280k
    size_t high = haystack.size() - 1;
45
2.88M
    while (low != high) {
46
2.60M
        size_t middle = low + (high - low) / 2;
47
2.60M
        int comparison = comparator(needle, haystack[middle]);
48
2.60M
        if (comparison <= 0)
49
359k
            high = middle;
50
2.24M
        else
51
2.24M
            low = middle + 1;
52
2.60M
    }
53
54
280k
    if (nearby_index)
55
280k
        *nearby_index = high;
56
280k
    if (comparator(needle, haystack[high]) == 0)
57
36.6k
        return &haystack[high];
58
243k
    return nullptr;
59
280k
}
GenericTypes.cpp:decltype (&({parm#1}[0])) AK::binary_search<AK::Vector<Audio::SeekPoint, 0ul> const&, unsigned long&, Audio::SeekTable::seek_point_sample_distance_around(unsigned long) const::$_0>(AK::Vector<Audio::SeekPoint, 0ul> const&, unsigned long&, unsigned long*, Audio::SeekTable::seek_point_sample_distance_around(unsigned long) const::$_0)
Line
Count
Source
35
107k
{
36
107k
    if (haystack.size() == 0) {
37
        // FIXME: Refactor the function's API to make it always return a valid index.
38
0
        if (nearby_index)
39
0
            *nearby_index = 0;
40
0
        return nullptr;
41
0
    }
42
43
107k
    size_t low = 0;
44
107k
    size_t high = haystack.size() - 1;
45
1.02M
    while (low != high) {
46
912k
        size_t middle = low + (high - low) / 2;
47
912k
        int comparison = comparator(needle, haystack[middle]);
48
912k
        if (comparison <= 0)
49
21.8k
            high = middle;
50
891k
        else
51
891k
            low = middle + 1;
52
912k
    }
53
54
107k
    if (nearby_index)
55
107k
        *nearby_index = high;
56
107k
    if (comparator(needle, haystack[high]) == 0)
57
18.3k
        return &haystack[high];
58
89.3k
    return nullptr;
59
107k
}
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Span<Shell::Shell::RunnablePath>, AK::StringView&, Shell::Shell::RunnablePathComparator>(AK::Span<Shell::Shell::RunnablePath>&&, AK::StringView&, unsigned long*, Shell::Shell::RunnablePathComparator)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Span<Shell::Shell::RunnablePath>, AK::ByteString&, Shell::Shell::RunnablePathComparator>(AK::Span<Shell::Shell::RunnablePath>&&, AK::ByteString&, unsigned long*, Shell::Shell::RunnablePathComparator)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Span<Shell::Shell::RunnablePath>, Shell::Shell::RunnablePath const&, Shell::Shell::RunnablePathComparator>(AK::Span<Shell::Shell::RunnablePath>&&, Shell::Shell::RunnablePath const&, unsigned long*, Shell::Shell::RunnablePathComparator)
Unexecuted instantiation: Shell.cpp:decltype (&({parm#1}[0])) AK::binary_search<AK::Span<Shell::Shell::RunnablePath>, AK::StringView&, Shell::Shell::complete_program_name(AK::StringView, unsigned long, Shell::Shell::EscapeMode)::$_0>(AK::Span<Shell::Shell::RunnablePath>&&, AK::StringView&, unsigned long*, Shell::Shell::complete_program_name(AK::StringView, unsigned long, Shell::Shell::EscapeMode)::$_0)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Span<Shell::Shell::RunnablePath>, AK::String&, Shell::Shell::RunnablePathComparator>(AK::Span<Shell::Shell::RunnablePath>&&, AK::String&, unsigned long*, Shell::Shell::RunnablePathComparator)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Vector<unsigned long, 0ul>&, unsigned long&, AK::DefaultComparator>(AK::Vector<unsigned long, 0ul>&, unsigned long&, unsigned long*, AK::DefaultComparator)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Vector<unsigned long, 0ul>&, unsigned long, AK::DefaultComparator>(AK::Vector<unsigned long, 0ul>&, unsigned long&&, unsigned long*, AK::DefaultComparator)
Unexecuted instantiation: XtermSuggestionDisplay.cpp:decltype (&({parm#1}[0])) AK::binary_search<AK::Span<Line::XtermSuggestionDisplay::PageRange>, Line::XtermSuggestionDisplay::PageRange, Line::XtermSuggestionDisplay::fit_to_page_boundary(unsigned long)::$_0>(AK::Span<Line::XtermSuggestionDisplay::PageRange>&&, Line::XtermSuggestionDisplay::PageRange&&, unsigned long*, Line::XtermSuggestionDisplay::fit_to_page_boundary(unsigned long)::$_0)
Unexecuted instantiation: Image.cpp:decltype (&({parm#1}[0])) AK::binary_search<AK::Vector<ELF::Image::SortedSymbol, 0ul>&, unsigned long&, ELF::Image::find_sorted_symbol(unsigned long) const::$_0>(AK::Vector<ELF::Image::SortedSymbol, 0ul>&, unsigned long&, unsigned long*, ELF::Image::find_sorted_symbol(unsigned long) const::$_0)
Unexecuted instantiation: EasingStyleValue.cpp:decltype (&({parm#1}[0])) AK::binary_search<AK::Vector<Web::CSS::EasingStyleValue::CubicBezier::CachedSample, 64ul>&, double&, Web::CSS::EasingStyleValue::Function::evaluate_at(double, bool) const::$_0::operator()(Web::CSS::EasingStyleValue::CubicBezier const&) const::{lambda(auto:1, auto:2&)#1}>(AK::Vector<Web::CSS::EasingStyleValue::CubicBezier::CachedSample, 64ul>&, double&, unsigned long*, Web::CSS::EasingStyleValue::Function::evaluate_at(double, bool) const::$_0::operator()(Web::CSS::EasingStyleValue::CubicBezier const&) const::{lambda(auto:1, auto:2&)#1})
Unexecuted instantiation: EasingStyleValue.cpp:decltype (&({parm#1}[0])) AK::binary_search<AK::Vector<Web::CSS::EasingStyleValue::CubicBezier::CachedSample, 64ul>&, double&, Web::CSS::EasingStyleValue::Function::evaluate_at(double, bool) const::$_0::operator()(Web::CSS::EasingStyleValue::CubicBezier const&) const::{lambda(auto:1, auto:2&)#2}>(AK::Vector<Web::CSS::EasingStyleValue::CubicBezier::CachedSample, 64ul>&, double&, unsigned long*, Web::CSS::EasingStyleValue::Function::evaluate_at(double, bool) const::$_0::operator()(Web::CSS::EasingStyleValue::CubicBezier const&) const::{lambda(auto:1, auto:2&)#2})
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Span<int const>, unsigned short&, AK::DefaultComparator>(AK::Span<int const>&&, unsigned short&, unsigned long*, AK::DefaultComparator)
60
61
// Unlike their std equivalents, these two function require the entire Container to be sorted!
62
// std::[lower,upper]_bound only require the array to be sorted after and before, respectively, the needle.
63
64
template<typename Container, typename Needle, typename Comparator = DefaultComparator>
65
constexpr auto lower_bound(
66
    Container&& haystack,
67
    Needle&& needle,
68
    Comparator comparator = {}) -> Optional<size_t>
69
{
70
    size_t index {};
71
    binary_search(haystack, needle, &index, comparator);
72
    if (index == haystack.size() - 1 && comparator(needle, haystack[index]) > 0)
73
        return OptionalNone {};
74
    return index;
75
}
76
77
template<typename Container, typename Needle, typename Comparator = DefaultComparator>
78
constexpr auto strict_lower_bound(
79
    Container&& haystack,
80
    Needle&& needle,
81
    Comparator comparator = {}) -> Optional<size_t>
82
1.71k
{
83
    // lower_bound give you the "first element x such that i ≤ x".
84
    // This gives you the last element x such that x < i.
85
1.71k
    size_t index {};
86
1.71k
    binary_search(haystack, needle, &index, comparator);
87
1.71k
    if (index > 0 && comparator(needle, haystack[index]) <= 0)
88
1.71k
        index--;
89
90
1.71k
    if (index == 0 && comparator(needle, haystack[index]) <= 0)
91
0
        return OptionalNone {};
92
1.71k
    return index;
93
1.71k
}
SourceCode.cpp:AK::Optional<unsigned long> AK::strict_lower_bound<AK::Span<JS::Position>, JS::Position const&, JS::SourceCode::range_from_offsets(unsigned int, unsigned int) const::$_0>(AK::Span<JS::Position>&&, JS::Position const&, JS::SourceCode::range_from_offsets(unsigned int, unsigned int) const::$_0)
Line
Count
Source
82
1.71k
{
83
    // lower_bound give you the "first element x such that i ≤ x".
84
    // This gives you the last element x such that x < i.
85
1.71k
    size_t index {};
86
1.71k
    binary_search(haystack, needle, &index, comparator);
87
1.71k
    if (index > 0 && comparator(needle, haystack[index]) <= 0)
88
1.71k
        index--;
89
90
1.71k
    if (index == 0 && comparator(needle, haystack[index]) <= 0)
91
0
        return OptionalNone {};
92
1.71k
    return index;
93
1.71k
}
Unexecuted instantiation: AK::Optional<unsigned long> AK::strict_lower_bound<AK::Span<unsigned long>, unsigned long&, AK::DefaultComparator>(AK::Span<unsigned long>&&, unsigned long&, AK::DefaultComparator)
94
95
struct UpperBoundComparator {
96
    template<typename T, typename S>
97
    [[nodiscard]] constexpr int operator()(T& lhs, S& rhs)
98
0
    {
99
0
        if (lhs >= rhs)
100
0
            return 1;
101
0
        return -1;
102
0
    }
103
};
104
105
template<typename Container, typename Needle, typename Comparator = UpperBoundComparator>
106
requires IsIntegral<RemoveReference<Needle>>
107
constexpr auto upper_bound(
108
    Container&& haystack,
109
    Needle&& needle,
110
    Comparator comparator = {}) -> Optional<size_t>
111
0
{
112
0
    size_t index = 0;
113
0
    binary_search(haystack, needle, &index, comparator);
114
0
    if (index == haystack.size() - 1 && comparator(needle, haystack[index]) >= 0)
115
0
        return OptionalNone {};
116
0
    return index;
117
0
}
Unexecuted instantiation: AK::Optional<unsigned long> AK::upper_bound<AK::Span<unsigned long>, unsigned long&, AK::UpperBoundComparator>(AK::Span<unsigned long>&&, unsigned long&, AK::UpperBoundComparator) requires IsIntegral<AK::Detail::__RemoveReference<unsigned long&>::Type>
Unexecuted instantiation: Image.cpp:AK::Optional<unsigned long> AK::upper_bound<AK::Vector<ELF::Image::SortedSymbol, 0ul>&, unsigned long&, ELF::Image::find_sorted_symbol(unsigned long) const::$_0>(AK::Vector<ELF::Image::SortedSymbol, 0ul>&, unsigned long&, ELF::Image::find_sorted_symbol(unsigned long) const::$_0) requires IsIntegral<AK::Detail::__RemoveReference<unsigned long&>::Type>
118
119
}
120
121
#if USING_AK_GLOBALLY
122
using AK::binary_search;
123
using AK::lower_bound;
124
using AK::strict_lower_bound;
125
using AK::upper_bound;
126
#endif