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