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(all(not(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(all(not(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
108    // NonZero<T>
109
110    /*
111    impl<T> super::IsZero for std_num::NonZero<T>
112    {
113        fn is_zero(&self) -> bool {
114            false
115        }
116    }
117     */
118}
119
120
121#[cfg(all(not(feature = "nostd"), feature = "implement-IsZero-for-standard_process_types"))]
122mod impl_for_std_process_types {
123    #![allow(non_snake_case)]
124
125    use std::process as std_process;
126
127
128    // ExitStatus
129
130    impl super::IsZero for std_process::ExitStatus
131    {
132        fn is_zero(&self) -> bool {
133            match self.code() {
134                Some(ec) => {
135                    0 == ec
136                },
137                None => false,
138            }
139        }
140    }
141}
142
143
144#[cfg(all(not(feature = "nostd"), feature = "implement-IsZero-for-standard_time_types"))]
145mod impl_for_std_time_types {
146    #![allow(non_snake_case)]
147
148    use std::time as std_time;
149
150
151    mod isolate_{
152        #![allow(non_snake_case)]
153
154        use std::time as std_time;
155
156
157        #[inline]
158        pub(super) fn get_is_zero_Duration_(d : &std_time::Duration) -> bool {
159            d.is_zero()
160        }
161    }
162
163
164    // Duration
165
166    impl super::IsZero for std_time::Duration {
167        fn is_zero(&self) -> bool {
168            isolate_::get_is_zero_Duration_(self)
169        }
170    }
171}
172
173
174#[cfg(test)]
175mod tests {
176    #![allow(non_snake_case)]
177
178    use super::IsZero;
179
180    use std::rc::Rc;
181
182
183    #[allow(unused)]
184    fn as_IsZero<T : IsZero>(t : &T) -> &impl IsZero {
185        t
186    }
187
188
189    mod TEST_CUSTOM_TYPE {
190        #![allow(non_snake_case)]
191
192        use super::*;
193
194
195        #[derive(Debug)]
196        struct CustomType {
197            value : i32,
198        }
199
200        impl IsZero for CustomType {
201            fn is_zero(&self) -> bool {
202                0 == self.value
203            }
204        }
205
206
207        #[test]
208        fn TEST_WHEN_ZERO_ELEMENTS() {
209            let ct = CustomType { value : 0 };
210
211            assert!(ct.is_zero());
212
213            let ct = &ct;
214
215            assert!(ct.is_zero());
216        }
217
218        #[test]
219        fn TEST_WHEN_HAVE_ELEMENTS() {
220            let ct = CustomType { value : 1 };
221
222            assert!(!ct.is_zero());
223
224            let ct = &ct;
225
226            assert!(!ct.is_zero());
227        }
228
229        #[test]
230        fn TEST_WHEN_ZERO_ELEMENTS_IN_Box() {
231            {
232                let ct = Box::new(CustomType { value : 0 });
233
234                assert!(ct.is_zero());
235
236                let ct = &ct;
237
238                assert!(ct.is_zero());
239            }
240
241            {
242                let ct = &Box::new(CustomType { value : 0 });
243
244                assert!(ct.is_zero());
245
246                let ct = &ct;
247
248                assert!(ct.is_zero());
249            }
250
251            {
252                let ct = Box::new(&CustomType { value : 0 });
253
254                assert!(ct.is_zero());
255
256                let ct = &ct;
257
258                assert!(ct.is_zero());
259            }
260
261            {
262                let ct = &Box::new(&CustomType { value : 0 });
263
264                assert!(ct.is_zero());
265
266                let ct = &ct;
267
268                assert!(ct.is_zero());
269            }
270        }
271
272        #[test]
273        fn TEST_WHEN_ZERO_ELEMENTS_IN_Rc() {
274            {
275                let ct = Rc::new(CustomType { value : 0 });
276
277                assert!(ct.is_zero());
278
279                let ct = &ct;
280
281                assert!(ct.is_zero());
282            }
283
284            {
285                let ct = &Rc::new(CustomType { value : 0 });
286
287                assert!(ct.is_zero());
288
289                let ct = &ct;
290
291                assert!(ct.is_zero());
292            }
293
294            {
295                let ct = Rc::new(&CustomType { value : 0 });
296
297                assert!(ct.is_zero());
298
299                let ct = &ct;
300
301                assert!(ct.is_zero());
302            }
303
304            {
305                let ct = &Rc::new(&CustomType { value : 0 });
306
307                assert!(ct.is_zero());
308
309                let ct = &ct;
310
311                assert!(ct.is_zero());
312            }
313        }
314    }
315
316
317    #[cfg(feature = "implement-IsZero-for-built_ins")]
318    mod TEST_BUILTIN_TYPES {
319        #![allow(non_snake_case)]
320
321        use super::*;
322
323
324        mod TEST_char {
325            #![allow(non_snake_case)]
326
327            use super::*;
328
329
330            #[test]
331            fn TEST_ZERO() {
332
333                {
334                    let c = '\0';
335
336                    assert!(c.is_zero());
337
338                    let ie = as_IsZero(&c);
339
340                    assert!(ie.is_zero());
341                }
342
343                {
344                    let c = '\u{0000}';
345
346                    assert!(c.is_zero());
347
348                    let ie = as_IsZero(&c);
349
350                    assert!(ie.is_zero());
351                }
352            }
353
354            #[test]
355            fn TEST_NONZERO() {
356                let c = 'a';
357
358                assert!(!c.is_zero());
359
360                let ie = as_IsZero(&c);
361
362                assert!(!ie.is_zero());
363            }
364        }
365
366
367        mod TEST_f64 {
368            #![allow(non_snake_case)]
369
370            use super::*;
371
372
373            #[test]
374            fn TEST_ZERO() {
375                let v = 0.0f64;
376
377                assert!(v.is_zero());
378
379                let ie = as_IsZero(&v);
380
381                assert!(ie.is_zero());
382            }
383
384            #[test]
385            fn TEST_NONZERO() {
386                let v = -123.456f64;
387
388                assert!(!v.is_zero());
389
390                let ie = as_IsZero(&v);
391
392                assert!(!ie.is_zero());
393            }
394
395            #[test]
396            fn TEST_ZERO_IN_Box() {
397                let v = Box::new(0.0f64);
398
399                assert!(v.is_zero());
400
401                let ie = as_IsZero(&v);
402
403                assert!(ie.is_zero());
404            }
405
406            #[test]
407            fn TEST_ZERO_IN_Box_ref() {
408                let v = &Box::new(0.0f64);
409
410                assert!(v.is_zero());
411
412                let ie = as_IsZero(v);
413
414                assert!(ie.is_zero());
415            }
416        }
417
418
419        mod TEST_i32 {
420            #![allow(non_snake_case)]
421
422            use super::*;
423
424
425            #[test]
426            fn TEST_ZERO() {
427                let v = 0i32;
428
429                assert!(v.is_zero());
430
431                let ie = as_IsZero(&v);
432
433                assert!(ie.is_zero());
434            }
435
436            #[test]
437            fn TEST_NONZERO() {
438                let v = 123i32;
439
440                assert!(!v.is_zero());
441
442                let ie = as_IsZero(&v);
443
444                assert!(!ie.is_zero());
445            }
446        }
447
448
449        mod TEST_usize {
450            #![allow(non_snake_case)]
451
452            use super::*;
453
454
455            #[test]
456            fn TEST_ZERO() {
457                let v = 0usize;
458
459                assert!(v.is_zero());
460
461                let ie = as_IsZero(&v);
462
463                assert!(ie.is_zero());
464            }
465
466            #[test]
467            fn TEST_NONZERO() {
468                let v = usize::MAX;
469
470                assert!(!v.is_zero());
471
472                let ie = as_IsZero(&v);
473
474                assert!(!ie.is_zero());
475            }
476        }
477    }
478
479
480    #[cfg(feature = "implement-IsZero-for-standard_process_types")]
481    mod TEST_PROCESS_TYPES {
482        #![allow(non_snake_case)]
483
484    }
485
486
487    #[cfg(feature = "implement-IsZero-for-standard_time_types")]
488    mod TEST_TIME_TYPES {
489        #![allow(non_snake_case)]
490
491        use super::*;
492
493        use std::time::{
494            Duration,
495        };
496
497
498        mod TEST_Duration {
499            #![allow(non_snake_case)]
500
501            use super::*;
502
503
504            #[test]
505            fn TEST_ZERO() {
506                let d = Duration::from_micros(0);
507
508                assert!(d.is_zero());
509
510                let ie = as_IsZero(&d);
511
512                assert!(ie.is_zero());
513            }
514
515            #[test]
516            fn TEST_NONZERO() {
517                let d = Duration::from_micros(1);
518
519                assert!(!d.is_zero());
520
521                let ie = as_IsZero(&d);
522
523                assert!(!ie.is_zero());
524            }
525        }
526    }
527}
528
529
530// ///////////////////////////// end of file //////////////////////////// //
531