• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "berberis/base/bit_util.h"
18 
19 #include <tuple>
20 
21 namespace berberis {
22 
23 namespace {
24 
25 static_assert(IsPowerOf2(sizeof(void*)));
26 static_assert(!IsPowerOf2(sizeof(void*) + 1));
27 
28 static_assert(IsPowerOf2(RawInt8(4)));
29 static_assert(IsPowerOf2(SatInt8(4)));
30 static_assert(IsPowerOf2(Int8(4)));
31 
32 static_assert(AlignUp(6, 4) == 8);
33 static_assert(AlignUp<4>(6) == 8);
34 static_assert(AlignUp<4>(RawInt8(6)) == RawInt8(8));
35 static_assert(AlignUp<4>(SatInt8(6)) == SatInt8(8));
36 static_assert(AlignUp<4>(Int8(6)) == Int8(8));
37 
38 static_assert(AlignDown(6, 4) == 4);
39 static_assert(AlignDown<4>(6) == 4);
40 static_assert(AlignDown<4>(RawInt8(6)) == RawInt8(4));
41 static_assert(AlignDown<4>(SatInt8(6)) == SatInt8(4));
42 static_assert(AlignDown<4>(Int8(6)) == Int8(4));
43 
44 static_assert(IsAligned(6, 2));
45 static_assert(!IsAligned(6, 4));
46 static_assert(IsAligned<2>(6));
47 static_assert(!IsAligned<4>(6));
48 static_assert(IsAligned<2>(RawInt8(6)));
49 static_assert(!IsAligned<4>(RawInt8(6)));
50 static_assert(IsAligned<2>(SatInt8(6)));
51 static_assert(!IsAligned<4>(SatInt8(6)));
52 static_assert(IsAligned<2>(Int8(6)));
53 static_assert(!IsAligned<4>(Int8(6)));
54 
55 static_assert(BitUtilLog2(1) == 0);
56 static_assert(BitUtilLog2(16) == 4);
57 static_assert(BitUtilLog2(sizeof(void*)) > 0);
58 
59 static_assert(CountRZero(~uint32_t{1}) == 1);
60 static_assert(CountRZero(RawInt32{~UInt32{1}}) == RawInt32{1});
61 static_assert(CountRZero(SatUInt32{~Int32{1}}) == SatUInt32{1});
62 static_assert(CountRZero(~UInt32{1}) == UInt32{1});
63 static_assert(CountRZero(~uint64_t{1}) == 1);
64 static_assert(CountRZero(RawInt64{~UInt64{1}}) == RawInt64{1});
65 static_assert(CountRZero(SatUInt64{~Int64{1}}) == SatUInt64{1});
66 static_assert(CountRZero(~UInt64{1}) == UInt64{1});
67 #if defined(__x86_64__)
68 static_assert(CountRZero(~static_cast<unsigned __int128>(1) << 64) == 65);
69 static_assert(CountRZero(RawInt128{~UInt128{1}}) == RawInt128{1});
70 static_assert(CountRZero(SatUInt128{~Int128{1}}) == SatUInt128{1});
71 static_assert(CountRZero(~UInt128{1} << UInt128{64}) == UInt128{65});
72 #endif
73 
74 static_assert(Popcount(~uint32_t{1}) == 31);
75 static_assert(Popcount(RawInt32{~UInt32{1}}) == RawInt32{31});
76 static_assert(Popcount(SatUInt32{~Int32{1}}) == SatUInt32{31});
77 static_assert(Popcount(~UInt32{1}) == UInt32{31});
78 static_assert(Popcount(~uint64_t{1}) == 63);
79 static_assert(Popcount(RawInt64{~UInt64{1}}) == RawInt64{63});
80 static_assert(Popcount(SatUInt64{~Int64{1}}) == SatUInt64{63});
81 static_assert(Popcount(~UInt64{1}) == UInt64{63});
82 #if defined(__x86_64__)
83 static_assert(Popcount(~static_cast<unsigned __int128>(1)) == 127);
84 static_assert(Popcount(RawInt128{~UInt128{1}}) == RawInt128{127});
85 static_assert(Popcount(SatUInt128{~Int128{1}}) == SatUInt128{127});
86 static_assert(Popcount(~UInt128{1}) == UInt128{127});
87 #endif
88 
89 static_assert(Add(SatInt8{126}, SatInt8{1}) == std::tuple{SatInt8{127}, false});
90 static_assert(Add(SatInt8{127}, SatInt8{1}) == std::tuple{SatInt8{127}, true});
91 static_assert(SatInt8{127} + SatInt8{1} == SatInt8{127});
92 static_assert(Int8{127} + Int8{1} == Int8{-128});
93 
94 static_assert(Add(SatUInt8{254}, SatUInt8{1}) == std::tuple{SatUInt8{255}, false});
95 static_assert(Add(SatUInt8{255}, SatUInt8{1}) == std::tuple{SatUInt8{255}, true});
96 static_assert(SatUInt8{255} + SatUInt8{1} == SatUInt8{255});
97 static_assert(UInt8{255} + UInt8{1} == UInt8{0});
98 
99 static_assert(Sub(SatInt8{-127}, SatInt8{1}) == std::tuple{SatInt8{-128}, false});
100 static_assert(Sub(SatInt8{-128}, SatInt8{1}) == std::tuple{SatInt8{-128}, true});
101 static_assert(SatInt8{-128} - SatInt8{1} == SatInt8{-128});
102 static_assert(Int8{-128} - Int8{1} == Int8{127});
103 
104 static_assert(Sub(SatUInt8{1}, SatUInt8{1}) == std::tuple{SatUInt8{0}, false});
105 static_assert(Sub(SatUInt8{0}, SatUInt8{1}) == std::tuple{SatUInt8{0}, true});
106 static_assert(SatUInt8{0} - SatUInt8{1} == SatUInt8{0});
107 static_assert(UInt8{0} - UInt8{1} == UInt8{255});
108 
109 static_assert(Mul(SatInt8{127}, SatInt8{1}) == std::tuple{SatInt8{127}, false});
110 static_assert(Mul(SatInt8{-128}, SatInt8{1}) == std::tuple{SatInt8{-128}, false});
111 static_assert(Mul(SatInt8{1}, SatInt8{-128}) == std::tuple{SatInt8{-128}, false});
112 static_assert(Mul(SatInt8{1}, SatInt8{127}) == std::tuple{SatInt8{127}, false});
113 static_assert(Mul(SatInt8{-128}, SatInt8{-128}) == std::tuple{SatInt8{127}, true});
114 static_assert(Mul(SatInt8{-128}, SatInt8{127}) == std::tuple{SatInt8{-128}, true});
115 static_assert(Mul(SatInt8{127}, SatInt8{-128}) == std::tuple{SatInt8{-128}, true});
116 static_assert(Mul(SatInt8{127}, SatInt8{127}) == std::tuple{SatInt8{127}, true});
117 static_assert(SatInt8{-128} * SatInt8{-128} == SatInt8{127});
118 static_assert(SatInt8{-128} * SatInt8{127} == SatInt8{-128});
119 static_assert(SatInt8{127} * SatInt8{-128} == SatInt8{-128});
120 static_assert(SatInt8{127} * SatInt8{127} == SatInt8{127});
121 static_assert(Int8{-128} * Int8{-128} == Int8{0});
122 static_assert(Int8{-128} * Int8{127} == Int8{-128});
123 static_assert(Int8{127} * Int8{-128} == Int8{-128});
124 static_assert(Int8{127} * Int8{127} == Int8{1});
125 
126 static_assert(Mul(SatUInt8{255}, SatUInt8{1}) == std::tuple{SatUInt8{255}, false});
127 static_assert(Mul(SatUInt8{255}, SatUInt8{255}) == std::tuple{SatUInt8{255}, true});
128 static_assert(SatUInt8{255} * SatUInt8{255} == SatUInt8{255});
129 static_assert(UInt8{255} * UInt8{255} == UInt8{1});
130 
131 static_assert(Div(SatInt8{127}, SatInt8{1}) == std::tuple{SatInt8{127}, false});
132 static_assert(Div(SatInt8{-128}, SatInt8{-1}) == std::tuple{SatInt8{127}, true});
133 static_assert(SatInt8{-128} / SatInt8{-1} == SatInt8{127});
134 static_assert(Int8{-128} / Int8{-1} == Int8{-128});
135 
136 // Note: division couldn't overflow with SatUInt8 (but could with SatUnt8, see above).
137 static_assert(Div(SatUInt8{255}, SatUInt8{1}) == std::tuple{SatUInt8{255}, false});
138 static_assert(SatUInt8{255} / SatUInt8{1} == SatUInt8{255});
139 static_assert(UInt8{255} / UInt8{1} == UInt8{255});
140 
141 static_assert((Int8{123} << Int8{8}) == Int8{123});
142 static_assert((Int8{123} << Int8{65}) == Int8{-10});
143 
144 static_assert((UInt8{123} << UInt8{8}) == UInt8{123});
145 static_assert((UInt8{123} << UInt8{65}) == UInt8{246});
146 
147 static_assert((Int8{123} >> Int8{8}) == Int8{123});
148 static_assert((Int8{123} >> Int8{65}) == Int8{61});
149 
150 static_assert((UInt8{123} >> UInt8{8}) == UInt8{123});
151 static_assert((UInt8{123} >> UInt8{65}) == UInt8{61});
152 
153 static_assert(SatInt8{1} == SatInt8{Int8{1}});
154 
155 // Verify that types are correctly expaned when needed.
156 // Note: attept to use signed and unsigned types in the same expression
157 // or mix saturating types and wrapping types trigger a compile-time error.
158 static_assert(SatInt16{1} + SatInt8{1} == SatInt16{2});
159 static_assert(Int16{1} + Int8{1} == Int16{2});
160 
161 static_assert(SatInt8{1} + SatInt32{1} == SatInt32{2});
162 static_assert(Int8{1} + Int32{1} == Int32{2});
163 
164 // Note: shifts use type of first operand to determine the result type.
165 // Wrapping also depends on the size of left operand only.
166 static_assert((Int16{1} << Int8{8}) == Int16{256});
167 static_assert((Int8{1} << Int16{8}) == Int8{1});
168 
169 static_assert(MaybeTruncateTo<SatInt8>(SatInt8{127}) == SatInt8{127});
170 static_assert(MaybeTruncateTo<SatInt8>(SatInt16{32767}) == SatInt8{-1});
171 static_assert(TruncateTo<SatInt8>(SatInt16{32767}) == SatInt8{-1});
172 static_assert(MaybeTruncateTo<SatInt8>(SatInt8{-128}) == SatInt8{-128});
173 static_assert(MaybeTruncateTo<SatInt8>(SatInt16{-32768}) == SatInt8{0});
174 static_assert(TruncateTo<SatInt8>(SatInt16{-32768}) == SatInt8{0});
175 
176 static_assert(MaybeTruncateTo<Int8>(Int8{127}) == Int8{127});
177 static_assert(MaybeTruncateTo<Int8>(Int16{32767}) == Int8{-1});
178 static_assert(TruncateTo<Int8>(Int16{32767}) == Int8{-1});
179 static_assert(MaybeTruncateTo<Int8>(Int8{-128}) == Int8{-128});
180 static_assert(MaybeTruncateTo<Int8>(Int16{-32768}) == Int8{0});
181 static_assert(TruncateTo<Int8>(Int16{-32768}) == Int8{0});
182 
183 // BitCastToSigned and BitCastToUnsigned don't change the bits of integer, they just treat them
184 // differently.
185 static_assert(BitCastToSigned(SatUInt8{128}) == SatInt8{-128});
186 static_assert(BitCastToSigned(UInt8{128}) == Int8{-128});
187 static_assert(BitCastToUnsigned(SatInt8{-128}) == SatUInt8{128});
188 static_assert(BitCastToUnsigned(Int8{-128}) == UInt8{128});
189 
190 static_assert(std::is_same_v<Int16, Int16::SignedType>);
191 static_assert(std::is_same_v<Int16, UInt16::SignedType>);
192 static_assert(std::is_same_v<UInt16, Int16::UnsignedType>);
193 static_assert(std::is_same_v<UInt16, UInt16::UnsignedType>);
194 
195 static_assert(std::is_same_v<Int16, SignedType<RawInt16>>);
196 static_assert(std::is_same_v<Int16, SignedType<Int16>>);
197 static_assert(std::is_same_v<Int16, SignedType<UInt16>>);
198 static_assert(std::is_same_v<UInt16, UnsignedType<RawInt16>>);
199 static_assert(std::is_same_v<UInt16, UnsignedType<Int16>>);
200 static_assert(std::is_same_v<UInt16, UnsignedType<UInt16>>);
201 
202 static_assert(std::is_same_v<Int16, WrappingType<Int16>>);
203 static_assert(std::is_same_v<UInt16, WrappingType<UInt16>>);
204 static_assert(std::is_same_v<Int16, WrappingType<SatInt16>>);
205 static_assert(std::is_same_v<UInt16, WrappingType<SatUInt16>>);
206 
207 static_assert(std::is_same_v<SatInt16, SatInt16::SignedType>);
208 static_assert(std::is_same_v<SatInt16, SatUInt16::SignedType>);
209 static_assert(std::is_same_v<SatUInt16, SatInt16::UnsignedType>);
210 static_assert(std::is_same_v<SatUInt16, SatUInt16::UnsignedType>);
211 
212 static_assert(std::is_same_v<SatInt16, SignedType<SatInt16>>);
213 static_assert(std::is_same_v<SatInt16, SignedType<SatUInt16>>);
214 static_assert(std::is_same_v<SatUInt16, UnsignedType<SatInt16>>);
215 static_assert(std::is_same_v<SatUInt16, UnsignedType<SatUInt16>>);
216 
217 static_assert(std::is_same_v<SatInt16, SaturatingType<Int16>>);
218 static_assert(std::is_same_v<SatUInt16, SaturatingType<UInt16>>);
219 static_assert(std::is_same_v<SatInt16, SaturatingType<SatInt16>>);
220 static_assert(std::is_same_v<SatUInt16, SaturatingType<SatUInt16>>);
221 
222 static_assert(std::is_same_v<SatInt16, SignedType<SatInt16>>);
223 static_assert(std::is_same_v<SatInt16, SignedType<SatUInt16>>);
224 static_assert(std::is_same_v<SatUInt16, UnsignedType<SatInt16>>);
225 static_assert(std::is_same_v<SatUInt16, UnsignedType<SatUInt16>>);
226 
227 static_assert(std::is_same_v<RawInt16, RawType<RawInt16>>);
228 static_assert(std::is_same_v<RawInt16, RawType<Int16>>);
229 static_assert(std::is_same_v<RawInt16, RawType<UInt16>>);
230 static_assert(std::is_same_v<RawInt16, RawType<SatInt16>>);
231 static_assert(std::is_same_v<RawInt16, RawType<SatUInt16>>);
232 
233 }  // namespace
234 
235 }  // namespace berberis
236