Skip to main content

base_traits/traits/
is_zero.rs

1// src/traits/is_zero.rs : `IsZero`
2
3/// Trait defining instance method `is_zero() : bool` that indicates whether
4/// the implementing type instance is numerically zero.
5///
6/// # Additional Implementations on Foreign Types
7///
8/// ## Built-in Types
9///
10/// If the feature `"implement-IsZero-for-built_ins"`
11/// is defined (as it is by `"default"`), then this is also implemented
12/// for the following types:
13/// - [`i8`];
14/// - [`i16`];
15/// - [`i32`];
16/// - [`i64`];
17/// - [`i128`];
18/// - [`u8`];
19/// - [`u16`];
20/// - [`u32`];
21/// - [`u64`];
22/// - [`u128`];
23/// - [`isize`];
24/// - [`usize`];
25/// - [`f32`];
26/// - [`f64`];
27/// - [`char`];
28///
29/// ## Standard Process Types
30///
31/// If the feature `"implement-IsZero-for-standard_process_types"`
32/// is defined (as it is by `"default"`), then this is also implemented
33/// for the following types:
34/// - [`std::process::ExitStatus`];
35///
36/// ## Standard Time Types
37///
38/// If the feature `"implement-IsZero-for-standard_time_types"`
39/// is defined (as it is by `"default"`), then this is also implemented
40/// for the following types:
41/// - [`std::time::Duration`];
42pub trait IsZero {
43    fn is_zero(&self) -> bool;
44}
45
46
47#[cfg(any(test, not(feature = "nostd")))]
48impl<T : IsZero + ?Sized> IsZero for Box<T> {
49    fn is_zero(&self) -> bool {
50        (**self).is_zero()
51    }
52}
53
54#[cfg(any(test, not(feature = "nostd")))]
55impl<T : IsZero + ?Sized> IsZero for std::rc::Rc<T> {
56    fn is_zero(&self) -> bool {
57        (**self).is_zero()
58    }
59}
60
61
62#[cfg(feature = "implement-IsZero-for-built_ins")]
63mod impl_for_built_ins {
64    #![allow(non_snake_case)]
65
66    macro_rules! implement_IsZero_ {
67        ($type:tt, $zero_value:expr) => {
68            impl super::IsZero for $type {
69                #[inline]
70                fn is_zero(&self) -> bool {
71                    $zero_value == *self
72                }
73            }
74        };
75    }
76
77    implement_IsZero_!(i8, 0);
78    implement_IsZero_!(i16, 0);
79    implement_IsZero_!(i32, 0);
80    implement_IsZero_!(i64, 0);
81    implement_IsZero_!(i128, 0);
82
83    implement_IsZero_!(u8, 0);
84    implement_IsZero_!(u16, 0);
85    implement_IsZero_!(u32, 0);
86    implement_IsZero_!(u64, 0);
87    implement_IsZero_!(u128, 0);
88
89    implement_IsZero_!(isize, 0);
90    implement_IsZero_!(usize, 0);
91
92    implement_IsZero_!(f32, 0.0);
93    implement_IsZero_!(f64, 0.0);
94
95    implement_IsZero_!(char, '\0');
96}
97
98
99#[cfg(feature = "implement-IsZero-for-standard_num_types")]
100mod impl_for_std_num_types {
101    #![allow(non_snake_case)]
102
103    /*
104    use std::num as std_num;
105     */
106
107    // NonZero<T>
108
109    /*
110    impl<T> super::IsZero for std_num::NonZero<T>
111    {
112        fn is_zero(&self) -> bool {
113            false
114        }
115    }
116     */
117}
118
119
120#[cfg(all(not(feature = "nostd"), feature = "implement-IsZero-for-standard_process_types"))]
121mod impl_for_std_process_types {
122    #![allow(non_snake_case)]
123
124    use std::process as std_process;
125
126
127    // ExitStatus
128
129    impl super::IsZero for std_process::ExitStatus {
130        fn is_zero(&self) -> bool {
131            match self.code() {
132                Some(ec) => 0 == ec,
133                None => false,
134            }
135        }
136    }
137}
138
139
140#[cfg(all(not(feature = "nostd"), feature = "implement-IsZero-for-standard_time_types"))]
141mod impl_for_std_time_types {
142    #![allow(non_snake_case)]
143
144    use std::time as std_time;
145
146
147    mod isolate_ {
148        #![allow(non_snake_case)]
149
150        use std::time as std_time;
151
152
153        #[inline]
154        pub(super) fn get_is_zero_Duration_(d : &std_time::Duration) -> bool {
155            d.is_zero()
156        }
157    }
158
159
160    // Duration
161
162    impl super::IsZero for std_time::Duration {
163        fn is_zero(&self) -> bool {
164            isolate_::get_is_zero_Duration_(self)
165        }
166    }
167}
168
169
170#[cfg(test)]
171mod tests {
172    #![allow(non_snake_case)]
173
174    use super::IsZero;
175
176    use std::rc::Rc;
177
178
179    #[allow(unused)]
180    fn as_IsZero<T : IsZero>(t : &T) -> &impl IsZero {
181        t
182    }
183
184
185    mod TEST_CUSTOM_TYPE {
186        #![allow(non_snake_case)]
187
188        use super::*;
189
190
191        #[derive(Debug)]
192        struct CustomType {
193            value : i32,
194        }
195
196        impl IsZero for CustomType {
197            fn is_zero(&self) -> bool {
198                0 == self.value
199            }
200        }
201
202
203        #[test]
204        fn TEST_WHEN_ZERO_ELEMENTS() {
205            let ct = CustomType { value : 0 };
206
207            assert!(ct.is_zero());
208
209            let ct = &ct;
210
211            assert!(ct.is_zero());
212        }
213
214        #[test]
215        fn TEST_WHEN_HAVE_ELEMENTS() {
216            let ct = CustomType { value : 1 };
217
218            assert!(!ct.is_zero());
219
220            let ct = &ct;
221
222            assert!(!ct.is_zero());
223        }
224
225        #[test]
226        fn TEST_WHEN_ZERO_ELEMENTS_IN_Box() {
227            {
228                let ct = Box::new(CustomType { value : 0 });
229
230                assert!(ct.is_zero());
231
232                let ct = &ct;
233
234                assert!(ct.is_zero());
235            }
236
237            {
238                let ct = &Box::new(CustomType { value : 0 });
239
240                assert!(ct.is_zero());
241
242                let ct = &ct;
243
244                assert!(ct.is_zero());
245            }
246
247            {
248                let ct = Box::new(&CustomType { value : 0 });
249
250                assert!(ct.is_zero());
251
252                let ct = &ct;
253
254                assert!(ct.is_zero());
255            }
256
257            {
258                let ct = &Box::new(&CustomType { value : 0 });
259
260                assert!(ct.is_zero());
261
262                let ct = &ct;
263
264                assert!(ct.is_zero());
265            }
266        }
267
268        #[test]
269        fn TEST_WHEN_ZERO_ELEMENTS_IN_Rc() {
270            {
271                let ct = Rc::new(CustomType { value : 0 });
272
273                assert!(ct.is_zero());
274
275                let ct = &ct;
276
277                assert!(ct.is_zero());
278            }
279
280            {
281                let ct = &Rc::new(CustomType { value : 0 });
282
283                assert!(ct.is_zero());
284
285                let ct = &ct;
286
287                assert!(ct.is_zero());
288            }
289
290            {
291                let ct = Rc::new(&CustomType { value : 0 });
292
293                assert!(ct.is_zero());
294
295                let ct = &ct;
296
297                assert!(ct.is_zero());
298            }
299
300            {
301                let ct = &Rc::new(&CustomType { value : 0 });
302
303                assert!(ct.is_zero());
304
305                let ct = &ct;
306
307                assert!(ct.is_zero());
308            }
309        }
310    }
311
312
313    #[cfg(feature = "implement-IsZero-for-built_ins")]
314    mod TEST_BUILTIN_TYPES {
315        #![allow(non_snake_case)]
316
317        use super::*;
318
319
320        mod TEST_char {
321            #![allow(non_snake_case)]
322
323            use super::*;
324
325
326            #[test]
327            fn TEST_ZERO() {
328                {
329                    let c = '\0';
330
331                    assert!(c.is_zero());
332
333                    let ie = as_IsZero(&c);
334
335                    assert!(ie.is_zero());
336                }
337
338                {
339                    let c = '\u{0000}';
340
341                    assert!(c.is_zero());
342
343                    let ie = as_IsZero(&c);
344
345                    assert!(ie.is_zero());
346                }
347            }
348
349            #[test]
350            fn TEST_NONZERO() {
351                let c = 'a';
352
353                assert!(!c.is_zero());
354
355                let ie = as_IsZero(&c);
356
357                assert!(!ie.is_zero());
358            }
359        }
360
361
362        mod TEST_f64 {
363            #![allow(non_snake_case)]
364
365            use super::*;
366
367
368            #[test]
369            fn TEST_ZERO() {
370                let v = 0.0f64;
371
372                assert!(v.is_zero());
373
374                let ie = as_IsZero(&v);
375
376                assert!(ie.is_zero());
377            }
378
379            #[test]
380            fn TEST_NONZERO() {
381                let v = -123.456f64;
382
383                assert!(!v.is_zero());
384
385                let ie = as_IsZero(&v);
386
387                assert!(!ie.is_zero());
388            }
389
390            #[test]
391            fn TEST_ZERO_IN_Box() {
392                let v = Box::new(0.0f64);
393
394                assert!(v.is_zero());
395
396                let ie = as_IsZero(&v);
397
398                assert!(ie.is_zero());
399            }
400
401            #[test]
402            fn TEST_ZERO_IN_Box_ref() {
403                let v = &Box::new(0.0f64);
404
405                assert!(v.is_zero());
406
407                let ie = as_IsZero(v);
408
409                assert!(ie.is_zero());
410            }
411        }
412
413
414        mod TEST_i32 {
415            #![allow(non_snake_case)]
416
417            use super::*;
418
419
420            #[test]
421            fn TEST_ZERO() {
422                let v = 0i32;
423
424                assert!(v.is_zero());
425
426                let ie = as_IsZero(&v);
427
428                assert!(ie.is_zero());
429            }
430
431            #[test]
432            fn TEST_NONZERO() {
433                let v = 123i32;
434
435                assert!(!v.is_zero());
436
437                let ie = as_IsZero(&v);
438
439                assert!(!ie.is_zero());
440            }
441        }
442
443
444        mod TEST_usize {
445            #![allow(non_snake_case)]
446
447            use super::*;
448
449
450            #[test]
451            fn TEST_ZERO() {
452                let v = 0usize;
453
454                assert!(v.is_zero());
455
456                let ie = as_IsZero(&v);
457
458                assert!(ie.is_zero());
459            }
460
461            #[test]
462            fn TEST_NONZERO() {
463                let v = usize::MAX;
464
465                assert!(!v.is_zero());
466
467                let ie = as_IsZero(&v);
468
469                assert!(!ie.is_zero());
470            }
471        }
472    }
473
474
475    #[cfg(feature = "implement-IsZero-for-standard_process_types")]
476    mod TEST_PROCESS_TYPES {
477        #![allow(non_snake_case)]
478    }
479
480
481    #[cfg(feature = "implement-IsZero-for-standard_time_types")]
482    mod TEST_TIME_TYPES {
483        #![allow(non_snake_case)]
484
485        use super::*;
486
487        use std::time::Duration;
488
489
490        mod TEST_Duration {
491            #![allow(non_snake_case)]
492
493            use super::*;
494
495
496            #[test]
497            fn TEST_ZERO() {
498                let d = Duration::from_micros(0);
499
500                assert!(d.is_zero());
501
502                let ie = as_IsZero(&d);
503
504                assert!(ie.is_zero());
505            }
506
507            #[test]
508            fn TEST_NONZERO() {
509                let d = Duration::from_micros(1);
510
511                assert!(!d.is_zero());
512
513                let ie = as_IsZero(&d);
514
515                assert!(!ie.is_zero());
516            }
517        }
518    }
519}
520
521
522// ///////////////////////////// end of file //////////////////////////// //