Coverage Report

Created: 2026-09-14 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/AK/IntegralMath.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2022, Leon Albrecht <leon2002.la@gmail.com>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#pragma once
8
9
#include <AK/BuiltinWrappers.h>
10
#include <AK/Concepts.h>
11
#include <AK/Types.h>
12
13
namespace AK {
14
15
template<Integral T>
16
constexpr T exp2(T exponent)
17
788k
{
18
788k
    return static_cast<T>(1) << exponent;
19
788k
}
_ZN2AK4exp2ITkNS_8Concepts8IntegralEmEET_S2_
Line
Count
Source
17
40.4k
{
18
40.4k
    return static_cast<T>(1) << exponent;
19
40.4k
}
_ZN2AK4exp2ITkNS_8Concepts8IntegralEjEET_S2_
Line
Count
Source
17
619k
{
18
619k
    return static_cast<T>(1) << exponent;
19
619k
}
_ZN2AK4exp2ITkNS_8Concepts8IntegralElEET_S2_
Line
Count
Source
17
19.2k
{
18
19.2k
    return static_cast<T>(1) << exponent;
19
19.2k
}
_ZN2AK4exp2ITkNS_8Concepts8IntegralEiEET_S2_
Line
Count
Source
17
91.1k
{
18
91.1k
    return static_cast<T>(1) << exponent;
19
91.1k
}
_ZN2AK4exp2ITkNS_8Concepts8IntegralEhEET_S2_
Line
Count
Source
17
18.0k
{
18
18.0k
    return static_cast<T>(1) << exponent;
19
18.0k
}
20
21
template<Integral T>
22
constexpr T log2(T x)
23
1.08M
{
24
1.08M
    return x ? (8 * sizeof(T) - 1) - count_leading_zeroes(static_cast<MakeUnsigned<T>>(x)) : 0;
25
1.08M
}
_ZN2AK4log2ITkNS_8Concepts8IntegralEmEET_S2_
Line
Count
Source
23
142
{
24
142
    return x ? (8 * sizeof(T) - 1) - count_leading_zeroes(static_cast<MakeUnsigned<T>>(x)) : 0;
25
142
}
_ZN2AK4log2ITkNS_8Concepts8IntegralEjEET_S2_
Line
Count
Source
23
1.08M
{
24
1.08M
    return x ? (8 * sizeof(T) - 1) - count_leading_zeroes(static_cast<MakeUnsigned<T>>(x)) : 0;
25
1.08M
}
Unexecuted instantiation: _ZN2AK4log2ITkNS_8Concepts8IntegralEiEET_S2_
_ZN2AK4log2ITkNS_8Concepts8IntegralEtEET_S2_
Line
Count
Source
23
1.76k
{
24
1.76k
    return x ? (8 * sizeof(T) - 1) - count_leading_zeroes(static_cast<MakeUnsigned<T>>(x)) : 0;
25
1.76k
}
Unexecuted instantiation: _ZN2AK4log2ITkNS_8Concepts8IntegralEhEET_S2_
26
27
template<Integral T>
28
constexpr T ceil_log2(T x)
29
680
{
30
680
    if (x <= 1)
31
538
        return 0;
32
33
142
    return AK::log2(x - 1) + 1;
34
680
}
_ZN2AK9ceil_log2ITkNS_8Concepts8IntegralEmEET_S2_
Line
Count
Source
29
680
{
30
680
    if (x <= 1)
31
538
        return 0;
32
33
142
    return AK::log2(x - 1) + 1;
34
680
}
Unexecuted instantiation: _ZN2AK9ceil_log2ITkNS_8Concepts8IntegralEjEET_S2_
Unexecuted instantiation: _ZN2AK9ceil_log2ITkNS_8Concepts8IntegralEiEET_S2_
35
36
template<Integral I>
37
constexpr I pow(I base, I exponent)
38
315
{
39
    // https://en.wikipedia.org/wiki/Exponentiation_by_squaring
40
315
    if (exponent < 0)
41
0
        return 0;
42
315
    if (exponent == 0)
43
0
        return 1;
44
45
315
    I res = 1;
46
1.14k
    while (exponent > 0) {
47
828
        if (exponent & 1)
48
355
            res *= base;
49
828
        base *= base;
50
828
        exponent /= 2u;
51
828
    }
52
315
    return res;
53
315
}
54
55
template<auto base, UnsignedIntegral U = decltype(base)>
56
constexpr bool is_power_of(U x)
57
{
58
    if constexpr (base == 1)
59
        return x == 1;
60
    else if constexpr (base == 2)
61
        return is_power_of_two(x);
62
63
    if (base == 0 && x == 0)
64
        return true;
65
    if (base == 0 || x == 0)
66
        return false;
67
68
    while (x != 1) {
69
        if (x % base != 0)
70
            return false;
71
        x /= base;
72
    }
73
    return true;
74
}
75
76
template<UnsignedIntegral T>
77
constexpr T reinterpret_as_octal(T decimal)
78
{
79
    T result = 0;
80
    T n = 0;
81
    while (decimal > 0) {
82
        result += pow<T>(8, n++) * (decimal % 10);
83
        decimal /= 10;
84
    }
85
    return result;
86
}
87
88
template<UnsignedIntegral T>
89
constexpr MakeSigned<T> sign_extend(T value, u8 bits)
90
145k
{
91
    // C++ considers the shift by sizeof(T) * 8 UB, and it doesn’t make logical sense to sign-extend 0 bits anyways.
92
145k
    VERIFY(bits > 0);
93
145k
    auto shift = sizeof(T) * 8 - bits;
94
145k
    return static_cast<MakeSigned<T>>(value << shift) >> shift;
95
145k
}
_ZN2AK11sign_extendITkNS_8Concepts16UnsignedIntegralEhEENS_6Detail12__MakeSignedIT_E4TypeES4_h
Line
Count
Source
90
635
{
91
    // C++ considers the shift by sizeof(T) * 8 UB, and it doesn’t make logical sense to sign-extend 0 bits anyways.
92
635
    VERIFY(bits > 0);
93
635
    auto shift = sizeof(T) * 8 - bits;
94
635
    return static_cast<MakeSigned<T>>(value << shift) >> shift;
95
635
}
_ZN2AK11sign_extendITkNS_8Concepts16UnsignedIntegralEmEENS_6Detail12__MakeSignedIT_E4TypeES4_h
Line
Count
Source
90
141k
{
91
    // C++ considers the shift by sizeof(T) * 8 UB, and it doesn’t make logical sense to sign-extend 0 bits anyways.
92
141k
    VERIFY(bits > 0);
93
141k
    auto shift = sizeof(T) * 8 - bits;
94
141k
    return static_cast<MakeSigned<T>>(value << shift) >> shift;
95
141k
}
_ZN2AK11sign_extendITkNS_8Concepts16UnsignedIntegralEjEENS_6Detail12__MakeSignedIT_E4TypeES4_h
Line
Count
Source
90
3.63k
{
91
    // C++ considers the shift by sizeof(T) * 8 UB, and it doesn’t make logical sense to sign-extend 0 bits anyways.
92
3.63k
    VERIFY(bits > 0);
93
3.63k
    auto shift = sizeof(T) * 8 - bits;
94
3.63k
    return static_cast<MakeSigned<T>>(value << shift) >> shift;
95
3.63k
}
96
97
}