• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kaidokert / fixed-bigint-rs / 16187943584

10 Jul 2025 06:36AM UTC coverage: 93.455% (+9.0%) from 84.416%
16187943584

push

github

web-flow
Improve coverage (#47)

* Improve coverage

1328 of 1421 relevant lines covered (93.46%)

909.57 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.32
/src/fixeduint/bit_ops_impl.rs
1
use super::{FixedUInt, MachineWord};
2

3
use crate::patch_num_traits::{OverflowingShl, OverflowingShr};
4

5
use num_traits::Zero;
6

7
impl<T: MachineWord, const N: usize> core::ops::Not for FixedUInt<T, N> {
8
    type Output = Self;
9
    fn not(self) -> <Self as core::ops::Not>::Output {
11✔
10
        let mut ret = Self::zero();
11✔
11
        for i in 0..N {
26✔
12
            ret.array[i] = !self.array[i]
15✔
13
        }
14
        ret
11✔
15
    }
11✔
16
}
17

18
impl<T: MachineWord, const N: usize> core::ops::BitAnd<&FixedUInt<T, N>> for &FixedUInt<T, N> {
19
    type Output = FixedUInt<T, N>;
20
    fn bitand(self, other: &FixedUInt<T, N>) -> Self::Output {
164✔
21
        let mut ret = Self::Output::zero();
164✔
22
        for i in 0..N {
472✔
23
            ret.array[i] = self.array[i] & other.array[i]
308✔
24
        }
25
        ret
164✔
26
    }
164✔
27
}
28

29
impl<T: MachineWord, const N: usize> core::ops::BitAnd for FixedUInt<T, N> {
30
    type Output = Self;
31
    fn bitand(self, other: Self) -> Self::Output {
161✔
32
        (&self).bitand(&other)
161✔
33
    }
161✔
34
}
35

36
impl<T: MachineWord, const N: usize> core::ops::BitAnd<&FixedUInt<T, N>> for FixedUInt<T, N> {
37
    type Output = Self;
38
    fn bitand(self, other: &FixedUInt<T, N>) -> Self::Output {
1✔
39
        (&self).bitand(other)
1✔
40
    }
1✔
41
}
42

43
impl<T: MachineWord, const N: usize> core::ops::BitAnd<FixedUInt<T, N>> for &FixedUInt<T, N> {
44
    type Output = FixedUInt<T, N>;
45
    fn bitand(self, other: FixedUInt<T, N>) -> Self::Output {
1✔
46
        self.bitand(&other)
1✔
47
    }
1✔
48
}
49

50
impl<T: MachineWord, const N: usize> core::ops::BitAndAssign for FixedUInt<T, N> {
51
    fn bitand_assign(&mut self, other: Self) {
136✔
52
        for i in 0..N {
404✔
53
            self.array[i] &= other.array[i]
268✔
54
        }
55
    }
136✔
56
}
57

58
impl<T: MachineWord, const N: usize> core::ops::BitOr<&FixedUInt<T, N>> for &FixedUInt<T, N> {
59
    type Output = FixedUInt<T, N>;
60
    fn bitor(self, other: &FixedUInt<T, N>) -> Self::Output {
215✔
61
        let mut ret = Self::Output::zero();
215✔
62
        for i in 0..N {
609✔
63
            ret.array[i] = self.array[i] | other.array[i]
394✔
64
        }
65
        ret
215✔
66
    }
215✔
67
}
68

69
impl<T: MachineWord, const N: usize> core::ops::BitOr for FixedUInt<T, N> {
70
    type Output = Self;
71
    fn bitor(self, other: Self) -> Self::Output {
212✔
72
        (&self).bitor(&other)
212✔
73
    }
212✔
74
}
75

76
impl<T: MachineWord, const N: usize> core::ops::BitOr<&FixedUInt<T, N>> for FixedUInt<T, N> {
77
    type Output = Self;
78
    fn bitor(self, other: &FixedUInt<T, N>) -> Self::Output {
1✔
79
        (&self).bitor(other)
1✔
80
    }
1✔
81
}
82

83
impl<T: MachineWord, const N: usize> core::ops::BitOr<FixedUInt<T, N>> for &FixedUInt<T, N> {
84
    type Output = FixedUInt<T, N>;
85
    fn bitor(self, other: FixedUInt<T, N>) -> Self::Output {
1✔
86
        self.bitor(&other)
1✔
87
    }
1✔
88
}
89

90
impl<T: MachineWord, const N: usize> core::ops::BitOrAssign for FixedUInt<T, N> {
91
    fn bitor_assign(&mut self, other: Self) {
1,780✔
92
        for i in 0..N {
5,942✔
93
            self.array[i] |= other.array[i]
4,162✔
94
        }
95
    }
1,780✔
96
}
97

98
impl<T: MachineWord, const N: usize> core::ops::BitXor<&FixedUInt<T, N>> for &FixedUInt<T, N> {
99
    type Output = FixedUInt<T, N>;
100
    fn bitxor(self, other: &FixedUInt<T, N>) -> Self::Output {
140✔
101
        let mut ret = Self::Output::zero();
140✔
102
        for i in 0..N {
416✔
103
            ret.array[i] = self.array[i] ^ other.array[i]
276✔
104
        }
105
        ret
140✔
106
    }
140✔
107
}
108

109
impl<T: MachineWord, const N: usize> core::ops::BitXor for FixedUInt<T, N> {
110
    type Output = Self;
111
    fn bitxor(self, other: Self) -> Self::Output {
137✔
112
        (&self).bitxor(&other)
137✔
113
    }
137✔
114
}
115

116
impl<T: MachineWord, const N: usize> core::ops::BitXor<&FixedUInt<T, N>> for FixedUInt<T, N> {
117
    type Output = Self;
118
    fn bitxor(self, other: &FixedUInt<T, N>) -> Self::Output {
1✔
119
        (&self).bitxor(other)
1✔
120
    }
1✔
121
}
122

123
impl<T: MachineWord, const N: usize> core::ops::BitXor<FixedUInt<T, N>> for &FixedUInt<T, N> {
124
    type Output = FixedUInt<T, N>;
125
    fn bitxor(self, other: FixedUInt<T, N>) -> Self::Output {
1✔
126
        self.bitxor(&other)
1✔
127
    }
1✔
128
}
129

130
impl<T: MachineWord, const N: usize> core::ops::BitXorAssign for FixedUInt<T, N> {
131
    fn bitxor_assign(&mut self, other: Self) {
136✔
132
        for i in 0..N {
404✔
133
            self.array[i] ^= other.array[i]
268✔
134
        }
135
    }
136✔
136
}
137

138
impl<T: MachineWord, const N: usize> OverflowingShl for FixedUInt<T, N> {
139
    fn overflowing_shl(self, bits: u32) -> (Self, bool) {
72✔
140
        let bitsu = bits as usize;
72✔
141
        let (shift, overflow) = if bitsu >= Self::BIT_SIZE {
72✔
142
            (bitsu & (Self::BIT_SIZE - 1), true)
36✔
143
        } else {
144
            (bitsu, false)
36✔
145
        };
146
        let res = core::ops::Shl::<usize>::shl(self, shift);
72✔
147
        (res, overflow)
72✔
148
    }
72✔
149
}
150

151
impl<T: MachineWord, const N: usize> core::ops::Shl<u32> for FixedUInt<T, N> {
152
    type Output = Self;
153
    fn shl(self, bits: u32) -> <Self as core::ops::Shl<u32>>::Output {
53✔
154
        core::ops::Shl::<usize>::shl(self, bits as usize)
53✔
155
    }
53✔
156
}
157

158
impl<T: MachineWord, const N: usize> core::ops::Shl<usize> for FixedUInt<T, N> {
159
    type Output = Self;
160
    fn shl(self, bits: usize) -> <Self as core::ops::Shl<usize>>::Output {
150✔
161
        // This copy can be avoided
162
        let mut result = self;
150✔
163
        Self::shl_impl(&mut result, bits);
150✔
164
        result
150✔
165
    }
150✔
166
}
167

168
impl<T: MachineWord, const N: usize> core::ops::Shl<&'_ usize> for FixedUInt<T, N> {
169
    type Output = Self;
170
    fn shl(self, bits: &usize) -> <Self as core::ops::Shl<usize>>::Output {
1✔
171
        let mut result = self;
1✔
172
        Self::shl_impl(&mut result, *bits);
1✔
173
        result
1✔
174
    }
1✔
175
}
176

