1#![ cfg_attr( feature = "no_std", no_std ) ]
2#![ doc( html_logo_url = "https://raw.githubusercontent.com/Wandalen/wTools/master/asset/img/logo_v3_trans_square.png" ) ]
3#![ doc( html_favicon_url = "https://raw.githubusercontent.com/Wandalen/wTools/alpha/asset/img/logo_v3_trans_square_icon_small_v2.ico" ) ]
4#![ doc( html_root_url = "https://docs.rs/winterval/latest/winterval/" ) ]
5#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ]
6
7#[ cfg( feature = "enabled" ) ]
9mod private
10{
11
12 #[ doc( inline ) ]
13 #[ allow( unused_imports ) ]
14 pub use core::ops::Bound;
15 #[ doc( inline ) ]
16 #[ allow( unused_imports ) ]
17 pub use core::ops::RangeBounds;
18
19 use core::cmp::{ PartialEq, Eq };
20 use core::ops::{ Sub, Add };
21
22 pub trait BoundExt< T >
26 where
27 T : EndPointTrait< T >,
28 isize : Into< T >,
29 {
30 fn into_left_closed( &self ) -> T;
32 fn into_right_closed( &self ) -> T;
34 }
35
36 impl< T > BoundExt< T > for Bound< T >
37 where
38 T : EndPointTrait< T >,
39 isize : Into< T >,
40 {
41 #[ inline( always ) ]
42 fn into_left_closed( &self ) -> T
43 {
44 match self
45 {
46 Bound::Included( v ) => *v,
47 Bound::Excluded( v ) => *v + 1.into(),
48 Bound::Unbounded => 0.into(),
49 }
51 }
52 #[ inline( always ) ]
53 fn into_right_closed( &self ) -> T
54 {
55 match self
56 {
57 Bound::Included( v ) => *v,
58 Bound::Excluded( v ) => *v - 1.into(),
59 Bound::Unbounded => isize::MAX.into(),
60 }
61 }
62 }
63
64 pub trait EndPointTrait< T >
67 where
68 Self : core::cmp::PartialOrd + Sub< Output = T > + Add< Output = T > + Clone + Copy + Sized,
69 {
70 }
71
72 impl< T, All > EndPointTrait< T > for All
73 where
74 Self : core::cmp::PartialOrd + Sub< Output = T > + Add< Output = T > + Clone + Copy + Sized,
75 {
76 }
77
78 pub trait NonIterableInterval< T = isize >
88 where
89 T : EndPointTrait< T >,
91 isize : Into< T >,
92 {
93
94 fn left( &self ) -> Bound< T >;
96 fn right( &self ) -> Bound< T >;
98 #[ inline( always ) ]
101 fn bounds( &self ) -> ( Bound< T >, Bound< T > )
102 {
103 ( self.left(), self.right() )
104 }
105
106 #[ inline( always ) ]
108 fn closed_left( &self ) -> T
109 {
110 self.left().into_left_closed()
111 }
112 #[ inline( always ) ]
114 fn closed_right( &self ) -> T
115 {
116 self.right().into_right_closed()
117 }
118 #[ inline( always ) ]
120 fn closed_len( &self ) -> T
121 {
122 let one : T = 1.into();
123 self.closed_right() - self.closed_left() + one
124 }
125 #[ inline( always ) ]
127 fn closed( &self ) -> ( T, T )
128 {
129 ( self.closed_left(), self.closed_right() )
130 }
131
132 #[ inline( always ) ]
134 fn canonical( &self ) -> Interval< T >
135 {
136 Interval::new( self.left(), self.right() )
137 }
138
139 }
140
141 pub trait IterableInterval< T = isize >
149 where
150 Self : IntoIterator< Item = T > + NonIterableInterval< T >,
151 T : EndPointTrait< T >,
152 isize : Into< T >,
153 {
154 }
155
156 impl< T, NonIterableIntervalType > IterableInterval< T >
157 for NonIterableIntervalType
158 where
159 NonIterableIntervalType : NonIterableInterval< T >,
160 Self : IntoIterator< Item = T > + NonIterableInterval< T >,
161 T : EndPointTrait< T >,
162 isize : Into< T >,
163 {
164 }
165
166 #[ derive( PartialEq, Eq, Debug, Clone, Copy ) ]
173 pub struct Interval< T = isize >
174 where
175 T : EndPointTrait< T >,
176 isize : Into< T >,
177 {
178 _left : Bound< T >,
179 _right : Bound< T >,
180 }
181
182 impl< T > Interval< T >
183 where
184 T : EndPointTrait< T >,
185 isize : Into< T >,
186 {
187 pub fn new( left : Bound< T >, right : Bound< T > ) -> Self
189 {
190 Self { _left : left, _right : right }
191 }
192 #[ inline( always ) ]
194 pub fn iter< It >( &self ) -> impl Iterator< Item = T >
195 {
196 ( &self ).into_iter()
197 }
198 }
199
200 impl< T > IntoIterator for Interval< T >
205 where
206 T : EndPointTrait< T >,
207 isize : Into< T >,
208 {
209 type Item = T;
210 type IntoIter = IntervalIterator< T >;
211 #[ inline( always ) ]
212 fn into_iter( self ) -> Self::IntoIter
213 {
214 IntervalIterator::new( self )
215 }
216 }
217
218 impl< T > IntoIterator for &Interval< T >
219 where
220 T : EndPointTrait< T >,
221 isize : Into< T >,
222 {
223 type Item = T;
224 type IntoIter = IntervalIterator< T >;
225 #[ inline( always ) ]
226 fn into_iter( self ) -> Self::IntoIter
227 {
228 IntervalIterator::new( *self )
229 }
230 }
231
232 #[ derive( Debug ) ]
233 pub struct IntervalIterator< T >
234 where
235 T : EndPointTrait< T >,
236 isize : Into< T >,
237 {
238 current : T,
239 right : T,
240 }
241
242 impl< T > IntervalIterator< T >
243 where
244 T : EndPointTrait< T >,
245 isize : Into< T >,
246 {
247 pub fn new( ins : Interval< T > ) -> Self
249 {
250 let current = ins._left.into_left_closed();
251 let right = ins._right.into_right_closed();
252 Self { current, right }
253 }
254 }
255
256 impl< T > Iterator for IntervalIterator< T >
257 where
258 T : EndPointTrait< T >,
259 isize : Into< T >,
260 {
261 type Item = T;
262 #[ inline( always ) ]
263 fn next( &mut self ) -> Option< Self::Item >
264 {
265 if self.current <= self.right
266 {
267 let result = Some( self.current );
268 self.current = self.current + 1.into();
269 result
270 }
271 else
272 {
273 None
274 }
275 }
276 }
277
278 impl< T > NonIterableInterval< T >
302 for Interval< T >
303 where
304 T : EndPointTrait< T >,
305 isize : Into< T >,
306 {
307 #[ inline( always ) ]
308 fn left( &self ) -> Bound< T >
309 {
310 self._left
311 }
312 #[ inline( always ) ]
313 fn right( &self ) -> Bound< T >
314 {
315 self._right
316 }
317 }
318
319 impl< T > NonIterableInterval< T >
320 for core::ops::Range< T >
321 where
322 T : EndPointTrait< T >,
323 isize : Into< T >,
324 {
325 #[ inline( always ) ]
326 fn left( &self ) -> Bound< T >
327 {
328 Bound::Included( self.start )
329 }
330 #[ inline( always ) ]
331 fn right( &self ) -> Bound< T >
332 {
333 Bound::Excluded( self.end )
334 }
335 }
336
337 impl< T > NonIterableInterval< T >
338 for core::ops::RangeInclusive< T >
339 where
340 T : EndPointTrait< T >,
341 isize : Into< T >,
342 {
343 #[ inline( always ) ]
344 fn left( &self ) -> Bound< T >
345 {
346 Bound::Included( *self.start() )
347 }
348 #[ inline( always ) ]
349 fn right( &self ) -> Bound< T >
350 {
351 Bound::Included( *self.end() )
352 }
353 }
354
355 impl< T > NonIterableInterval< T >
356 for core::ops::RangeTo< T >
357 where
358 T : EndPointTrait< T >,
359 isize : Into< T >,
360 {
361 #[ inline( always ) ]
362 fn left( &self ) -> Bound< T >
363 {
364 Bound::Unbounded
365 }
366 #[ inline( always ) ]
367 fn right( &self ) -> Bound< T >
368 {
369 Bound::Excluded( self.end )
370 }
371 }
372
373 impl< T > NonIterableInterval< T >
374 for core::ops::RangeToInclusive< T >
375 where
376 T : EndPointTrait< T >,
377 isize : Into< T >,
378 {
379 #[ inline( always ) ]
380 fn left( &self ) -> Bound< T >
381 {
382 Bound::Unbounded
383 }
384 #[ inline( always ) ]
385 fn right( &self ) -> Bound< T >
386 {
387 Bound::Included( self.end )
388 }
389 }
390
391 impl< T > NonIterableInterval< T >
392 for core::ops::RangeFrom< T >
393 where
394 T : EndPointTrait< T >,
395 isize : Into< T >,
396 {
397 #[ inline( always ) ]
398 fn left( &self ) -> Bound< T >
399 {
400 Bound::Included( self.start )
401 }
402 #[ inline( always ) ]
403 fn right( &self ) -> Bound< T >
404 {
405 Bound::Unbounded
406 }
407 }
408
409 impl< T > NonIterableInterval< T >
410 for core::ops::RangeFull
411 where
412 T : EndPointTrait< T >,
413 isize : Into< T >,
414 {
415 #[ inline( always ) ]
416 fn left( &self ) -> Bound< T >
417 {
418 Bound::Unbounded
419 }
420 #[ inline( always ) ]
421 fn right( &self ) -> Bound< T >
422 {
423 Bound::Unbounded
424 }
425 }
426
427 impl< T > NonIterableInterval< T >
428 for ( T, T )
429 where
430 T : EndPointTrait< T >,
431 isize : Into< T >,
432 {
433 #[ inline( always ) ]
434 fn left( &self ) -> Bound< T >
435 {
436 Bound::Included( self.0 )
437 }
438 #[ inline( always ) ]
439 fn right( &self ) -> Bound< T >
440 {
441 Bound::Included( self.1 )
442 }
443 }
444
445 impl< T > NonIterableInterval< T >
446 for ( Bound< T >, Bound< T > )
447 where
448 T : EndPointTrait< T >,
449 isize : Into< T >,
450 {
451 #[ inline( always ) ]
452 fn left( &self ) -> Bound< T >
453 {
454 self.0
455 }
456 #[ inline( always ) ]
457 fn right( &self ) -> Bound< T >
458 {
459 self.1
460 }
461 }
462
463 impl< T > NonIterableInterval< T >
464 for [ T ; 2 ]
465 where
466 T : EndPointTrait< T >,
467 isize : Into< T >,
468 {
469 #[ inline( always ) ]
470 fn left( &self ) -> Bound< T >
471 {
472 Bound::Included( self[ 0 ] )
473 }
474 #[ inline( always ) ]
475 fn right( &self ) -> Bound< T >
476 {
477 Bound::Included( self[ 1 ] )
478 }
479 }
480
481 impl< T > NonIterableInterval< T >
482 for [ Bound< T > ; 2 ]
483 where
484 T : EndPointTrait< T >,
485 isize : Into< T >,
486 {
487 #[ inline( always ) ]
488 fn left( &self ) -> Bound< T >
489 {
490 self[ 0 ]
491 }
492 #[ inline( always ) ]
493 fn right( &self ) -> Bound< T >
494 {
495 self[ 1 ]
496 }
497 }
498
499 macro_rules! impl_interval_from
504 {
505 {} => {};
506 {
507 $Type : ty
508 }
509 =>
510 {
511 impl< T > From< $Type >
512 for Interval< T >
513 where
514 T : EndPointTrait< T >,
515 isize : Into< T >,
516 {
517 #[ inline( always ) ]
518 fn from( src : $Type ) -> Self
519 {
520 let _left = NonIterableInterval::left( &src );
521 let _right = NonIterableInterval::right( &src );
522 Self { _left, _right }
523 }
524 }
525 };
526 {
527 $Type : ty
528 , $( $Rest : tt )*
529 }
530 =>
531 {
532 impl_interval_from!{ $Type }
533 impl_interval_from!{ $( $Rest )* }
534 };
535 }
536
537 impl_interval_from!
538 {
539 core::ops::Range< T >,
540 core::ops::RangeInclusive< T >,
541 core::ops::RangeTo< T >,
542 core::ops::RangeToInclusive< T >,
543 core::ops::RangeFrom< T >,
544 core::ops::RangeFull,
545 ( T, T ),
546 ( Bound< T >, Bound< T > ),
547 [ T ; 2 ],
548 [ Bound< T > ; 2 ],
549 }
550
551 pub trait IntoInterval< T >
553 where
554 T : EndPointTrait< T >,
555 isize : Into< T >,
556 {
557 fn into_interval( self ) -> Interval< T >;
559 }
560
561 impl< T, All > IntoInterval< T > for All
562 where
563 T : EndPointTrait< T >,
564 isize : Into< T >,
565 Interval< T > : From< Self >,
566 {
567 fn into_interval( self ) -> Interval< T >
568 {
569 From::from( self )
570 }
571 }
572
573}
574
575#[ doc( inline ) ]
576#[ allow( unused_imports ) ]
577#[ cfg( feature = "enabled" ) ]
578pub use own::*;
580
581#[ cfg( feature = "enabled" ) ]
583#[ allow( unused_imports ) ]
584pub mod own
585{
586 use super::*;
587 #[ doc( inline ) ]
588 pub use orphan::*;
589}
590
591#[ cfg( feature = "enabled" ) ]
593#[ allow( unused_imports ) ]
594pub mod orphan
595{
596 use super::*;
597 #[ doc( inline ) ]
598 pub use exposed::*;
599}
600
601#[ cfg( feature = "enabled" ) ]
603#[ allow( unused_imports ) ]
604pub mod exposed
605{
606 use super::*;
607 #[ doc( inline ) ]
608 pub use prelude::*;
609 #[ doc( inline ) ]
610 pub use private::
611 {
612 Bound,
613 BoundExt,
614 EndPointTrait,
615 Interval,
616 };
620}
621
622#[ allow( unused_imports ) ]
624#[ cfg( feature = "enabled" ) ]
630#[ allow( unused_imports ) ]
631pub mod prelude
632{
633 use super::*;
634 #[ doc( inline ) ]
635 pub use private::
636 {
637 IterableInterval,
638 NonIterableInterval,
639 IntoInterval,
640 };
641}