@@ -2381,6 +2381,220 @@ impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
2381
2381
// RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
2382
2382
// because underflow would be possible with (..0).into()
2383
2383
2384
+
2385
+ /// An endpoint of a range of keys.
2386
+ ///
2387
+ /// # Examples
2388
+ ///
2389
+ /// `Bound`s are range endpoints:
2390
+ ///
2391
+ /// ```
2392
+ /// #![feature(collections_range)]
2393
+ ///
2394
+ /// use std::collections::range::RangeArgument;
2395
+ /// use std::collections::Bound::*;
2396
+ ///
2397
+ /// assert_eq!((..100).start(), Unbounded);
2398
+ /// assert_eq!((1..12).start(), Included(&1));
2399
+ /// assert_eq!((1..12).end(), Excluded(&12));
2400
+ /// ```
2401
+ ///
2402
+ /// Using a tuple of `Bound`s as an argument to [`BTreeMap::range`].
2403
+ /// Note that in most cases, it's better to use range syntax (`1..5`) instead.
2404
+ ///
2405
+ /// ```
2406
+ /// use std::collections::BTreeMap;
2407
+ /// use std::collections::Bound::{Excluded, Included, Unbounded};
2408
+ ///
2409
+ /// let mut map = BTreeMap::new();
2410
+ /// map.insert(3, "a");
2411
+ /// map.insert(5, "b");
2412
+ /// map.insert(8, "c");
2413
+ ///
2414
+ /// for (key, value) in map.range((Excluded(3), Included(8))) {
2415
+ /// println!("{}: {}", key, value);
2416
+ /// }
2417
+ ///
2418
+ /// assert_eq!(Some((&3, &"a")), map.range((Unbounded, Included(5))).next());
2419
+ /// ```
2420
+ ///
2421
+ /// [`BTreeMap::range`]: btree_map/struct.BTreeMap.html#method.range
2422
+ #[ stable( feature = "collections_bound" , since = "1.17.0" ) ]
2423
+ #[ derive( Clone , Copy , Debug , Hash , PartialEq , Eq ) ]
2424
+ pub enum Bound < T > {
2425
+ /// An inclusive bound.
2426
+ #[ stable( feature = "collections_bound" , since = "1.17.0" ) ]
2427
+ Included ( T ) ,
2428
+ /// An exclusive bound.
2429
+ #[ stable( feature = "collections_bound" , since = "1.17.0" ) ]
2430
+ Excluded ( T ) ,
2431
+ /// An infinite endpoint. Indicates that there is no bound in this direction.
2432
+ #[ stable( feature = "collections_bound" , since = "1.17.0" ) ]
2433
+ Unbounded ,
2434
+ }
2435
+
2436
+ /// `RangeArgument` is implemented by Rust's built-in range types, produced
2437
+ /// by range syntax like `..`, `a..`, `..b` or `c..d`.
2438
+ #[ unstable( feature = "collections_range" ,
2439
+ reason = "waiting for dust to settle on inclusive ranges" ,
2440
+ issue = "30877" ) ]
2441
+ pub trait RangeArgument < T : ?Sized > {
2442
+ /// Start index bound.
2443
+ ///
2444
+ /// Returns the start value as a `Bound`.
2445
+ ///
2446
+ /// # Examples
2447
+ ///
2448
+ /// ```
2449
+ /// #![feature(collections)]
2450
+ /// #![feature(collections_range)]
2451
+ ///
2452
+ /// extern crate collections;
2453
+ ///
2454
+ /// # fn main() {
2455
+ /// use collections::range::RangeArgument;
2456
+ /// use collections::Bound::*;
2457
+ ///
2458
+ /// assert_eq!((..10).start(), Unbounded);
2459
+ /// assert_eq!((3..10).start(), Included(&3));
2460
+ /// # }
2461
+ /// ```
2462
+ fn start ( & self ) -> Bound < & T > ;
2463
+
2464
+ /// End index bound.
2465
+ ///
2466
+ /// Returns the end value as a `Bound`.
2467
+ ///
2468
+ /// # Examples
2469
+ ///
2470
+ /// ```
2471
+ /// #![feature(collections)]
2472
+ /// #![feature(collections_range)]
2473
+ ///
2474
+ /// extern crate collections;
2475
+ ///
2476
+ /// # fn main() {
2477
+ /// use collections::range::RangeArgument;
2478
+ /// use collections::Bound::*;
2479
+ ///
2480
+ /// assert_eq!((3..).end(), Unbounded);
2481
+ /// assert_eq!((3..10).end(), Excluded(&10));
2482
+ /// # }
2483
+ /// ```
2484
+ fn end ( & self ) -> Bound < & T > ;
2485
+ }
2486
+
2487
+ // FIXME add inclusive ranges to RangeArgument
2488
+
2489
+ #[ unstable( feature = "collections_range" ,
2490
+ reason = "waiting for dust to settle on inclusive ranges" ,
2491
+ issue = "30877" ) ]
2492
+ impl < T : ?Sized > RangeArgument < T > for RangeFull {
2493
+ fn start ( & self ) -> Bound < & T > {
2494
+ Bound :: Unbounded
2495
+ }
2496
+ fn end ( & self ) -> Bound < & T > {
2497
+ Bound :: Unbounded
2498
+ }
2499
+ }
2500
+
2501
+ #[ unstable( feature = "collections_range" ,
2502
+ reason = "waiting for dust to settle on inclusive ranges" ,
2503
+ issue = "30877" ) ]
2504
+ impl < T > RangeArgument < T > for RangeFrom < T > {
2505
+ fn start ( & self ) -> Bound < & T > {
2506
+ Bound :: Included ( & self . start )
2507
+ }
2508
+ fn end ( & self ) -> Bound < & T > {
2509
+ Bound :: Unbounded
2510
+ }
2511
+ }
2512
+
2513
+ #[ unstable( feature = "collections_range" ,
2514
+ reason = "waiting for dust to settle on inclusive ranges" ,
2515
+ issue = "30877" ) ]
2516
+ impl < T > RangeArgument < T > for RangeTo < T > {
2517
+ fn start ( & self ) -> Bound < & T > {
2518
+ Bound :: Unbounded
2519
+ }
2520
+ fn end ( & self ) -> Bound < & T > {
2521
+ Bound :: Excluded ( & self . end )
2522
+ }
2523
+ }
2524
+
2525
+ #[ unstable( feature = "collections_range" ,
2526
+ reason = "waiting for dust to settle on inclusive ranges" ,
2527
+ issue = "30877" ) ]
2528
+ impl < T > RangeArgument < T > for Range < T > {
2529
+ fn start ( & self ) -> Bound < & T > {
2530
+ Bound :: Included ( & self . start )
2531
+ }
2532
+ fn end ( & self ) -> Bound < & T > {
2533
+ Bound :: Excluded ( & self . end )
2534
+ }
2535
+ }
2536
+
2537
+ #[ unstable( feature = "inclusive_range" , reason = "recently added, follows RFC" , issue = "28237" ) ]
2538
+ impl < T > RangeArgument < T > for RangeInclusive < T > {
2539
+ fn start ( & self ) -> Bound < & T > {
2540
+ match * self {
2541
+ RangeInclusive :: Empty { ref at } => Bound :: Included ( at) ,
2542
+ RangeInclusive :: NonEmpty { ref start, .. } => Bound :: Included ( start) ,
2543
+ }
2544
+ }
2545
+ fn end ( & self ) -> Bound < & T > {
2546
+ match * self {
2547
+ RangeInclusive :: Empty { ref at } => Bound :: Excluded ( at) ,
2548
+ RangeInclusive :: NonEmpty { ref end, .. } => Bound :: Included ( end) ,
2549
+ }
2550
+ }
2551
+ }
2552
+
2553
+ #[ unstable( feature = "inclusive_range" , reason = "recently added, follows RFC" , issue = "28237" ) ]
2554
+ impl < T > RangeArgument < T > for RangeToInclusive < T > {
2555
+ fn start ( & self ) -> Bound < & T > {
2556
+ Bound :: Unbounded
2557
+ }
2558
+ fn end ( & self ) -> Bound < & T > {
2559
+ Bound :: Included ( & self . end )
2560
+ }
2561
+ }
2562
+
2563
+ #[ unstable( feature = "collections_range" ,
2564
+ reason = "waiting for dust to settle on inclusive ranges" ,
2565
+ issue = "30877" ) ]
2566
+ impl < T > RangeArgument < T > for ( Bound < T > , Bound < T > ) {
2567
+ fn start ( & self ) -> Bound < & T > {
2568
+ match * self {
2569
+ ( Bound :: Included ( ref start) , _) => Bound :: Included ( start) ,
2570
+ ( Bound :: Excluded ( ref start) , _) => Bound :: Excluded ( start) ,
2571
+ ( Bound :: Unbounded , _) => Bound :: Unbounded ,
2572
+ }
2573
+ }
2574
+
2575
+ fn end ( & self ) -> Bound < & T > {
2576
+ match * self {
2577
+ ( _, Bound :: Included ( ref end) ) => Bound :: Included ( end) ,
2578
+ ( _, Bound :: Excluded ( ref end) ) => Bound :: Excluded ( end) ,
2579
+ ( _, Bound :: Unbounded ) => Bound :: Unbounded ,
2580
+ }
2581
+ }
2582
+ }
2583
+
2584
+ #[ unstable( feature = "collections_range" ,
2585
+ reason = "waiting for dust to settle on inclusive ranges" ,
2586
+ issue = "30877" ) ]
2587
+ impl < ' a , T : ?Sized + ' a > RangeArgument < T > for ( Bound < & ' a T > , Bound < & ' a T > ) {
2588
+ fn start ( & self ) -> Bound < & T > {
2589
+ self . 0
2590
+ }
2591
+
2592
+ fn end ( & self ) -> Bound < & T > {
2593
+ self . 1
2594
+ }
2595
+ }
2596
+
2597
+
2384
2598
/// The `Deref` trait is used to specify the functionality of dereferencing
2385
2599
/// operations, like `*v`.
2386
2600
///
0 commit comments