177
impl<T: MachineWord, const N: usize> num_traits::WrappingShl for FixedUInt<T, N> {
178
    fn wrapping_shl(&self, bits: u32) -> Self {
24✔
179
        self.overflowing_shl(bits).0
24✔
180
    }
24✔
181
}
182

183
impl<T: MachineWord, const N: usize> num_traits::CheckedShl for FixedUInt<T, N> {
184
    fn checked_shl(&self, bits: u32) -> Option<Self> {
24✔
185
        let res = self.overflowing_shl(bits);
24✔
186
        if res.1 {
24✔
187
            None
12✔
188
        } else {
189
            Some(res.0)
12✔
190
        }
191
    }
24✔
192
}
193

194
// SaturatingShl doesn't exist
195

196
impl<T: MachineWord, const N: usize> core::ops::ShlAssign<usize> for FixedUInt<T, N> {
197
    fn shl_assign(&mut self, bits: usize) {
6,244✔
198
        Self::shl_impl(self, bits);
6,244✔
199
    }
6,244✔
200
}
201

202
impl<T: MachineWord, const N: usize> core::ops::ShlAssign<&'_ usize> for FixedUInt<T, N> {
203
    fn shl_assign(&mut self, bits: &usize) {
×
204
        Self::shl_impl(self, *bits);
×
205
    }
