Coverage Report

Created: 2026-06-07 07:41

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.39G
    {
19
1.39G
        if (lhs > rhs)
20
33.5M
            return 1;
21
22
1.36G
        if (lhs < rhs)
23
716M
            return -1;
24
25
647M
        return 0;
26
1.36G
    }
int AK::DefaultComparator::operator()<unsigned long, unsigned long const>(unsigned long&, unsigned long const&)
Line
Count
Source
18
1.39G
    {
19
1.39G
        if (lhs > rhs)
20
33.5M
            return 1;
21
22
1.36G
        if (lhs < rhs)
23
716M
            return -1;
24
25
647M
        return 0;
26
1.36G
    }
int AK::DefaultComparator::operator()<unsigned long const, unsigned long>(unsigned long const&, unsigned long&)
Line
Count
Source
18
24.5k
    {
19
24.5k
        if (lhs > rhs)
20
9.73k
            return 1;
21
22
14.8k
        if (lhs < rhs)
23
14.8k
            return -1;
24
25
0
        return 0;
26
14.8k
    }
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
718M
{
36
718M
    if (haystack.size() == 0) {
37
        // FIXME: Refactor the function's API to make it always return a valid index.
38
485
        if (nearby_index)
39
485
            *nearby_index = 0;
40
485
        return nullptr;
41
485
    }
42
43
718M
    size_t low = 0;
44
718M
    size_t high = haystack.size() - 1;
45
1.44G
    while (low != high) {
46
722M
        size_t middle = low + (high - low) / 2;
47
722M
        int comparison = comparator(needle, haystack[middle]);
48
722M
        if (comparison <= 0)
49
671M
            high = middle;
50
51.8M
        else
51
51.8M
            low = middle + 1;
52
722M
    }
53
54
718M
    if (nearby_index)
55
698M
        *nearby_index = high;
56
718M
    if (comparator(needle, haystack[high]) == 0)
57
613M
        return &haystack[high];
58
105M
    return nullptr;
59
718M
}
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
697M
{
36
697M
    if (haystack.size() == 0) {
37
        // FIXME: Refactor the function's API to make it always return a valid index.
38
485
        if (nearby_index)
39
485
            *nearby_index = 0;
40
485
        return nullptr;
41
485
    }
42
43
697M
    size_t low = 0;
44
697M
    size_t high = haystack.size() - 1;
45
1.39G
    while (low != high) {
46
698M
        size_t middle = low + (high - low) / 2;
47
698M
        int comparison = comparator(needle, haystack[middle]);
48
698M
        if (comparison <= 0)
49
665M
            high = middle;
50
33.5M
        else
51
33.5M
            low = middle + 1;
52
698M
    }
53
54
697M
    if (nearby_index)
55
697M
        *nearby_index = high;
56
697M
    if (comparator(needle, haystack[high]) == 0)
57
609M
        return &haystack[high];
58
88.8M
    return nullptr;
59
697M
}
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
92.6k
{
36
92.6k
    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
92.6k
    size_t low = 0;
44
92.6k
    size_t high = haystack.size() - 1;
45
763k
    while (low != high) {
46
670k
        size_t middle = low + (high - low) / 2;
47
670k
        int comparison = comparator(needle, haystack[middle]);
48
670k
        if (comparison <= 0)
49
87.6k
            high = middle;
50
582k
        else
51
582k
            low = middle + 1;
52
670k
    }
53
54
92.6k
    if (nearby_index)
55
92.6k
        *nearby_index = high;
56
92.6k
    if (comparator(needle, haystack[high]) == 0)
57
45
        return &haystack[high];
58
92.5k
    return nullptr;
59
92.6k
}
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, 328ul> const&, unsigned int&, Unicode::BlockNameComparator>(AK::Array<Unicode::BlockNameData, 328ul> const&, unsigned int&, unsigned long*, Unicode::BlockNameComparator)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Unicode::CodePointName, 33037ul> const&, unsigned int&, Unicode::CodePointNameComparator>(AK::Array<Unicode::CodePointName, 33037ul> 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, 5857ul> const&, unsigned int&, Unicode::CodePointComparator<Unicode::CodePointDecompositionRaw> >(AK::Array<Unicode::CodePointDecompositionRaw, 5857ul> const&, unsigned int&, unsigned long*, Unicode::CodePointComparator<Unicode::CodePointDecompositionRaw>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Unicode::CodePointCompositionRaw, 941ul> const&, unsigned int&, Unicode::CodePointComparator<Unicode::CodePointCompositionRaw> >(AK::Array<Unicode::CodePointCompositionRaw, 941ul> const&, unsigned int&, unsigned long*, Unicode::CodePointComparator<Unicode::CodePointCompositionRaw>)
Unexecuted instantiation: decltype (&({parm#1}[0])) AK::binary_search<AK::Array<Unicode::BidiClassData, 34912ul> const&, unsigned int&, Unicode::CodePointBidiClassComparator>(AK::Array<Unicode::BidiClassData, 34912ul> 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>, 144ul> const&, unsigned int&, Unicode::HashValueComparator<Unicode::Property> >(AK::Array<Unicode::HashValuePair<Unicode::Property>, 144ul> 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>, 322ul> const&, unsigned int&, Unicode::HashValueComparator<Unicode::Script> >(AK::Array<Unicode::HashValuePair<Unicode::Script>, 322ul> 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
3.27k
{
36
3.27k
    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
3.27k
    size_t low = 0;
44
3.27k
    size_t high = haystack.size() - 1;
45
19.6k
    while (low != high) {
46
16.4k
        size_t middle = low + (high - low) / 2;
47
16.4k
        int comparison = comparator(needle, haystack[middle]);
48
16.4k
        if (comparison <= 0)
49
8.29k
            high = middle;
50
8.11k
        else
51
8.11k
            low = middle + 1;
52
16.4k
    }
53
54
3.27k
    if (nearby_index)
55
3.27k
        *nearby_index = high;
56
3.27k
    if (comparator(needle, haystack[high]) == 0)
57
0
        return &haystack[high];
58
3.27k
    return nullptr;
59
3.27k
}
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
20.1M
{
36
20.1M
    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
20.1M
    size_t low = 0;
44
20.1M
    size_t high = haystack.size() - 1;
45
40.5M
    while (low != high) {
46
20.4M
        size_t middle = low + (high - low) / 2;
47
20.4M
        int comparison = comparator(needle, haystack[middle]);
48
20.4M
        if (comparison <= 0)
49
5.35M
            high = middle;
50
15.0M
        else
51
15.0M
            low = middle + 1;
52
20.4M
    }
53
54
20.1M
    if (nearby_index)
55
0
        *nearby_index = high;
56
20.1M
    if (comparator(needle, haystack[high]) == 0)
57
4.23M
        return &haystack[high];
58
15.9M
    return nullptr;
59
20.1M
}
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
241k
{
36
241k
    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
241k
    size_t low = 0;
44
241k
    size_t high = haystack.size() - 1;
45
2.43M
    while (low != high) {
46
2.19M
        size_t middle = low + (high - low) / 2;
47
2.19M
        int comparison = comparator(needle, haystack[middle]);
48
2.19M
        if (comparison <= 0)
49
254k
            high = middle;
50
1.93M
        else
51
1.93M
            low = middle + 1;
52
2.19M
    }
53
54
241k
    if (nearby_index)
55
241k
        *nearby_index = high;
56
241k
    if (comparator(needle, haystack[high]) == 0)
57
31.8k
        return &haystack[high];
58
209k
    return nullptr;
59
241k
}
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
95.7k
{
36
95.7k
    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
95.7k
    size_t low = 0;
44
95.7k
    size_t high = haystack.size() - 1;
45
887k
    while (low != high) {
46
791k
        size_t middle = low + (high - low) / 2;
47
791k
        int comparison = comparator(needle, haystack[middle]);
48
791k
        if (comparison <= 0)
49
12.6k
            high = middle;
50
779k
        else
51
779k
            low = middle + 1;
52
791k
    }
53
54
95.7k
    if (nearby_index)
55
95.7k
        *nearby_index = high;
56
95.7k
    if (comparator(needle, haystack[high]) == 0)
57
18.0k
        return &haystack[high];
58
77.6k
    return nullptr;
59
95.7k
}
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
3.27k
{
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
3.27k
    size_t index {};
86
3.27k
    binary_search(haystack, needle, &index, comparator);
87
3.27k
    if (index > 0 && comparator(needle, haystack[index]) <= 0)
88
3.27k
        index--;
89
90
3.27k
    if (index == 0 && comparator(needle, haystack[index]) <= 0)
91
0
        return OptionalNone {};
92
3.27k
    return index;
93
3.27k
}
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
3.27k
{
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
3.27k
    size_t index {};
86
3.27k
    binary_search(haystack, needle, &index, comparator);
87
3.27k
    if (index > 0 && comparator(needle, haystack[index]) <= 0)
88
3.27k
        index--;
89
90
3.27k
    if (index == 0 && comparator(needle, haystack[index]) <= 0)
91
0
        return OptionalNone {};
92
3.27k
    return index;
93
3.27k
}
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