Skip to main content

base_traits/traits/
is_positive.rs

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