×
206
}
207

208
impl<T: MachineWord, const N: usize> OverflowingShr for FixedUInt<T, N> {
209
    fn overflowing_shr(self, bits: u32) -> (Self, bool) {
72✔
210
        let bitsu = bits as usize;
72✔
211
        let (shift, overflow) = if bitsu >= Self::BIT_SIZE {
72✔
212
            (bitsu & (Self::BIT_SIZE - 1), true)
36✔
213
        } else {
214
            (bitsu, false)
36✔
215
        };
216
        let res = core::ops::Shr::<usize>::shr(self, shift);
72✔
217
        (res, overflow)
72✔
218
    }
72✔
219
}
220

221
impl<T: MachineWord, const N: usize> core::ops::Shr<u32> for FixedUInt<T, N> {
222
    type Output = Self;
223
    fn shr(self, bits: u32) -> <Self as core::ops::Shr<u32>>::Output {
86✔
224
        core::ops::Shr::<usize>::shr(self, bits as usize)
86✔
225
    }
86✔
226
}
227

228
impl<T: MachineWord, const N: usize> core::ops::Shr<usize> for FixedUInt<T, N> {
229
    type Output = Self;
230
    fn shr(self, bits: usize) -> <Self as core::ops::Shr<usize>>::Output {
189✔
231
        // Technically, this copy can be avoided
232
        let mut result = self;
189✔
233
        Self::shr_impl(&mut result, bits);
189✔
234
        result
189✔
235
    }
189✔
236
}
237

238
impl<T: MachineWord, const N: usize> core::ops::Shr<&'_ usize> for FixedUInt<T, N> {
239
    type Output = Self;
240
    fn shr(self, bits: &usize) -> <Self as core::ops::Shr<usize>>::Output {
1✔
241
        let mut result = self;
1✔
242
        Self::shr_impl(&mut result, *bits);
1✔
243
        result
1✔
244
    }
1✔
245
}
246

247
impl<T: MachineWord, const N: usize> num_traits::WrappingShr for FixedUInt<T, N> {
248
    fn wrapping_shr(&self, bits: u32) -> Self {
24✔
249
        self.overflowing_shr(bits).0
24✔
250
    }
24✔
251
}
252

253
impl<T: MachineWord, const N: usize> num_traits::CheckedShr for FixedUInt<T, N> {
254
    fn checked_shr(&self, bits: u32) -> Option<Self> {
24✔
255
        let res = self.overflowing_shr(bits);
24✔
256
        if res.1 {
24✔
257
            None
12✔
258
        } else {
259
            Some(res.0)
12✔
260
        }
261
    }
24✔
262
}
263

