/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 |