Coverage Report

Created: 2025-12-18 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/AK/DistinctNumeric.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2020, Ben Wiederhake <BenWiederhake.GitHub@gmx.de>
3
 * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
4
 * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
5
 *
6
 * SPDX-License-Identifier: BSD-2-Clause
7
 */
8
9
#pragma once
10
11
#include <AK/Format.h>
12
#include <AK/Traits.h>
13
#include <AK/Types.h>
14
15
namespace AK {
16
17
/**
18
 * This implements a "distinct" numeric type that is intentionally incompatible
19
 * to other incantations. The intention is that each "distinct" type that you
20
 * want simply gets different values for `fn_length` and `line`. The macros
21
 * `TYPEDEF_DISTINCT_NUMERIC_*()` at the bottom of `DistinctNumeric.h`.
22
 *
23
 * The tags in `DistinctNumericFeature` simply split up the space of operators into 6 simple categories:
24
 * - No matter the values of these, `DistinctNumeric` always implements `==` and `!=`.
25
 * - If `Arithmetic` is present, then `a+b`, `a-b`, `+a`, `-a`, `a*b`, `a/b`, `a%b`, and the respective `a_=b` versions are implemented.
26
 * - If `CastToBool` is present, then `!a`, `a&&b`, and `a||b` are implemented (but not `operator bool()`, because of overzealous integer promotion rules).
27
 * - If `Comparison` is present, then `a>b`, `a<b`, `a>=b`, and `a<=b` are implemented via operator<=>
28
 * - If `Flags` is present, then `~a`, `a&b`, `a|b`, `a^b`, `a&=b`, `a|=b`, and `a^=b` are implemented.
29
 * - If `Increment` is present, then `++a`, `a++`, `--a`, and `a--` are implemented.
30
 * - If `Shift` is present, then `a<<b`, `a>>b`, `a<<=b`, `a>>=b` are implemented.
31
 * The semantics are always those of the underlying basic type `T`.
32
 *
33
 * These can be combined arbitrarily. Want a numeric type that supports `++a`
34
 * and `a >> b` but not `a > b`? Sure thing, just set
35
 * `Increment, Comparison, Shift` and you're done!
36
 * Furthermore, some of these overloads make more sense with specific types, like `a&&b` which should be able to operate
37
 *
38
 * I intentionally decided against overloading `&a` because these shall remain
39
 * numeric types.
40
 *
41
 * The are many operators that do not work on `int`, so I left them out:
42
 * `a[b]`, `*a`, `a->b`, `a.b`, `a->*b`, `a.*b`.
43
 *
44
 * There are many more operators that do not make sense for numerical types,
45
 * or cannot be overloaded in the first place. Naturally, they are not implemented.
46
 */
47
48
namespace DistinctNumericFeature {
49
enum Arithmetic { };
50
enum CastToBool { };
51
enum CastToUnderlying { };
52
enum Comparison { };
53
enum Flags { };
54
enum Increment { };
55
enum Shift { };
56
};
57
58
template<typename T, typename X, typename... Opts>
59
class DistinctNumeric {
60
    using Self = DistinctNumeric<T, X, Opts...>;
61
62
    struct Option {
63
        template<typename K, typename... Os>
64
        consteval Option(K option, Os... other_options)
65
            : Option(other_options...)
66
        {
67
            set(option);
68
        }
69
70
        consteval Option() { }
71
72
0
        constexpr void set(DistinctNumericFeature::Arithmetic const&) { arithmetic = true; }
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__InstructionPointer_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Flags, AK::DistinctNumericFeature::Increment>::Option::set(AK::DistinctNumericFeature::Arithmetic const&)
Unexecuted instantiation: AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::Option::set(AK::DistinctNumericFeature::Arithmetic const&)
73
0
        constexpr void set(DistinctNumericFeature::CastToBool const&) { cast_to_bool = true; }
74
0
        constexpr void set(DistinctNumericFeature::CastToUnderlying const&) { cast_to_underlying = true; }
75
0
        constexpr void set(DistinctNumericFeature::Comparison const&) { comparisons = true; }
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__InstructionPointer_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Flags, AK::DistinctNumericFeature::Increment>::Option::set(AK::DistinctNumericFeature::Comparison const&)
Unexecuted instantiation: AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::Option::set(AK::DistinctNumericFeature::Comparison const&)
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__GlobalIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::Option::set(AK::DistinctNumericFeature::Comparison const&)
76
0
        constexpr void set(DistinctNumericFeature::Flags const&) { flags = true; }
77
0
        constexpr void set(DistinctNumericFeature::Increment const&) { increment = true; }
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__InstructionPointer_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Flags, AK::DistinctNumericFeature::Increment>::Option::set(AK::DistinctNumericFeature::Increment const&)
Unexecuted instantiation: AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::Option::set(AK::DistinctNumericFeature::Increment const&)
78
        constexpr void set(DistinctNumericFeature::Shift const&) { shift = true; }
79
80
        bool arithmetic { false };
81
        bool cast_to_bool { false };
82
        bool cast_to_underlying { false };
83
        bool comparisons { false };
84
        bool flags { false };
85
        bool increment { false };
86
        bool shift { false };
87
    };
88
89
    constexpr static Option options { Opts()... };
90
91
public:
92
    using Type = T;
93
94
3.03M
    constexpr DistinctNumeric() = default;
AK::DistinctNumeric<unsigned long, Wasm::__InstructionPointer_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Flags, AK::DistinctNumericFeature::Increment>::DistinctNumeric()
Line
Count
Source
94
3.03M
    constexpr DistinctNumeric() = default;
Unexecuted instantiation: AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::DistinctNumeric()
95
96
    constexpr DistinctNumeric(T value)
97
26.2M
        : m_value { value }
98
26.2M
    {
99
26.2M
    }
AK::DistinctNumeric<unsigned long, Wasm::__TypeIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::DistinctNumeric(unsigned long)
Line
Count
Source
97
5.32M
        : m_value { value }
98
5.32M
    {
99
5.32M
    }
AK::DistinctNumeric<unsigned long, Wasm::__OpCode_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::DistinctNumeric(unsigned long)
Line
Count
Source
97
8.17M
        : m_value { value }
98
8.17M
    {
99
8.17M
    }
AK::DistinctNumeric<unsigned long, Wasm::__MemoryIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::DistinctNumeric(unsigned long)
Line
Count
Source
97
70.6k
        : m_value { value }
98
70.6k
    {
99
70.6k
    }
AK::DistinctNumeric<unsigned long, Wasm::__InstructionPointer_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Flags, AK::DistinctNumericFeature::Increment>::DistinctNumeric(unsigned long)
Line
Count
Source
97
378k
        : m_value { value }
98
378k
    {
99
378k
    }
AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::DistinctNumeric(unsigned long)
Line
Count
Source
97
8.70M
        : m_value { value }
98
8.70M
    {
99
8.70M
    }
AK::DistinctNumeric<unsigned long, Wasm::__TableIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::DistinctNumeric(unsigned long)
Line
Count
Source
97
102k
        : m_value { value }
98
102k
    {
99
102k
    }
AK::DistinctNumeric<unsigned long, Wasm::__GlobalIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::DistinctNumeric(unsigned long)
Line
Count
Source
97
19.6k
        : m_value { value }
98
19.6k
    {
99
19.6k
    }
AK::DistinctNumeric<unsigned long, Wasm::__LabelIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::DistinctNumeric(unsigned long)
Line
Count
Source
97
3.43M
        : m_value { value }
98
3.43M
    {
99
3.43M
    }
AK::DistinctNumeric<unsigned long, Wasm::__LocalIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::DistinctNumeric(unsigned long)
Line
Count
Source
97
35.5k
        : m_value { value }
98
35.5k
    {
99
35.5k
    }
AK::DistinctNumeric<unsigned long, Wasm::__DataIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::DistinctNumeric(unsigned long)
Line
Count
Source
97
989
        : m_value { value }
98
989
    {
99
989
    }
AK::DistinctNumeric<unsigned long, Wasm::__ElementIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::DistinctNumeric(unsigned long)
Line
Count
Source
97
1.05k
        : m_value { value }
98
1.05k
    {
99
1.05k
    }
Unexecuted instantiation: AK::DistinctNumeric<unsigned int, JS::Bytecode::__StringTableIndex_tag, AK::DistinctNumericFeature::Comparison>::DistinctNumeric(unsigned int)
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, JS::Bytecode::__RegexTableIndex_tag, AK::DistinctNumericFeature::Comparison>::DistinctNumeric(unsigned long)
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Web::HTML::__TaskID_tag, AK::DistinctNumericFeature::Comparison>::DistinctNumeric(unsigned long)
Unexecuted instantiation: AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::DistinctNumeric(int)
Unexecuted instantiation: AK::DistinctNumeric<long, Threading::__ThreadError_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::DistinctNumeric(long)
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__FunctionAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::DistinctNumeric(unsigned long)
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__TableAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::DistinctNumeric(unsigned long)
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__MemoryAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::DistinctNumeric(unsigned long)
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__GlobalAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::DistinctNumeric(unsigned long)
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__DataAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::DistinctNumeric(unsigned long)
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__ElementAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::DistinctNumeric(unsigned long)
100
101
8.02M
    constexpr T const& value() const { return m_value; }
AK::DistinctNumeric<unsigned long, Wasm::__OpCode_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value() const
Line
Count
Source
101
8.02M
    constexpr T const& value() const { return m_value; }
Unexecuted instantiation: AK::DistinctNumeric<unsigned int, JS::Bytecode::__StringTableIndex_tag, AK::DistinctNumericFeature::Comparison>::value() const
Unexecuted instantiation: AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::value() const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__FunctionAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::value() const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__TableAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::value() const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__MemoryAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::value() const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__TableIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value() const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__MemoryIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value() const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value() const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__GlobalIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value() const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__LocalIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value() const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__TypeIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value() const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__InstructionPointer_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Flags, AK::DistinctNumericFeature::Increment>::value() const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__DataIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value() const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__ElementIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value() const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__LabelIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value() const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__ExternAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::value() const
102
8.49M
    constexpr T& value() { return m_value; }
AK::DistinctNumeric<unsigned long, Wasm::__OpCode_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value()
Line
Count
Source
102
8.32M
    constexpr T& value() { return m_value; }
AK::DistinctNumeric<unsigned long, Wasm::__InstructionPointer_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Flags, AK::DistinctNumericFeature::Increment>::value()
Line
Count
Source
102
168k
    constexpr T& value() { return m_value; }
Unexecuted instantiation: AK::DistinctNumeric<unsigned int, JS::Bytecode::__StringTableIndex_tag, AK::DistinctNumericFeature::Comparison>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, JS::Bytecode::__RegexTableIndex_tag, AK::DistinctNumericFeature::Comparison>::value()
Unexecuted instantiation: AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__TypeIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__FunctionAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__MemoryIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__ElementIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__DataIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__GlobalIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__LabelIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__LocalIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__TableIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__TableAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__MemoryAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__GlobalAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__ElementAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::value()
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__DataAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::value()
103
104
    // Always implemented: identity.
105
    constexpr bool operator==(Self const& other) const
106
0
    {
107
0
        return this->m_value == other.m_value;
108
0
    }
Unexecuted instantiation: AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::operator==(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> const&) const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Web::HTML::__TaskID_tag, AK::DistinctNumericFeature::Comparison>::operator==(AK::DistinctNumeric<unsigned long, Web::HTML::__TaskID_tag, AK::DistinctNumericFeature::Comparison> const&) const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__FunctionAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::operator==(AK::DistinctNumeric<unsigned long, Wasm::__FunctionAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> const&) const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__TableAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::operator==(AK::DistinctNumeric<unsigned long, Wasm::__TableAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> const&) const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__MemoryAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::operator==(AK::DistinctNumeric<unsigned long, Wasm::__MemoryAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> const&) const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__InstructionPointer_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Flags, AK::DistinctNumericFeature::Increment>::operator==(AK::DistinctNumeric<unsigned long, Wasm::__InstructionPointer_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Flags, AK::DistinctNumericFeature::Increment> const&) const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__OpCode_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::operator==(AK::DistinctNumeric<unsigned long, Wasm::__OpCode_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> const&) const
109
110
    // Only implemented when `CastToUnderlying` is true:
111
    constexpr explicit operator T() const
112
0
    {
113
0
        static_assert(options.cast_to_underlying, "Cast to underlying type is only available for DistinctNumeric types with 'CastToUnderlying'.");
114
0
        return value();
115
0
    }
116
117
    // Only implemented when `Increment` is true:
118
    constexpr Self& operator++()
119
7.99M
    {
120
7.99M
        static_assert(options.increment, "'++a' is only available for DistinctNumeric types with 'Increment'.");
121
7.99M
        this->m_value += 1;
122
7.99M
        return *this;
123
7.99M
    }
124
    constexpr Self operator++(int)
125
    {
126
        static_assert(options.increment, "'a++' is only available for DistinctNumeric types with 'Increment'.");
127
        Self ret = this->m_value;
128
        this->m_value += 1;
129
        return ret;
130
    }
131
    constexpr Self& operator--()
132
    {
133
        static_assert(options.increment, "'--a' is only available for DistinctNumeric types with 'Increment'.");
134
        this->m_value -= 1;
135
        return *this;
136
    }
137
    constexpr Self operator--(int)
138
    {
139
        static_assert(options.increment, "'a--' is only available for DistinctNumeric types with 'Increment'.");
140
        Self ret = this->m_value;
141
        this->m_value -= 1;
142
        return ret;
143
    }
144
145
    // Only implemented when `Comparison` is true:
146
    constexpr int operator<=>(Self const& other) const
147
0
    {
148
0
        static_assert(options.comparisons, "'a<=>b' is only available for DistinctNumeric types with 'Comparison'.");
149
0
        return this->m_value > other.m_value ? 1 : this->m_value < other.m_value ? -1
150
0
                                                                                 : 0;
151
0
    }
Unexecuted instantiation: AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::operator<=>(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> const&) const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__InstructionPointer_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Flags, AK::DistinctNumericFeature::Increment>::operator<=>(AK::DistinctNumeric<unsigned long, Wasm::__InstructionPointer_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Flags, AK::DistinctNumericFeature::Increment> const&) const
Unexecuted instantiation: AK::DistinctNumeric<unsigned long, Wasm::__GlobalIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool>::operator<=>(AK::DistinctNumeric<unsigned long, Wasm::__GlobalIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> const&) const
152
153
    // Only implemented when `CastToBool` is true:
154
    constexpr bool operator!() const
155
    {
156
        static_assert(options.cast_to_bool, "'!a' is only available for DistinctNumeric types with 'CastToBool'.");
157
        return !this->m_value;
158
    }
159
    // Intentionally don't define `operator bool() const` here. C++ is a bit
160
    // overzealous, and whenever there would be a type error, C++ instead tries
161
    // to convert to a common int-ish type first. `bool` is int-ish, so
162
    // `operator bool() const` would defy the entire point of this class.
163
164
    // Only implemented when `Flags` is true:
165
    constexpr Self operator~() const
166
    {
167
        static_assert(options.flags, "'~a' is only available for DistinctNumeric types with 'Flags'.");
168
        return ~this->m_value;
169
    }
170
    constexpr Self operator&(Self const& other) const
171
    {
172
        static_assert(options.flags, "'a&b' is only available for DistinctNumeric types with 'Flags'.");
173
        return this->m_value & other.m_value;
174
    }
175
    constexpr Self operator|(Self const& other) const
176
    {
177
        static_assert(options.flags, "'a|b' is only available for DistinctNumeric types with 'Flags'.");
178
        return this->m_value | other.m_value;
179
    }
180
    constexpr Self operator^(Self const& other) const
181
    {
182
        static_assert(options.flags, "'a^b' is only available for DistinctNumeric types with 'Flags'.");
183
        return this->m_value ^ other.m_value;
184
    }
185
    constexpr Self& operator&=(Self const& other)
186
    {
187
        static_assert(options.flags, "'a&=b' is only available for DistinctNumeric types with 'Flags'.");
188
        this->m_value &= other.m_value;
189
        return *this;
190
    }
191
    constexpr Self& operator|=(Self const& other)
192
    {
193
        static_assert(options.flags, "'a|=b' is only available for DistinctNumeric types with 'Flags'.");
194
        this->m_value |= other.m_value;
195
        return *this;
196
    }
197
    constexpr Self& operator^=(Self const& other)
198
    {
199
        static_assert(options.flags, "'a^=b' is only available for DistinctNumeric types with 'Flags'.");
200
        this->m_value ^= other.m_value;
201
        return *this;
202
    }
203
204
    // Only implemented when `Shift` is true:
205
    // TODO: Should this take `int` instead?
206
    constexpr Self operator<<(Self const& other) const
207
    {
208
        static_assert(options.shift, "'a<<b' is only available for DistinctNumeric types with 'Shift'.");
209
        return this->m_value << other.m_value;
210
    }
211
    constexpr Self operator>>(Self const& other) const
212
    {
213
        static_assert(options.shift, "'a>>b' is only available for DistinctNumeric types with 'Shift'.");
214
        return this->m_value >> other.m_value;
215
    }
216
    constexpr Self& operator<<=(Self const& other)
217
    {
218
        static_assert(options.shift, "'a<<=b' is only available for DistinctNumeric types with 'Shift'.");
219
        this->m_value <<= other.m_value;
220
        return *this;
221
    }
222
    constexpr Self& operator>>=(Self const& other)
223
    {
224
        static_assert(options.shift, "'a>>=b' is only available for DistinctNumeric types with 'Shift'.");
225
        this->m_value >>= other.m_value;
226
        return *this;
227
    }
228
229
    // Only implemented when `Arithmetic` is true:
230
    constexpr Self operator+(Self const& other) const
231
168k
    {
232
168k
        static_assert(options.arithmetic, "'a+b' is only available for DistinctNumeric types with 'Arithmetic'.");
233
168k
        return this->m_value + other.m_value;
234
168k
    }
AK::DistinctNumeric<unsigned long, Wasm::__InstructionPointer_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Flags, AK::DistinctNumericFeature::Increment>::operator+(AK::DistinctNumeric<unsigned long, Wasm::__InstructionPointer_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Flags, AK::DistinctNumericFeature::Increment> const&) const
Line
Count
Source
231
168k
    {
232
168k
        static_assert(options.arithmetic, "'a+b' is only available for DistinctNumeric types with 'Arithmetic'.");
233
168k
        return this->m_value + other.m_value;
234
168k
    }
Unexecuted instantiation: AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment>::operator+(AK::DistinctNumeric<int, Web::__DevicePixels_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::CastToUnderlying, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> const&) const
235
    constexpr Self operator-(Self const& other) const
236
0
    {
237
0
        static_assert(options.arithmetic, "'a-b' is only available for DistinctNumeric types with 'Arithmetic'.");
238
0
        return this->m_value - other.m_value;
239
0
    }
240
    constexpr Self operator+() const
241
    {
242
        static_assert(options.arithmetic, "'+a' is only available for DistinctNumeric types with 'Arithmetic'.");
243
        return +this->m_value;
244
    }
245
    constexpr Self operator-() const
246
0
    {
247
0
        static_assert(options.arithmetic, "'-a' is only available for DistinctNumeric types with 'Arithmetic'.");
248
0
        return -this->m_value;
249
0
    }
250
    constexpr Self operator*(Self const& other) const
251
    {
252
        static_assert(options.arithmetic, "'a*b' is only available for DistinctNumeric types with 'Arithmetic'.");
253
        return this->m_value * other.m_value;
254
    }
255
    constexpr Self operator/(Self const& other) const
256
    {
257
        static_assert(options.arithmetic, "'a/b' is only available for DistinctNumeric types with 'Arithmetic'.");
258
        return this->m_value / other.m_value;
259
    }
260
    constexpr Self operator%(Self const& other) const
261
    {
262
        static_assert(options.arithmetic, "'a%b' is only available for DistinctNumeric types with 'Arithmetic'.");
263
        return this->m_value % other.m_value;
264
    }
265
    constexpr Self& operator+=(Self const& other)
266
0
    {
267
0
        static_assert(options.arithmetic, "'a+=b' is only available for DistinctNumeric types with 'Arithmetic'.");
268
0
        this->m_value += other.m_value;
269
0
        return *this;
270
0
    }
271
    constexpr Self& operator-=(Self const& other)
272
0
    {
273
0
        static_assert(options.arithmetic, "'a-=b' is only available for DistinctNumeric types with 'Arithmetic'.");
274
0
        this->m_value -= other.m_value;
275
0
        return *this;
276
0
    }
277
    constexpr Self& operator*=(Self const& other)
278
    {
279
        static_assert(options.arithmetic, "'a*=b' is only available for DistinctNumeric types with 'Arithmetic'.");
280
        this->m_value *= other.m_value;
281
        return *this;
282
    }
283
    constexpr Self& operator/=(Self const& other)
284
    {
285
        static_assert(options.arithmetic, "'a/=b' is only available for DistinctNumeric types with 'Arithmetic'.");
286
        this->m_value /= other.m_value;
287
        return *this;
288
    }
289
    constexpr Self& operator%=(Self const& other)
290
    {
291
        static_assert(options.arithmetic, "'a%=b' is only available for DistinctNumeric types with 'Arithmetic'.");
292
        this->m_value %= other.m_value;
293
        return *this;
294
    }
295
296
private:
297
    T m_value {};
298
};
299
300
template<typename T, typename X, typename... Opts>
301
struct Formatter<DistinctNumeric<T, X, Opts...>> : Formatter<T> {
302
    ErrorOr<void> format(FormatBuilder& builder, DistinctNumeric<T, X, Opts...> value)
303
0
    {
304
0
        return Formatter<T>::format(builder, value.value());
305
0
    }
306
};
307
}
308
309
#define AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(T, NAME, ...)                                       \
310
    struct NAME##_decl {                                                                        \
