/src/serenity/AK/Checked.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2011-2019 Apple Inc. All rights reserved. |
3 | | * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> |
4 | | * All rights reserved. |
5 | | * |
6 | | * Redistribution and use in source and binary forms, with or without |
7 | | * modification, are permitted provided that the following conditions are met: |
8 | | * |
9 | | * 1. Redistributions of source code must retain the above copyright notice, this |
10 | | * list of conditions and the following disclaimer. |
11 | | * |
12 | | * 2. Redistributions in binary form must reproduce the above copyright notice, |
13 | | * this list of conditions and the following disclaimer in the documentation |
14 | | * and/or other materials provided with the distribution. |
15 | | * |
16 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
17 | | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
18 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
20 | | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
21 | | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
22 | | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
23 | | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
25 | | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | | */ |
27 | | |
28 | | #pragma once |
29 | | |
30 | | #include <AK/Assertions.h> |
31 | | #include <AK/Concepts.h> |
32 | | #include <AK/NumericLimits.h> |
33 | | #include <AK/StdLibExtras.h> |
34 | | |
35 | | namespace AK { |
36 | | |
37 | | template<typename Destination, typename Source, bool destination_is_wider = (sizeof(Destination) >= sizeof(Source)), bool destination_is_signed = NumericLimits<Destination>::is_signed(), bool source_is_signed = NumericLimits<Source>::is_signed()> |
38 | | struct TypeBoundsChecker; |
39 | | |
40 | | template<typename Destination, typename Source> |
41 | | struct TypeBoundsChecker<Destination, Source, false, false, false> { |
42 | | static constexpr bool is_within_range(Source value) |
43 | 77 | { |
44 | 77 | return value <= NumericLimits<Destination>::max(); |
45 | 77 | } AK::TypeBoundsChecker<unsigned int, unsigned long, false, false, false>::is_within_range(unsigned long) Line | Count | Source | 43 | 77 | { | 44 | 77 | return value <= NumericLimits<Destination>::max(); | 45 | 77 | } |
Unexecuted instantiation: AK::TypeBoundsChecker<unsigned char, unsigned long, false, false, false>::is_within_range(unsigned long) Unexecuted instantiation: AK::TypeBoundsChecker<unsigned short, unsigned long, false, false, false>::is_within_range(unsigned long) |
46 | | }; |
47 | | |
48 | | template<typename Destination, typename Source> |
49 | | struct TypeBoundsChecker<Destination, Source, false, true, true> { |
50 | | static constexpr bool is_within_range(Source value) |
51 | 0 | { |
52 | 0 | return value <= NumericLimits<Destination>::max() |
53 | 0 | && NumericLimits<Destination>::min() <= value; |
54 | 0 | } Unexecuted instantiation: AK::TypeBoundsChecker<int, long, false, true, true>::is_within_range(long) Unexecuted instantiation: AK::TypeBoundsChecker<signed char, long, false, true, true>::is_within_range(long) Unexecuted instantiation: AK::TypeBoundsChecker<short, long, false, true, true>::is_within_range(long) Unexecuted instantiation: AK::TypeBoundsChecker<int, double, false, true, true>::is_within_range(double) |
55 | | }; |
56 | | |
57 | | template<typename Destination, typename Source> |
58 | | struct TypeBoundsChecker<Destination, Source, false, false, true> { |
59 | | static constexpr bool is_within_range(Source value) |
60 | 0 | { |
61 | 0 | return value >= 0 && value <= NumericLimits<Destination>::max(); |
62 | 0 | } Unexecuted instantiation: AK::TypeBoundsChecker<unsigned int, long, false, false, true>::is_within_range(long) Unexecuted instantiation: AK::TypeBoundsChecker<unsigned char, long, false, false, true>::is_within_range(long) Unexecuted instantiation: AK::TypeBoundsChecker<unsigned short, long, false, false, true>::is_within_range(long) Unexecuted instantiation: AK::TypeBoundsChecker<unsigned int, double, false, false, true>::is_within_range(double) Unexecuted instantiation: AK::TypeBoundsChecker<unsigned char, double, false, false, true>::is_within_range(double) Unexecuted instantiation: AK::TypeBoundsChecker<unsigned short, double, false, false, true>::is_within_range(double) |
63 | | }; |
64 | | |
65 | | template<typename Destination, typename Source> |
66 | | struct TypeBoundsChecker<Destination, Source, false, true, false> { |
67 | | static constexpr bool is_within_range(Source value) |
68 | 0 | { |
69 | 0 | return value <= static_cast<Source>(NumericLimits<Destination>::max()); |
70 | 0 | } Unexecuted instantiation: AK::TypeBoundsChecker<int, unsigned long, false, true, false>::is_within_range(unsigned long) Unexecuted instantiation: AK::TypeBoundsChecker<signed char, unsigned long, false, true, false>::is_within_range(unsigned long) Unexecuted instantiation: AK::TypeBoundsChecker<short, unsigned long, false, true, false>::is_within_range(unsigned long) |
71 | | }; |
72 | | |
73 | | template<typename Destination, typename Source> |
74 | | struct TypeBoundsChecker<Destination, Source, true, false, false> { |
75 | | static constexpr bool is_within_range(Source) |
76 | 8.04G | { |
77 | 8.04G | return true; |
78 | 8.04G | } AK::TypeBoundsChecker<unsigned long, unsigned long, true, false, false>::is_within_range(unsigned long) Line | Count | Source | 76 | 8.03G | { | 77 | 8.03G | return true; | 78 | 8.03G | } |
AK::TypeBoundsChecker<unsigned long, unsigned int, true, false, false>::is_within_range(unsigned int) Line | Count | Source | 76 | 63 | { | 77 | 63 | return true; | 78 | 63 | } |
AK::TypeBoundsChecker<unsigned int, unsigned int, true, false, false>::is_within_range(unsigned int) Line | Count | Source | 76 | 75 | { | 77 | 75 | return true; | 78 | 75 | } |
AK::TypeBoundsChecker<unsigned int, unsigned char, true, false, false>::is_within_range(unsigned char) Line | Count | Source | 76 | 4.66M | { | 77 | 4.66M | return true; | 78 | 4.66M | } |
AK::TypeBoundsChecker<unsigned long, unsigned short, true, false, false>::is_within_range(unsigned short) Line | Count | Source | 76 | 4.13k | { | 77 | 4.13k | return true; | 78 | 4.13k | } |
|
79 | | }; |
80 | | |
81 | | template<typename Destination, typename Source> |
82 | | struct TypeBoundsChecker<Destination, Source, true, true, true> { |
83 | | static constexpr bool is_within_range(Source) |
84 | 23.0M | { |
85 | 23.0M | return true; |
86 | 23.0M | } AK::TypeBoundsChecker<int, int, true, true, true>::is_within_range(int) Line | Count | Source | 84 | 20.6M | { | 85 | 20.6M | return true; | 86 | 20.6M | } |
Unexecuted instantiation: AK::TypeBoundsChecker<long, long, true, true, true>::is_within_range(long) AK::TypeBoundsChecker<long, int, true, true, true>::is_within_range(int) Line | Count | Source | 84 | 2.42M | { | 85 | 2.42M | return true; | 86 | 2.42M | } |
Unexecuted instantiation: AK::TypeBoundsChecker<int, float, true, true, true>::is_within_range(float) Unexecuted instantiation: AK::TypeBoundsChecker<long, float, true, true, true>::is_within_range(float) Unexecuted instantiation: AK::TypeBoundsChecker<long, double, true, true, true>::is_within_range(double) |
87 | | }; |
88 | | |
89 | | template<typename Destination, typename Source> |
90 | | struct TypeBoundsChecker<Destination, Source, true, false, true> { |
91 | | static constexpr bool is_within_range(Source value) |
92 | 13 | { |
93 | 13 | return value >= 0; |
94 | 13 | } AK::TypeBoundsChecker<unsigned int, int, true, false, true>::is_within_range(int) Line | Count | Source | 92 | 13 | { | 93 | 13 | return value >= 0; | 94 | 13 | } |
Unexecuted instantiation: AK::TypeBoundsChecker<unsigned long, long, true, false, true>::is_within_range(long) Unexecuted instantiation: AK::TypeBoundsChecker<unsigned long, int, true, false, true>::is_within_range(int) Unexecuted instantiation: AK::TypeBoundsChecker<unsigned int, float, true, false, true>::is_within_range(float) Unexecuted instantiation: AK::TypeBoundsChecker<unsigned long, float, true, false, true>::is_within_range(float) Unexecuted instantiation: AK::TypeBoundsChecker<unsigned long, double, true, false, true>::is_within_range(double) |
95 | | }; |
96 | | |
97 | | template<typename Destination, typename Source> |
98 | | struct TypeBoundsChecker<Destination, Source, true, true, false> { |
99 | | static constexpr bool is_within_range(Source value) |
100 | 0 | { |
101 | 0 | if (sizeof(Destination) > sizeof(Source)) |
102 | 0 | return true; |
103 | 0 | return value <= static_cast<Source>(NumericLimits<Destination>::max()); |
104 | 0 | } |
105 | | }; |
106 | | |
107 | | template<typename Destination, typename Source> |
108 | | [[nodiscard]] constexpr bool is_within_range(Source value) |
109 | 8.06G | { |
110 | 8.06G | return TypeBoundsChecker<Destination, Source>::is_within_range(value); |
111 | 8.06G | } bool AK::is_within_range<unsigned long, unsigned long>(unsigned long) Line | Count | Source | 109 | 8.03G | { | 110 | 8.03G | return TypeBoundsChecker<Destination, Source>::is_within_range(value); | 111 | 8.03G | } |
bool AK::is_within_range<unsigned long, unsigned int>(unsigned int) Line | Count | Source | 109 | 63 | { | 110 | 63 | return TypeBoundsChecker<Destination, Source>::is_within_range(value); | 111 | 63 | } |
bool AK::is_within_range<unsigned int, int>(int) Line | Count | Source | 109 | 13 | { | 110 | 13 | return TypeBoundsChecker<Destination, Source>::is_within_range(value); | 111 | 13 | } |
bool AK::is_within_range<unsigned int, unsigned long>(unsigned long) Line | Count | Source | 109 | 77 | { | 110 | 77 | return TypeBoundsChecker<Destination, Source>::is_within_range(value); | 111 | 77 | } |
bool AK::is_within_range<unsigned int, unsigned int>(unsigned int) Line | Count | Source | 109 | 75 | { | 110 | 75 | return TypeBoundsChecker<Destination, Source>::is_within_range(value); | 111 | 75 | } |
bool AK::is_within_range<int, int>(int) Line | Count | Source | 109 | 20.6M | { | 110 | 20.6M | return TypeBoundsChecker<Destination, Source>::is_within_range(value); | 111 | 20.6M | } |
bool AK::is_within_range<unsigned int, unsigned char>(unsigned char) Line | Count | Source | 109 | 4.66M | { | 110 | 4.66M | return TypeBoundsChecker<Destination, Source>::is_within_range(value); | 111 | 4.66M | } |
Unexecuted instantiation: bool AK::is_within_range<int, unsigned long>(unsigned long) Unexecuted instantiation: bool AK::is_within_range<int, long>(long) Unexecuted instantiation: bool AK::is_within_range<long, unsigned long>(unsigned long) Unexecuted instantiation: bool AK::is_within_range<long, long>(long) Unexecuted instantiation: bool AK::is_within_range<unsigned int, long>(long) Unexecuted instantiation: bool AK::is_within_range<unsigned long, long>(long) Unexecuted instantiation: bool AK::is_within_range<signed char, long>(long) Unexecuted instantiation: bool AK::is_within_range<signed char, unsigned long>(unsigned long) Unexecuted instantiation: bool AK::is_within_range<unsigned char, long>(long) Unexecuted instantiation: bool AK::is_within_range<unsigned char, unsigned long>(unsigned long) Unexecuted instantiation: bool AK::is_within_range<short, long>(long) Unexecuted instantiation: bool AK::is_within_range<short, unsigned long>(unsigned long) Unexecuted instantiation: bool AK::is_within_range<unsigned short, long>(long) Unexecuted instantiation: bool AK::is_within_range<unsigned short, unsigned long>(unsigned long) Unexecuted instantiation: bool AK::is_within_range<unsigned long, int>(int) Unexecuted instantiation: bool AK::is_within_range<unsigned int, double>(double) Unexecuted instantiation: bool AK::is_within_range<int, double>(double) Unexecuted instantiation: bool AK::is_within_range<unsigned char, double>(double) Unexecuted instantiation: bool AK::is_within_range<unsigned short, double>(double) bool AK::is_within_range<long, int>(int) Line | Count | Source | 109 | 2.42M | { | 110 | 2.42M | return TypeBoundsChecker<Destination, Source>::is_within_range(value); | 111 | 2.42M | } |
bool AK::is_within_range<unsigned long, unsigned short>(unsigned short) Line | Count | Source | 109 | 4.13k | { | 110 | 4.13k | return TypeBoundsChecker<Destination, Source>::is_within_range(value); | 111 | 4.13k | } |
Unexecuted instantiation: bool AK::is_within_range<int, float>(float) Unexecuted instantiation: bool AK::is_within_range<unsigned int, float>(float) Unexecuted instantiation: bool AK::is_within_range<long, float>(float) Unexecuted instantiation: bool AK::is_within_range<unsigned long, float>(float) Unexecuted instantiation: bool AK::is_within_range<long, double>(double) Unexecuted instantiation: bool AK::is_within_range<unsigned long, double>(double) |
112 | | |
113 | | template<Integral T> |
114 | | class Checked { |
115 | | public: |
116 | 0 | constexpr Checked() = default; Unexecuted instantiation: AK::Checked<unsigned int>::Checked() Unexecuted instantiation: AK::Checked<int>::Checked() |
117 | | |
118 | | explicit constexpr Checked(T value) |
119 | 76.8M | : m_value(value) |
120 | 76.8M | { |
121 | 76.8M | } AK::Checked<int>::Checked(int) Line | Count | Source | 119 | 55.6M | : m_value(value) | 120 | 55.6M | { | 121 | 55.6M | } |
AK::Checked<long>::Checked(long) Line | Count | Source | 119 | 21.1M | : m_value(value) | 120 | 21.1M | { | 121 | 21.1M | } |
Unexecuted instantiation: AK::Checked<unsigned int>::Checked(unsigned int) AK::Checked<unsigned long>::Checked(unsigned long) Line | Count | Source | 119 | 2.31k | : m_value(value) | 120 | 2.31k | { | 121 | 2.31k | } |
|
122 | | |
123 | | template<Integral U> |
124 | | constexpr Checked(U value) |
125 | 8.06G | { |
126 | 8.06G | m_overflow = !is_within_range<T>(value); |
127 | 8.06G | m_value = value; |
128 | 8.06G | } _ZN2AK7CheckedImEC2ITkNS_8Concepts8IntegralEmEET_ Line | Count | Source | 125 | 8.03G | { | 126 | 8.03G | m_overflow = !is_within_range<T>(value); | 127 | 8.03G | m_value = value; | 128 | 8.03G | } |
_ZN2AK7CheckedImEC2ITkNS_8Concepts8IntegralEjEET_ Line | Count | Source | 125 | 63 | { | 126 | 63 | m_overflow = !is_within_range<T>(value); | 127 | 63 | m_value = value; | 128 | 63 | } |
_ZN2AK7CheckedIjEC2ITkNS_8Concepts8IntegralEiEET_ Line | Count | Source | 125 | 13 | { | 126 | 13 | m_overflow = !is_within_range<T>(value); | 127 | 13 | m_value = value; | 128 | 13 | } |
_ZN2AK7CheckedIjEC2ITkNS_8Concepts8IntegralEmEET_ Line | Count | Source | 125 | 77 | { | 126 | 77 | m_overflow = !is_within_range<T>(value); | 127 | 77 | m_value = value; | 128 | 77 | } |
_ZN2AK7CheckedIjEC2ITkNS_8Concepts8IntegralEjEET_ Line | Count | Source | 125 | 75 | { | 126 | 75 | m_overflow = !is_within_range<T>(value); | 127 | 75 | m_value = value; | 128 | 75 | } |
_ZN2AK7CheckedIiEC2ITkNS_8Concepts8IntegralEiEET_ Line | Count | Source | 125 | 20.6M | { | 126 | 20.6M | m_overflow = !is_within_range<T>(value); | 127 | 20.6M | m_value = value; | 128 | 20.6M | } |
_ZN2AK7CheckedIjEC2ITkNS_8Concepts8IntegralEhEET_ Line | Count | Source | 125 | 4.66M | { | 126 | 4.66M | m_overflow = !is_within_range<T>(value); | 127 | 4.66M | m_value = value; | 128 | 4.66M | } |
Unexecuted instantiation: _ZN2AK7CheckedImEC2ITkNS_8Concepts8IntegralEiEET_ Unexecuted instantiation: _ZN2AK7CheckedIlEC2ITkNS_8Concepts8IntegralElEET_ _ZN2AK7CheckedIlEC2ITkNS_8Concepts8IntegralEiEET_ Line | Count | Source | 125 | 2.42M | { | 126 | 2.42M | m_overflow = !is_within_range<T>(value); | 127 | 2.42M | m_value = value; | 128 | 2.42M | } |
_ZN2AK7CheckedImEC2ITkNS_8Concepts8IntegralEtEET_ Line | Count | Source | 125 | 4.13k | { | 126 | 4.13k | m_overflow = !is_within_range<T>(value); | 127 | 4.13k | m_value = value; | 128 | 4.13k | } |
|
129 | | |
130 | | constexpr Checked(Checked const&) = default; |
131 | | |
132 | | constexpr Checked(Checked&& other) |
133 | 0 | : m_value(exchange(other.m_value, 0)) |
134 | 0 | , m_overflow(exchange(other.m_overflow, false)) |
135 | 0 | { |
136 | 0 | } |
137 | | |
138 | | template<typename U> |
139 | | constexpr Checked& operator=(U value) |
140 | 0 | { |
141 | 0 | *this = Checked(value); |
142 | 0 | return *this; |
143 | 0 | } Unexecuted instantiation: AK::Checked<unsigned long>& AK::Checked<unsigned long>::operator=<unsigned int>(unsigned int) Unexecuted instantiation: AK::Checked<unsigned long>& AK::Checked<unsigned long>::operator=<int>(int) Unexecuted instantiation: AK::Checked<unsigned int>& AK::Checked<unsigned int>::operator=<unsigned long>(unsigned long) Unexecuted instantiation: AK::Checked<int>& AK::Checked<int>::operator=<int>(int) |
144 | | |
145 | | constexpr Checked& operator=(Checked const& other) = default; |
146 | | |
147 | | constexpr Checked& operator=(Checked&& other) |
148 | 0 | { |
149 | 0 | m_value = exchange(other.m_value, 0); |
150 | 0 | m_overflow = exchange(other.m_overflow, false); |
151 | 0 | return *this; |
152 | 0 | } Unexecuted instantiation: AK::Checked<unsigned int>::operator=(AK::Checked<unsigned int>&&) Unexecuted instantiation: AK::Checked<unsigned long>::operator=(AK::Checked<unsigned long>&&) Unexecuted instantiation: AK::Checked<int>::operator=(AK::Checked<int>&&) |
153 | | |
154 | | [[nodiscard]] constexpr bool has_overflow() const |
155 | 5.00G | { |
156 | 5.00G | return m_overflow; |
157 | 5.00G | } AK::Checked<unsigned long>::has_overflow() const Line | Count | Source | 155 | 4.98G | { | 156 | 4.98G | return m_overflow; | 157 | 4.98G | } |
AK::Checked<long>::has_overflow() const Line | Count | Source | 155 | 2.57k | { | 156 | 2.57k | return m_overflow; | 157 | 2.57k | } |
AK::Checked<int>::has_overflow() const Line | Count | Source | 155 | 13.5M | { | 156 | 13.5M | return m_overflow; | 157 | 13.5M | } |
AK::Checked<unsigned int>::has_overflow() const Line | Count | Source | 155 | 4.66M | { | 156 | 4.66M | return m_overflow; | 157 | 4.66M | } |
|
158 | | |
159 | | ALWAYS_INLINE constexpr bool operator!() const |
160 | 0 | { |
161 | 0 | VERIFY(!m_overflow); |
162 | 0 | return !m_value; |
163 | 0 | } |
164 | | |
165 | | ALWAYS_INLINE constexpr T value() const |
166 | 8.14G | { |
167 | 8.14G | VERIFY(!m_overflow); |
168 | 8.14G | return m_value; |
169 | 8.14G | } AK::Checked<unsigned long>::value() const Line | Count | Source | 166 | 8.03G | { | 167 | 8.03G | VERIFY(!m_overflow); | 168 | 8.03G | return m_value; | 169 | 8.03G | } |
AK::Checked<long>::value() const Line | Count | Source | 166 | 23.6M | { | 167 | 23.6M | VERIFY(!m_overflow); | 168 | 23.6M | return m_value; | 169 | 23.6M | } |
AK::Checked<int>::value() const Line | Count | Source | 166 | 76.3M | { | 167 | 76.3M | VERIFY(!m_overflow); | 168 | 76.3M | return m_value; | 169 | 76.3M | } |
AK::Checked<unsigned int>::value() const Line | Count | Source | 166 | 4.32M | { | 167 | 4.32M | VERIFY(!m_overflow); | 168 | 4.32M | return m_value; | 169 | 4.32M | } |
|
170 | | |
171 | | ALWAYS_INLINE constexpr T value_unchecked() const |
172 | 0 | { |
173 | 0 | return m_value; |
174 | 0 | } Unexecuted instantiation: AK::Checked<long>::value_unchecked() const Unexecuted instantiation: AK::Checked<unsigned long>::value_unchecked() const |
175 | | |
176 | | constexpr void add(T other) |
177 | 2.02G | { |
178 | 2.02G | m_overflow |= __builtin_add_overflow(m_value, other, &m_value); |
179 | 2.02G | } AK::Checked<long>::add(long) Line | Count | Source | 177 | 21.1M | { | 178 | 21.1M | m_overflow |= __builtin_add_overflow(m_value, other, &m_value); | 179 | 21.1M | } |
AK::Checked<unsigned long>::add(unsigned long) Line | Count | Source | 177 | 1.93G | { | 178 | 1.93G | m_overflow |= __builtin_add_overflow(m_value, other, &m_value); | 179 | 1.93G | } |
AK::Checked<unsigned int>::add(unsigned int) Line | Count | Source | 177 | 410 | { | 178 | 410 | m_overflow |= __builtin_add_overflow(m_value, other, &m_value); | 179 | 410 | } |
AK::Checked<int>::add(int) Line | Count | Source | 177 | 62.4M | { | 178 | 62.4M | m_overflow |= __builtin_add_overflow(m_value, other, &m_value); | 179 | 62.4M | } |
|
180 | | |
181 | | constexpr void sub(T other) |
182 | 0 | { |
183 | 0 | m_overflow |= __builtin_sub_overflow(m_value, other, &m_value); |
184 | 0 | } Unexecuted instantiation: AK::Checked<long>::sub(long) Unexecuted instantiation: AK::Checked<unsigned int>::sub(unsigned int) Unexecuted instantiation: AK::Checked<unsigned long>::sub(unsigned long) Unexecuted instantiation: AK::Checked<int>::sub(int) |
185 | | |
186 | | constexpr void mul(T other) |
187 | 3.14G | { |
188 | 3.14G | m_overflow |= __builtin_mul_overflow(m_value, other, &m_value); |
189 | 3.14G | } AK::Checked<unsigned long>::mul(unsigned long) Line | Count | Source | 187 | 3.04G | { | 188 | 3.04G | m_overflow |= __builtin_mul_overflow(m_value, other, &m_value); | 189 | 3.04G | } |
AK::Checked<long>::mul(long) Line | Count | Source | 187 | 21.1M | { | 188 | 21.1M | m_overflow |= __builtin_mul_overflow(m_value, other, &m_value); | 189 | 21.1M | } |
AK::Checked<int>::mul(int) Line | Count | Source | 187 | 69.1M | { | 188 | 69.1M | m_overflow |= __builtin_mul_overflow(m_value, other, &m_value); | 189 | 69.1M | } |
AK::Checked<unsigned int>::mul(unsigned int) Line | Count | Source | 187 | 4.66M | { | 188 | 4.66M | m_overflow |= __builtin_mul_overflow(m_value, other, &m_value); | 189 | 4.66M | } |
|
190 | | |
191 | | constexpr void div(T other) |
192 | 6.75M | { |
193 | 6.75M | if constexpr (IsSigned<T>) { |
194 | | // Ensure that the resulting value won't be out of range, this can only happen when dividing by -1. |
195 | 6.75M | if (other == -1 && m_value == NumericLimits<T>::min()) { |
196 | 0 | m_overflow = true; |
197 | 0 | return; |
198 | 0 | } |
199 | 6.75M | } |
200 | 6.75M | if (other == 0) { |
201 | 0 | m_overflow = true; |
202 | 0 | return; |
203 | 0 | } |
204 | 6.75M | m_value /= other; |
205 | 6.75M | } AK::Checked<int>::div(int) Line | Count | Source | 192 | 6.75M | { | 193 | 6.75M | if constexpr (IsSigned<T>) { | 194 | | // Ensure that the resulting value won't be out of range, this can only happen when dividing by -1. | 195 | 6.75M | if (other == -1 && m_value == NumericLimits<T>::min()) { | 196 | 0 | m_overflow = true; | 197 | 0 | return; | 198 | 0 | } | 199 | 6.75M | } | 200 | 6.75M | if (other == 0) { | 201 | 0 | m_overflow = true; | 202 | 0 | return; | 203 | 0 | } | 204 | 6.75M | m_value /= other; | 205 | 6.75M | } |
Unexecuted instantiation: AK::Checked<unsigned int>::div(unsigned int) Unexecuted instantiation: AK::Checked<long>::div(long) Unexecuted instantiation: AK::Checked<unsigned long>::div(unsigned long) |
206 | | |
207 | | constexpr void mod(T other) |
208 | 0 | { |
209 | 0 | auto initial = m_value; |
210 | 0 | div(other); |
211 | 0 | m_value *= other; |
212 | 0 | m_value = initial - m_value; |
213 | 0 | } Unexecuted instantiation: AK::Checked<unsigned int>::mod(unsigned int) Unexecuted instantiation: AK::Checked<long>::mod(long) Unexecuted instantiation: AK::Checked<unsigned long>::mod(unsigned long) |
214 | | |
215 | | constexpr void saturating_sub(T other) |
216 | 0 | { |
217 | 0 | sub(other); |
218 | | // Depending on whether other was positive or negative, we have to saturate to min or max. |
219 | 0 | if (m_overflow && other <= 0) |
220 | 0 | m_value = NumericLimits<T>::max(); |
221 | 0 | else if (m_overflow) |
222 | 0 | m_value = NumericLimits<T>::min(); |
223 | 0 | m_overflow = false; |
224 | 0 | } Unexecuted instantiation: AK::Checked<long>::saturating_sub(long) Unexecuted instantiation: AK::Checked<int>::saturating_sub(int) |
225 | | |
226 | | constexpr void saturating_add(T other) |
227 | 76.8M | { |
228 | 76.8M | add(other); |
229 | | // Depending on whether other was positive or negative, we have to saturate to max or min. |
230 | 76.8M | if (m_overflow && other >= 0) |
231 | 2.60M | m_value = NumericLimits<T>::max(); |
232 | 74.2M | else if (m_overflow) |
233 | 6.61M | m_value = NumericLimits<T>::min(); |
234 | 76.8M | m_overflow = false; |
235 | 76.8M | } AK::Checked<long>::saturating_add(long) Line | Count | Source | 227 | 21.1M | { | 228 | 21.1M | add(other); | 229 | | // Depending on whether other was positive or negative, we have to saturate to max or min. | 230 | 21.1M | if (m_overflow && other >= 0) | 231 | 82.2k | m_value = NumericLimits<T>::max(); | 232 | 21.1M | else if (m_overflow) | 233 | 89.3k | m_value = NumericLimits<T>::min(); | 234 | 21.1M | m_overflow = false; | 235 | 21.1M | } |
AK::Checked<int>::saturating_add(int) Line | Count | Source | 227 | 55.6M | { | 228 | 55.6M | add(other); | 229 | | // Depending on whether other was positive or negative, we have to saturate to max or min. | 230 | 55.6M | if (m_overflow && other >= 0) | 231 | 2.52M | m_value = NumericLimits<T>::max(); | 232 | 53.1M | else if (m_overflow) | 233 | 6.52M | m_value = NumericLimits<T>::min(); | 234 | 55.6M | m_overflow = false; | 235 | 55.6M | } |
Unexecuted instantiation: AK::Checked<unsigned long>::saturating_add(unsigned long) |
236 | | |
237 | | constexpr void saturating_mul(T other) |
238 | 76.8M | { |
239 | | // Figure out if the result is positive, negative or zero beforehand. |
240 | 76.8M | auto either_is_zero = this->m_value == 0 || other == 0; |
241 | 76.8M | auto result_is_positive = (this->m_value > 0) == (other > 0); |
242 | | |
243 | 76.8M | mul(other); |
244 | 76.8M | if (m_overflow) { |
245 | 8.40M | if (either_is_zero) |
246 | 0 | m_value = 0; |
247 | 8.40M | else if (result_is_positive) |
248 | 2.34M | m_value = NumericLimits<T>::max(); |
249 | 6.05M | else |
250 | 6.05M | m_value = NumericLimits<T>::min(); |
251 | 8.40M | } |
252 | 76.8M | m_overflow = false; |
253 | 76.8M | } AK::Checked<long>::saturating_mul(long) Line | Count | Source | 238 | 21.1M | { | 239 | | // Figure out if the result is positive, negative or zero beforehand. | 240 | 21.1M | auto either_is_zero = this->m_value == 0 || other == 0; | 241 | 21.1M | auto result_is_positive = (this->m_value > 0) == (other > 0); | 242 | | | 243 | 21.1M | mul(other); | 244 | 21.1M | if (m_overflow) { | 245 | 166k | if (either_is_zero) | 246 | 0 | m_value = 0; | 247 | 166k | else if (result_is_positive) | 248 | 165k | m_value = NumericLimits<T>::max(); | 249 | 1.49k | else | 250 | 1.49k | m_value = NumericLimits<T>::min(); | 251 | 166k | } | 252 | 21.1M | m_overflow = false; | 253 | 21.1M | } |
AK::Checked<int>::saturating_mul(int) Line | Count | Source | 238 | 55.6M | { | 239 | | // Figure out if the result is positive, negative or zero beforehand. | 240 | 55.6M | auto either_is_zero = this->m_value == 0 || other == 0; | 241 | 55.6M | auto result_is_positive = (this->m_value > 0) == (other > 0); | 242 | | | 243 | 55.6M | mul(other); | 244 | 55.6M | if (m_overflow) { | 245 | 8.23M | if (either_is_zero) | 246 | 0 | m_value = 0; | 247 | 8.23M | else if (result_is_positive) | 248 | 2.18M | m_value = NumericLimits<T>::max(); | 249 | 6.05M | else | 250 | 6.05M | m_value = NumericLimits<T>::min(); | 251 | 8.23M | } | 252 | 55.6M | m_overflow = false; | 253 | 55.6M | } |
|
254 | | |
255 | | constexpr Checked& operator+=(Checked const& other) |
256 | 4.82k | { |
257 | 4.82k | m_overflow |= other.m_overflow; |
258 | 4.82k | add(other.value()); |
259 | 4.82k | return *this; |
260 | 4.82k | } AK::Checked<unsigned int>::operator+=(AK::Checked<unsigned int> const&) Line | Count | Source | 256 | 75 | { | 257 | 75 | m_overflow |= other.m_overflow; | 258 | 75 | add(other.value()); | 259 | 75 | return *this; | 260 | 75 | } |
AK::Checked<unsigned long>::operator+=(AK::Checked<unsigned long> const&) Line | Count | Source | 256 | 4.75k | { | 257 | 4.75k | m_overflow |= other.m_overflow; | 258 | 4.75k | add(other.value()); | 259 | 4.75k | return *this; | 260 | 4.75k | } |
|
261 | | |
262 | | constexpr Checked& operator+=(T other) |
263 | 1.94G | { |
264 | 1.94G | add(other); |
265 | 1.94G | return *this; |
266 | 1.94G | } AK::Checked<long>::operator+=(long) Line | Count | Source | 263 | 2.57k | { | 264 | 2.57k | add(other); | 265 | 2.57k | return *this; | 266 | 2.57k | } |
AK::Checked<unsigned long>::operator+=(unsigned long) Line | Count | Source | 263 | 1.93G | { | 264 | 1.93G | add(other); | 265 | 1.93G | return *this; | 266 | 1.93G | } |
AK::Checked<unsigned int>::operator+=(unsigned int) Line | Count | Source | 263 | 335 | { | 264 | 335 | add(other); | 265 | 335 | return *this; | 266 | 335 | } |
AK::Checked<int>::operator+=(int) Line | Count | Source | 263 | 6.75M | { | 264 | 6.75M | add(other); | 265 | 6.75M | return *this; | 266 | 6.75M | } |
|
267 | | |
268 | | constexpr Checked& operator-=(Checked const& other) |
269 | | { |
270 | | m_overflow |= other.m_overflow; |
271 | | sub(other.value()); |
272 | | return *this; |
273 | | } |
274 | | |
275 | | constexpr Checked& operator-=(T other) |
276 | 0 | { |
277 | 0 | sub(other); |
278 | 0 | return *this; |
279 | 0 | } Unexecuted instantiation: AK::Checked<long>::operator-=(long) Unexecuted instantiation: AK::Checked<unsigned int>::operator-=(unsigned int) Unexecuted instantiation: AK::Checked<unsigned long>::operator-=(unsigned long) |
280 | | |
281 | | constexpr Checked& operator*=(Checked const& other) |
282 | | { |
283 | | m_overflow |= other.m_overflow; |
284 | | mul(other.value()); |
285 | | return *this; |
286 | | } |
287 | | |
288 | | constexpr Checked& operator*=(T other) |
289 | 18.4M | { |
290 | 18.4M | mul(other); |
291 | 18.4M | return *this; |
292 | 18.4M | } Unexecuted instantiation: AK::Checked<long>::operator*=(long) AK::Checked<unsigned long>::operator*=(unsigned long) Line | Count | Source | 289 | 231k | { | 290 | 231k | mul(other); | 291 | 231k | return *this; | 292 | 231k | } |
AK::Checked<unsigned int>::operator*=(unsigned int) Line | Count | Source | 289 | 4.66M | { | 290 | 4.66M | mul(other); | 291 | 4.66M | return *this; | 292 | 4.66M | } |
AK::Checked<int>::operator*=(int) Line | Count | Source | 289 | 13.5M | { | 290 | 13.5M | mul(other); | 291 | 13.5M | return *this; | 292 | 13.5M | } |
|
293 | | |
294 | | constexpr Checked& operator/=(Checked const& other) |
295 | | { |
296 | | m_overflow |= other.m_overflow; |
297 | | div(other.value()); |
298 | | return *this; |
299 | | } |
300 | | |
301 | | constexpr Checked& operator/=(T other) |
302 | 6.75M | { |
303 | 6.75M | div(other); |
304 | 6.75M | return *this; |
305 | 6.75M | } AK::Checked<int>::operator/=(int) Line | Count | Source | 302 | 6.75M | { | 303 | 6.75M | div(other); | 304 | 6.75M | return *this; | 305 | 6.75M | } |
Unexecuted instantiation: AK::Checked<unsigned int>::operator/=(unsigned int) Unexecuted instantiation: AK::Checked<long>::operator/=(long) Unexecuted instantiation: AK::Checked<unsigned long>::operator/=(unsigned long) |
306 | | |
307 | | constexpr Checked& operator%=(Checked const& other) |
308 | | { |
309 | | m_overflow |= other.m_overflow; |
310 | | mod(other.value()); |
311 | | return *this; |
312 | | } |
313 | | |
314 | | constexpr Checked& operator%=(T other) |
315 | | { |
316 | | mod(other); |
317 | | return *this; |
318 | | } |
319 | | |
320 | | constexpr Checked& operator++() |
321 | 0 | { |
322 | 0 | add(1); |
323 | 0 | return *this; |
324 | 0 | } |
325 | | |
326 | | constexpr Checked operator++(int) |
327 | 0 | { |
328 | 0 | Checked old { *this }; |
329 | 0 | add(1); |
330 | 0 | return old; |
331 | 0 | } Unexecuted instantiation: AK::Checked<long>::operator++(int) Unexecuted instantiation: AK::Checked<unsigned int>::operator++(int) Unexecuted instantiation: AK::Checked<unsigned long>::operator++(int) |
332 | | |
333 | | constexpr Checked& operator--() |
334 | | { |
335 | | sub(1); |
336 | | return *this; |
337 | | } |
338 | | |
339 | | constexpr Checked operator--(int) |
340 | | { |
341 | | Checked old { *this }; |
342 | | sub(1); |
343 | | return old; |
344 | | } |
345 | | |
346 | | template<typename U, typename V> |
347 | | [[nodiscard]] static constexpr bool addition_would_overflow(U u, V v) |
348 | 7.77G | { |
349 | | #if __has_builtin(__builtin_add_overflow_p) |
350 | | return __builtin_add_overflow_p(u, v, (T)0); |
351 | | #elif __has_builtin(__builtin_add_overflow) |
352 | | T result; |
353 | 7.77G | return __builtin_add_overflow(u, v, &result); |
354 | | #else |
355 | | Checked checked; |
356 | | checked = u; |
357 | | checked += v; |
358 | | return checked.has_overflow(); |
359 | | #endif |
360 | 7.77G | } bool AK::Checked<unsigned long>::addition_would_overflow<unsigned long, unsigned long>(unsigned long, unsigned long) Line | Count | Source | 348 | 3.20G | { | 349 | | #if __has_builtin(__builtin_add_overflow_p) | 350 | | return __builtin_add_overflow_p(u, v, (T)0); | 351 | | #elif __has_builtin(__builtin_add_overflow) | 352 | | T result; | 353 | 3.20G | return __builtin_add_overflow(u, v, &result); | 354 | | #else | 355 | | Checked checked; | 356 | | checked = u; | 357 | | checked += v; | 358 | | return checked.has_overflow(); | 359 | | #endif | 360 | 3.20G | } |
bool AK::Checked<unsigned int>::addition_would_overflow<unsigned int, int>(unsigned int, int) Line | Count | Source | 348 | 4.55G | { | 349 | | #if __has_builtin(__builtin_add_overflow_p) | 350 | | return __builtin_add_overflow_p(u, v, (T)0); | 351 | | #elif __has_builtin(__builtin_add_overflow) | 352 | | T result; | 353 | 4.55G | return __builtin_add_overflow(u, v, &result); | 354 | | #else | 355 | | Checked checked; | 356 | | checked = u; | 357 | | checked += v; | 358 | | return checked.has_overflow(); | 359 | | #endif | 360 | 4.55G | } |
bool AK::Checked<unsigned int>::addition_would_overflow<unsigned int, unsigned int>(unsigned int, unsigned int) Line | Count | Source | 348 | 158k | { | 349 | | #if __has_builtin(__builtin_add_overflow_p) | 350 | | return __builtin_add_overflow_p(u, v, (T)0); | 351 | | #elif __has_builtin(__builtin_add_overflow) | 352 | | T result; | 353 | 158k | return __builtin_add_overflow(u, v, &result); | 354 | | #else | 355 | | Checked checked; | 356 | | checked = u; | 357 | | checked += v; | 358 | | return checked.has_overflow(); | 359 | | #endif | 360 | 158k | } |
Unexecuted instantiation: bool AK::Checked<long>::addition_would_overflow<long, long>(long, long) Unexecuted instantiation: bool AK::Checked<int>::addition_would_overflow<int, int>(int, int) bool AK::Checked<short>::addition_would_overflow<int, unsigned short>(int, unsigned short) Line | Count | Source | 348 | 4.97M | { | 349 | | #if __has_builtin(__builtin_add_overflow_p) | 350 | | return __builtin_add_overflow_p(u, v, (T)0); | 351 | | #elif __has_builtin(__builtin_add_overflow) | 352 | | T result; | 353 | 4.97M | return __builtin_add_overflow(u, v, &result); | 354 | | #else | 355 | | Checked checked; | 356 | | checked = u; | 357 | | checked += v; | 358 | | return checked.has_overflow(); | 359 | | #endif | 360 | 4.97M | } |
bool AK::Checked<short>::addition_would_overflow<short, int>(short, int) Line | Count | Source | 348 | 7.37M | { | 349 | | #if __has_builtin(__builtin_add_overflow_p) | 350 | | return __builtin_add_overflow_p(u, v, (T)0); | 351 | | #elif __has_builtin(__builtin_add_overflow) | 352 | | T result; | 353 | 7.37M | return __builtin_add_overflow(u, v, &result); | 354 | | #else | 355 | | Checked checked; | 356 | | checked = u; | 357 | | checked += v; | 358 | | return checked.has_overflow(); | 359 | | #endif | 360 | 7.37M | } |
|
361 | | |
362 | | template<typename U, typename V> |
363 | | [[nodiscard]] static constexpr bool subtraction_would_overflow(U u, V v) |
364 | 0 | { |
365 | | #if __has_builtin(__builtin_sub_overflow_p) |
366 | | return __builtin_sub_overflow_p(u, v, (T)0); |
367 | | #elif __has_builtin(__builtin_sub_overflow) |
368 | | T result; |
369 | 0 | return __builtin_sub_overflow(u, v, &result); |
370 | | #else |
371 | | Checked checked; |
372 | | checked = u; |
373 | | checked -= v; |
374 | | return checked.has_overflow(); |
375 | | #endif |
376 | 0 | } |
377 | | |
378 | | template<typename U, typename V> |
379 | | static constexpr T saturating_add(U a, V b) |
380 | 0 | { |
381 | 0 | Checked checked { a }; |
382 | 0 | checked.saturating_add(b); |
383 | 0 | return checked.value(); |
384 | 0 | } Unexecuted instantiation: long AK::Checked<long>::saturating_add<long, int>(long, int) Unexecuted instantiation: int AK::Checked<int>::saturating_add<int, int>(int, int) |
385 | | |
386 | | template<typename U, typename V> |
387 | | static constexpr T saturating_sub(U a, V b) |
388 | 0 | { |
389 | 0 | Checked checked { a }; |
390 | 0 | checked.saturating_sub(b); |
391 | 0 | return checked.value(); |
392 | 0 | } |
393 | | |
394 | | template<typename U, typename V> |
395 | | static constexpr T saturating_mul(U a, V b) |
396 | 76.8M | { |
397 | 76.8M | Checked checked { a }; |
398 | 76.8M | checked.saturating_mul(b); |
399 | 76.8M | return checked.value(); |
400 | 76.8M | } long AK::Checked<long>::saturating_mul<long, long>(long, long) Line | Count | Source | 396 | 21.1M | { | 397 | 21.1M | Checked checked { a }; | 398 | 21.1M | checked.saturating_mul(b); | 399 | 21.1M | return checked.value(); | 400 | 21.1M | } |
int AK::Checked<int>::saturating_mul<int, int>(int, int) Line | Count | Source | 396 | 55.6M | { | 397 | 55.6M | Checked checked { a }; | 398 | 55.6M | checked.saturating_mul(b); | 399 | 55.6M | return checked.value(); | 400 | 55.6M | } |
|
401 | | |
402 | | template<typename U, typename V> |
403 | | [[nodiscard]] static constexpr bool multiplication_would_overflow(U u, V v) |
404 | 449k | { |
405 | | #if __has_builtin(__builtin_mul_overflow_p) |
406 | | return __builtin_mul_overflow_p(u, v, (T)0); |
407 | | #elif __has_builtin(__builtin_mul_overflow) |
408 | | T result; |
409 | 449k | return __builtin_mul_overflow(u, v, &result); |
410 | | #else |
411 | | Checked checked; |
412 | | checked = u; |
413 | | checked *= v; |
414 | | return checked.has_overflow(); |
415 | | #endif |
416 | 449k | } bool AK::Checked<unsigned long>::multiplication_would_overflow<unsigned long, int>(unsigned long, int) Line | Count | Source | 404 | 449k | { | 405 | | #if __has_builtin(__builtin_mul_overflow_p) | 406 | | return __builtin_mul_overflow_p(u, v, (T)0); | 407 | | #elif __has_builtin(__builtin_mul_overflow) | 408 | | T result; | 409 | 449k | return __builtin_mul_overflow(u, v, &result); | 410 | | #else | 411 | | Checked checked; | 412 | | checked = u; | 413 | | checked *= v; | 414 | | return checked.has_overflow(); | 415 | | #endif | 416 | 449k | } |
Unexecuted instantiation: bool AK::Checked<unsigned int>::multiplication_would_overflow<unsigned long, unsigned long>(unsigned long, unsigned long) Unexecuted instantiation: bool AK::Checked<int>::multiplication_would_overflow<int, int>(int, int) Unexecuted instantiation: bool AK::Checked<unsigned int>::multiplication_would_overflow<unsigned int, unsigned long>(unsigned int, unsigned long) Unexecuted instantiation: bool AK::Checked<unsigned long>::multiplication_would_overflow<unsigned int, unsigned long>(unsigned int, unsigned long) |
417 | | |
418 | | template<typename U, typename V, typename X> |
419 | | [[nodiscard]] static constexpr bool multiplication_would_overflow(U u, V v, X x) |
420 | | { |
421 | | Checked checked; |
422 | | checked = u; |
423 | | checked *= v; |
424 | | checked *= x; |
425 | | return checked.has_overflow(); |
426 | | } |
427 | | |
428 | | private: |
429 | | T m_value {}; |
430 | | bool m_overflow { false }; |
431 | | }; |
432 | | |
433 | | template<typename T> |
434 | | constexpr Checked<T> operator+(Checked<T> const& a, Checked<T> const& b) |
435 | 1.54k | { |
436 | 1.54k | Checked<T> c { a }; |
437 | 1.54k | c.add(b.value()); |
438 | 1.54k | return c; |
439 | 1.54k | } AK::Checked<int> AK::operator+<int>(AK::Checked<int> const&, AK::Checked<int> const&) Line | Count | Source | 435 | 1.54k | { | 436 | 1.54k | Checked<T> c { a }; | 437 | 1.54k | c.add(b.value()); | 438 | 1.54k | return c; | 439 | 1.54k | } |
Unexecuted instantiation: AK::Checked<unsigned int> AK::operator+<unsigned int>(AK::Checked<unsigned int> const&, AK::Checked<unsigned int> const&) Unexecuted instantiation: AK::Checked<unsigned long> AK::operator+<unsigned long>(AK::Checked<unsigned long> const&, AK::Checked<unsigned long> const&) |
440 | | |
441 | | template<typename T> |
442 | | constexpr Checked<T> operator-(Checked<T> const& a, Checked<T> const& b) |
443 | 0 | { |
444 | 0 | Checked<T> c { a }; |
445 | 0 | c.sub(b.value()); |
446 | 0 | return c; |
447 | 0 | } Unexecuted instantiation: AK::Checked<unsigned int> AK::operator-<unsigned int>(AK::Checked<unsigned int> const&, AK::Checked<unsigned int> const&) Unexecuted instantiation: AK::Checked<unsigned long> AK::operator-<unsigned long>(AK::Checked<unsigned long> const&, AK::Checked<unsigned long> const&) |
448 | | |
449 | | template<typename T> |
450 | | constexpr Checked<T> operator*(Checked<T> const& a, Checked<T> const& b) |
451 | 3.04G | { |
452 | 3.04G | Checked<T> c { a }; |
453 | 3.04G | c.mul(b.value()); |
454 | 3.04G | return c; |
455 | 3.04G | } AK::Checked<unsigned long> AK::operator*<unsigned long>(AK::Checked<unsigned long> const&, AK::Checked<unsigned long> const&) Line | Count | Source | 451 | 3.04G | { | 452 | 3.04G | Checked<T> c { a }; | 453 | 3.04G | c.mul(b.value()); | 454 | 3.04G | return c; | 455 | 3.04G | } |
Unexecuted instantiation: AK::Checked<unsigned int> AK::operator*<unsigned int>(AK::Checked<unsigned int> const&, AK::Checked<unsigned int> const&) |
456 | | |
457 | | template<typename T> |
458 | | constexpr Checked<T> operator/(Checked<T> const& a, Checked<T> const& b) |
459 | | { |
460 | | Checked<T> c { a }; |
461 | | c.div(b.value()); |
462 | | return c; |
463 | | } |
464 | | |
465 | | template<typename T> |
466 | | constexpr Checked<T> operator%(Checked<T> const& a, Checked<T> const& b) |
467 | 0 | { |
468 | 0 | Checked<T> c { a }; |
469 | 0 | c.mod(b.value()); |
470 | 0 | return c; |
471 | 0 | } |
472 | | |
473 | | template<typename T> |
474 | | constexpr bool operator<(Checked<T> const& a, T b) |
475 | 1.36k | { |
476 | 1.36k | return a.value() < b; |
477 | 1.36k | } |
478 | | |
479 | | template<typename T> |
480 | | constexpr bool operator>(Checked<T> const& a, T b) |
481 | 5.27k | { |
482 | 5.27k | return a.value() > b; |
483 | 5.27k | } bool AK::operator><int>(AK::Checked<int> const&, int) Line | Count | Source | 481 | 1.13k | { | 482 | 1.13k | return a.value() > b; | 483 | 1.13k | } |
bool AK::operator><unsigned long>(AK::Checked<unsigned long> const&, unsigned long) Line | Count | Source | 481 | 4.13k | { | 482 | 4.13k | return a.value() > b; | 483 | 4.13k | } |
|
484 | | |
485 | | template<typename T> |
486 | | constexpr bool operator>=(Checked<T> const& a, T b) |
487 | 0 | { |
488 | 0 | return a.value() >= b; |
489 | 0 | } |
490 | | |
491 | | template<typename T> |
492 | | constexpr bool operator<=(Checked<T> const& a, T b) |
493 | 1.93G | { |
494 | 1.93G | return a.value() <= b; |
495 | 1.93G | } bool AK::operator<=<int>(AK::Checked<int> const&, int) Line | Count | Source | 493 | 1.23k | { | 494 | 1.23k | return a.value() <= b; | 495 | 1.23k | } |
bool AK::operator<=<unsigned long>(AK::Checked<unsigned long> const&, unsigned long) Line | Count | Source | 493 | 1.93G | { | 494 | 1.93G | return a.value() <= b; | 495 | 1.93G | } |
Unexecuted instantiation: bool AK::operator<=<unsigned int>(AK::Checked<unsigned int> const&, unsigned int) |
496 | | |
497 | | template<typename T> |
498 | | constexpr bool operator==(Checked<T> const& a, T b) |
499 | | { |
500 | | return a.value() == b; |
501 | | } |
502 | | |
503 | | template<typename T> |
504 | | constexpr bool operator!=(Checked<T> const& a, T b) |
505 | | { |
506 | | return a.value() != b; |
507 | | } |
508 | | |
509 | | template<typename T> |
510 | | constexpr bool operator<(T a, Checked<T> const& b) |
511 | 620 | { |
512 | 620 | return a < b.value(); |
513 | 620 | } bool AK::operator< <unsigned long>(unsigned long, AK::Checked<unsigned long> const&) Line | Count | Source | 511 | 620 | { | 512 | 620 | return a < b.value(); | 513 | 620 | } |
Unexecuted instantiation: bool AK::operator< <int>(int, AK::Checked<int> const&) Unexecuted instantiation: bool AK::operator< <unsigned int>(unsigned int, AK::Checked<unsigned int> const&) |
514 | | |
515 | | template<typename T> |
516 | | constexpr bool operator>(T a, Checked<T> const& b) |
517 | | { |
518 | | return a > b.value(); |
519 | | } |
520 | | |
521 | | template<typename T> |
522 | | constexpr bool operator>=(T a, Checked<T> const& b) |
523 | | { |
524 | | return a >= b.value(); |
525 | | } |
526 | | |
527 | | template<typename T> |
528 | | constexpr bool operator<=(T a, Checked<T> const& b) |
529 | | { |
530 | | return a <= b.value(); |
531 | | } |
532 | | |
533 | | template<typename T> |
534 | | constexpr bool operator==(T a, Checked<T> const& b) |
535 | | { |
536 | | return a == b.value(); |
537 | | } |
538 | | |
539 | | template<typename T> |
540 | | constexpr bool operator!=(T a, Checked<T> const& b) |
541 | | { |
542 | | return a != b.value(); |
543 | | } |
544 | | |
545 | | template<typename T> |
546 | | constexpr Checked<T> make_checked(T value) |
547 | 0 | { |
548 | 0 | return Checked<T>(value); |
549 | 0 | } |
550 | | |
551 | | } |
552 | | |
553 | | #if USING_AK_GLOBALLY |
554 | | using AK::Checked; |
555 | | using AK::make_checked; |
556 | | #endif |