264
// SaturatingShr doesn't exist
265

266
impl<T: MachineWord, const N: usize> core::ops::ShrAssign<usize> for FixedUInt<T, N> {
267
    fn shr_assign(&mut self, bits: usize) {
7,070✔
268
        Self::shr_impl(self, bits);
7,070✔
269
    }
7,070✔
270
}
271

272
impl<T: MachineWord, const N: usize> core::ops::ShrAssign<&'_ usize> for FixedUInt<T, N> {
273
    fn shr_assign(&mut self, bits: &usize) {
×
274
        Self::shr_impl(self, *bits);
×
275
    }
×
276
}
277

278
impl<T: MachineWord, const N: usize> core::ops::Shl<&usize> for &FixedUInt<T, N> {
279
    type Output = FixedUInt<T, N>;
280
    fn shl(self, bits: &usize) -> Self::Output {
4✔
281
        let mut result = *self;
4✔
282
        Self::Output::shl_impl(&mut result, *bits);
4✔
283
        result
4✔
284
    }
4✔
285
}
286

287
impl<T: MachineWord, const N: usize> core::ops::Shl<&u32> for &FixedUInt<T, N> {
288
    type Output = FixedUInt<T, N>;
289
    fn shl(self, bits: &u32) -> Self::Output {
1✔
290
        self.shl(&(*bits as usize))
1✔
291
    }
1✔
292
}
293

294
impl<T: MachineWord, const N: usize> core::ops::Shr<&usize> for &FixedUInt<T, N> {
295
    type Output = FixedUInt<T, N>;
296
    fn shr(self, bits: &usize) -> Self::Output {
4✔
297
        let mut result = *self;
4✔
298
        Self::Output::shr_impl(&mut result, *bits);
4✔
299
        result
4✔
300
    }
4✔
301
}
302

303
impl<T: MachineWord, const N: usize> core::ops::Shr<&u32> for &FixedUInt<T, N> {
304
    type Output = FixedUInt<T, N>;
305
    fn shr(self, bits: &u32) -> Self::Output {
1✔
306
        self.shr(&(*bits as usize))
1✔
307
    }
1✔
308
}
309

310
// Additional Shl implementations
311
impl<T: MachineWord, const N: usize> core::ops::Shl<usize> for &FixedUInt<T, N> {
312
    type Output = FixedUInt<T, N>;
313
    fn shl(self, bits: usize) -> Self::Output {
1✔
314
        self.shl(&bits)
1✔
315
    }
1✔
316
}
317

318
impl<T: MachineWord, const N: usize> core::ops::Shl<u32> for &FixedUInt<T, N> {
319
    type Output = FixedUInt<T, N>;
320
    fn shl(self, bits: u32) -> Self::Output {
1✔
321
        self.shl(&(bits as usize))
1✔
322
    }
1✔
323
}
324

325
impl<T: MachineWord, const N: usize> core::ops::Shl<&u32> for FixedUInt<T, N> {
326
    type Output = Self;
327
    fn shl(self, bits: &u32) -> Self::Output {
1✔
328
        self.shl(*bits)
1✔
329
    }
1✔
330
}
331

332
// Additional Shr implementations
333
impl<T: MachineWord, const N: usize> core::ops::Shr<usize> for &FixedUInt<T, N> {
334
    type Output = FixedUInt<T, N>;
335
    fn shr(self, bits: usize) -> Self::Output {
1✔
336
        self.shr(&bits)
1✔
337
    }
1✔
338
}
339

340
impl<T: MachineWord, const N: usize> core::ops::Shr<u32> for &FixedUInt<T, N> {
341
    type Output = FixedUInt<T, N>;
342
    fn shr(self, bits: u32) -> Self::Output {
1✔
343
        self.shr(&(bits as usize))
1✔
344
    }
1✔
345
}
346

347
impl<T: MachineWord, const N: usize> core::ops::Shr<&u32> for FixedUInt<T, N> {
348
    type Output = Self;
349
    fn shr(self, bits: &u32) -> Self::Output {
1✔
350
        self.shr(*bits)
1✔
351
    }
1✔
352
}
353