311
        using Arithmetic [[maybe_unused]] = AK::DistinctNumericFeature::Arithmetic;             \
312
        using CastToBool [[maybe_unused]] = AK::DistinctNumericFeature::CastToBool;             \
313
        using CastToUnderlying [[maybe_unused]] = AK::DistinctNumericFeature::CastToUnderlying; \
314
        using Comparison [[maybe_unused]] = AK::DistinctNumericFeature::Comparison;             \
315
        using Flags [[maybe_unused]] = AK::DistinctNumericFeature::Flags;                       \
316
        using Increment [[maybe_unused]] = AK::DistinctNumericFeature::Increment;               \
317
        using Shift [[maybe_unused]] = AK::DistinctNumericFeature::Shift;                       \
318
        using NAME [[maybe_unused]] = DistinctNumeric<T, struct __##NAME##_tag, ##__VA_ARGS__>; \
319
    };                                                                                          \
320
    using NAME = typename NAME##_decl::NAME;
321
322
#define AK_TYPEDEF_DISTINCT_ORDERED_ID(T, NAME) AK_TYPEDEF_DISTINCT_NUMERIC_GENERAL(T, NAME, Comparison, CastToBool)
323
// TODO: Further type aliases?
324
325
#define AK_MAKE_DISTINCT_NUMERIC_COMPARABLE_TO_ENUM(DN, E) \
326
    constexpr bool operator==(DN n, E e) { return n.value() == to_underlying(e); }
327
328
template<typename T, typename X, typename... Opts>
329
struct Traits<AK::DistinctNumeric<T, X, Opts...>> : public DefaultTraits<AK::DistinctNumeric<T, X, Opts...>> {
330
0
    static constexpr bool is_trivial() { return true; }
Unexecuted instantiation: AK::Traits<AK::DistinctNumeric<unsigned long, Wasm::__LabelIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> >::is_trivial()
Unexecuted instantiation: AK::Traits<AK::DistinctNumeric<unsigned long, Wasm::__TypeIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> >::is_trivial()
Unexecuted instantiation: AK::Traits<AK::DistinctNumeric<unsigned long, Wasm::__InstructionPointer_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Flags, AK::DistinctNumericFeature::Increment> >::is_trivial()
Unexecuted instantiation: AK::Traits<AK::DistinctNumeric<unsigned long, Wasm::__FunctionIndex_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> >::is_trivial()
Unexecuted instantiation: AK::Traits<AK::DistinctNumeric<unsigned long, Wasm::__GlobalAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::is_trivial()
Unexecuted instantiation: AK::Traits<AK::DistinctNumeric<unsigned long, Wasm::__FunctionAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::is_trivial()
Unexecuted instantiation: AK::Traits<AK::DistinctNumeric<unsigned long, Wasm::__DataAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::is_trivial()
Unexecuted instantiation: AK::Traits<AK::DistinctNumeric<unsigned long, Wasm::__TableAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::is_trivial()
Unexecuted instantiation: AK::Traits<AK::DistinctNumeric<unsigned long, Wasm::__MemoryAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::is_trivial()
Unexecuted instantiation: AK::Traits<AK::DistinctNumeric<unsigned long, Wasm::__ElementAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::is_trivial()
331
0
    static constexpr auto hash(DistinctNumeric<T, X, Opts...> const& d) { return Traits<T>::hash(d.value()); }
Unexecuted instantiation: AK::Traits<AK::DistinctNumeric<unsigned long, Wasm::__FunctionAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::hash(AK::DistinctNumeric<unsigned long, Wasm::__FunctionAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> const&)
Unexecuted instantiation: AK::Traits<AK::DistinctNumeric<unsigned long, Wasm::__TableAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::hash(AK::DistinctNumeric<unsigned long, Wasm::__TableAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> const&)
Unexecuted instantiation: AK::Traits<AK::DistinctNumeric<unsigned long, Wasm::__MemoryAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> >::hash(AK::DistinctNumeric<unsigned long, Wasm::__MemoryAddress_tag, AK::DistinctNumericFeature::Arithmetic, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::Increment> const&)
Unexecuted instantiation: AK::Traits<AK::DistinctNumeric<unsigned long, Wasm::__OpCode_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> >::hash(AK::DistinctNumeric<unsigned long, Wasm::__OpCode_tag, AK::DistinctNumericFeature::Comparison, AK::DistinctNumericFeature::CastToBool> const&)
332
};
333
334
#if USING_AK_GLOBALLY
335
using AK::DistinctNumeric;
336
#endif