1pub 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