354
#[cfg(test)]
355
mod tests {
356
    use super::*;
357

358
    #[test]
359
    fn test_bitand_combinations() {
1✔
360
        let a = FixedUInt::<u8, 2>::from(12u8); // 1100
1✔
361
        let b = FixedUInt::<u8, 2>::from(10u8); // 1010
1✔
362
        let expected = FixedUInt::<u8, 2>::from(8u8); // 1000
1✔
363

364
        // value & value
365
        assert_eq!(a & b, expected);
1✔
366
        // value & ref
367
        assert_eq!(a & &b, expected);
1✔
368
        // ref & value
369
        assert_eq!(&a & b, expected);
1✔
370
        // ref & ref
371
        assert_eq!(&a & &b, expected);
1✔
372
    }
1✔
373

374
    #[test]
375
    fn test_bitor_combinations() {
1✔
376
        let a = FixedUInt::<u8, 2>::from(12u8); // 1100
1✔
377
        let b = FixedUInt::<u8, 2>::from(10u8); // 1010
1✔
378
        let expected = FixedUInt::<u8, 2>::from(14u8); // 1110
1✔
379

380
        // value | value
381
        assert_eq!(a | b, expected);
1✔
382
        // value | ref
383
        assert_eq!(a | &b, expected);
1✔
384
        // ref | value
385
        assert_eq!(&a | b, expected);
1✔
386
        // ref | ref
387
        assert_eq!(&a | &b, expected);
1✔
388
    }
1✔
389

390
    #[test]
391
    fn test_bitxor_combinations() {
1✔
392
        let a = FixedUInt::<u8, 2>::from(12u8); // 1100
1✔
393
        let b = FixedUInt::<u8, 2>::from(10u8); // 1010
1✔
394
        let expected = FixedUInt::<u8, 2>::from(6u8); // 0110
1✔
395

396
        // value ^ value
397
        assert_eq!(a ^ b, expected);
1✔
398
        // value ^ ref
399
        assert_eq!(a ^ &b, expected);
1✔
400
        // ref ^ value
401
        assert_eq!(&a ^ b, expected);
1✔
402
        // ref ^ ref
403
        assert_eq!(&a ^ &b, expected);
1✔
404
    }
1✔
405

406
    #[test]
407
    fn test_shl_combinations() {
1✔
408
        let a = FixedUInt::<u8, 2>::from(2u8); // 0010
1✔
409
        let shift: usize = 2;
1✔
410
        let expected = FixedUInt::<u8, 2>::from(8u8); // 1000
1✔
411

412
        // value << value
413
        assert_eq!(a << shift, expected);
1✔
414
        // value << ref
415
        assert_eq!(a << &shift, expected);
1✔
416
        // ref << value
417
        assert_eq!(&a << shift, expected);
1✔
418
        // ref << ref
419
        assert_eq!(&a << &shift, expected);
1✔
420

421
        // Same with u32
422
        let shift32: u32 = 2;
1✔
423
        assert_eq!(a << shift32, expected);
1✔
424
        assert_eq!(a << &shift32, expected);
1✔
425
        assert_eq!(&a << shift32, expected);
1✔
426
        assert_eq!(&a << &shift32, expected);
1✔
427
    }
1✔
428

429
    #[test]
430
    fn test_shr_combinations() {
1✔
431
        let a = FixedUInt::<u8, 2>::from(8u8); // 1000
1✔
432
        let shift: usize = 2;
1✔
433
        let expected = FixedUInt::<u8, 2>::from(2u8); // 0010
1✔
434

435
        // value >> value
436
        assert_eq!(a >> shift, expected);
1✔
437
        // value >> ref
438
        assert_eq!(a >> &shift, expected);
1✔
439
        // ref >> value
440
        assert_eq!(&a >> shift, expected);
1✔
441
        // ref >> ref
442
        assert_eq!(&a >> &shift, expected);
1✔
443

444
        // Same with u32
445
        let shift32: u32 = 2;
1✔
446
        assert_eq!(a >> shift32, expected);
1✔
447
        assert_eq!(a >> &shift32, expected);
1✔
448
        assert_eq!(&a >> shift32, expected);
1✔
449
        assert_eq!(&a >> &shift32, expected);
1✔
450
    }
1✔
451
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc