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