@@ -146,7 +146,7 @@ use clone::Clone;
146
146
use cmp:: { PartialEq , Eq } ;
147
147
use default:: Default ;
148
148
use marker:: { Copy , Send , Sync , Sized } ;
149
- use ops:: { Deref , DerefMut , Drop } ;
149
+ use ops:: { Deref , DerefMut , Drop , FnOnce } ;
150
150
use option:: Option ;
151
151
use option:: Option :: { None , Some } ;
152
152
@@ -551,13 +551,161 @@ impl<'b, T: ?Sized> Deref for Ref<'b, T> {
551
551
///
552
552
/// A `Clone` implementation would interfere with the widespread
553
553
/// use of `r.borrow().clone()` to clone the contents of a `RefCell`.
554
+ #[ deprecated( since = "1.2.0" , reason = "moved to a `Ref::clone` associated function" ) ]
554
555
#[ unstable( feature = "core" ,
555
556
reason = "likely to be moved to a method, pending language changes" ) ]
556
557
#[ inline]
557
558
pub fn clone_ref < ' b , T : Clone > ( orig : & Ref < ' b , T > ) -> Ref < ' b , T > {
558
- Ref {
559
- _value : orig. _value ,
560
- _borrow : orig. _borrow . clone ( ) ,
559
+ Ref :: clone ( orig)
560
+ }
561
+
562
+ impl < ' b , T : ?Sized > Ref < ' b , T > {
563
+ /// Copies a `Ref`.
564
+ ///
565
+ /// The `RefCell` is already immutably borrowed, so this cannot fail.
566
+ ///
567
+ /// This is an associated function that needs to be used as `Ref::clone(...)`.
568
+ /// A `Clone` implementation or a method would interfere with the widespread
569
+ /// use of `r.borrow().clone()` to clone the contents of a `RefCell`.
570
+ #[ unstable( feature = "cell_extras" ,
571
+ reason = "likely to be moved to a method, pending language changes" ) ]
572
+ #[ inline]
573
+ pub fn clone ( orig : & Ref < ' b , T > ) -> Ref < ' b , T > {
574
+ Ref {
575
+ _value : orig. _value ,
576
+ _borrow : orig. _borrow . clone ( ) ,
577
+ }
578
+ }
579
+
580
+ /// Make a new `Ref` for a component of the borrowed data.
581
+ ///
582
+ /// The `RefCell` is already immutably borrowed, so this cannot fail.
583
+ ///
584
+ /// This is an associated function that needs to be used as `Ref::map(...)`.
585
+ /// A method would interfere with methods of the same name on the contents of a `RefCell`
586
+ /// used through `Deref`.
587
+ ///
588
+ /// # Example
589
+ ///
590
+ /// ```
591
+ /// # #![feature(cell_extras)]
592
+ /// use std::cell::{RefCell, Ref};
593
+ ///
594
+ /// let c = RefCell::new((5, 'b'));
595
+ /// let b1: Ref<(u32, char)> = c.borrow();
596
+ /// let b2: Ref<u32> = Ref::map(b1, |t| &t.0);
597
+ /// assert_eq!(*b2, 5)
598
+ /// ```
599
+ #[ unstable( feature = "cell_extras" , reason = "recently added" ) ]
600
+ #[ inline]
601
+ pub fn map < U : ?Sized , F > ( orig : Ref < ' b , T > , f : F ) -> Ref < ' b , U >
602
+ where F : FnOnce ( & T ) -> & U
603
+ {
604
+ Ref {
605
+ _value : f ( orig. _value ) ,
606
+ _borrow : orig. _borrow ,
607
+ }
608
+ }
609
+
610
+ /// Make a new `Ref` for a optional component of the borrowed data, e.g. an enum variant.
611
+ ///
612
+ /// The `RefCell` is already immutably borrowed, so this cannot fail.
613
+ ///
614
+ /// This is an associated function that needs to be used as `Ref::filter_map(...)`.
615
+ /// A method would interfere with methods of the same name on the contents of a `RefCell`
616
+ /// used through `Deref`.
617
+ ///
618
+ /// # Example
619
+ ///
620
+ /// ```
621
+ /// # #![feature(cell_extras)]
622
+ /// use std::cell::{RefCell, Ref};
623
+ ///
624
+ /// let c = RefCell::new(Ok(5));
625
+ /// let b1: Ref<Result<u32, ()>> = c.borrow();
626
+ /// let b2: Ref<u32> = Ref::filter_map(b1, |o| o.as_ref().ok()).unwrap();
627
+ /// assert_eq!(*b2, 5)
628
+ /// ```
629
+ #[ unstable( feature = "cell_extras" , reason = "recently added" ) ]
630
+ #[ inline]
631
+ pub fn filter_map < U : ?Sized , F > ( orig : Ref < ' b , T > , f : F ) -> Option < Ref < ' b , U > >
632
+ where F : FnOnce ( & T ) -> Option < & U >
633
+ {
634
+ f ( orig. _value ) . map ( move |new| Ref {
635
+ _value : new,
636
+ _borrow : orig. _borrow ,
637
+ } )
638
+ }
639
+ }
640
+
641
+ impl < ' b , T : ?Sized > RefMut < ' b , T > {
642
+ /// Make a new `RefMut` for a component of the borrowed data, e.g. an enum variant.
643
+ ///
644
+ /// The `RefCell` is already mutably borrowed, so this cannot fail.
645
+ ///
646
+ /// This is an associated function that needs to be used as `RefMut::map(...)`.
647
+ /// A method would interfere with methods of the same name on the contents of a `RefCell`
648
+ /// used through `Deref`.
649
+ ///
650
+ /// # Example
651
+ ///
652
+ /// ```
653
+ /// # #![feature(cell_extras)]
654
+ /// use std::cell::{RefCell, RefMut};
655
+ ///
656
+ /// let c = RefCell::new((5, 'b'));
657
+ /// {
658
+ /// let b1: RefMut<(u32, char)> = c.borrow_mut();
659
+ /// let mut b2: RefMut<u32> = RefMut::map(b1, |t| &mut t.0);
660
+ /// assert_eq!(*b2, 5);
661
+ /// *b2 = 42;
662
+ /// }
663
+ /// assert_eq!(*c.borrow(), (42, 'b'));
664
+ /// ```
665
+ #[ unstable( feature = "cell_extras" , reason = "recently added" ) ]
666
+ #[ inline]
667
+ pub fn map < U : ?Sized , F > ( orig : RefMut < ' b , T > , f : F ) -> RefMut < ' b , U >
668
+ where F : FnOnce ( & mut T ) -> & mut U
669
+ {
670
+ RefMut {
671
+ _value : f ( orig. _value ) ,
672
+ _borrow : orig. _borrow ,
673
+ }
674
+ }
675
+
676
+ /// Make a new `RefMut` for a optional component of the borrowed data, e.g. an enum variant.
677
+ ///
678
+ /// The `RefCell` is already mutably borrowed, so this cannot fail.
679
+ ///
680
+ /// This is an associated function that needs to be used as `RefMut::filter_map(...)`.
681
+ /// A method would interfere with methods of the same name on the contents of a `RefCell`
682
+ /// used through `Deref`.
683
+ ///
684
+ /// # Example
685
+ ///
686
+ /// ```
687
+ /// # #![feature(cell_extras)]
688
+ /// use std::cell::{RefCell, RefMut};
689
+ ///
690
+ /// let c = RefCell::new(Ok(5));
691
+ /// {
692
+ /// let b1: RefMut<Result<u32, ()>> = c.borrow_mut();
693
+ /// let mut b2: RefMut<u32> = RefMut::filter_map(b1, |o| o.as_mut().ok()).unwrap();
694
+ /// assert_eq!(*b2, 5);
695
+ /// *b2 = 42;
696
+ /// }
697
+ /// assert_eq!(*c.borrow(), Ok(42));
698
+ /// ```
699
+ #[ unstable( feature = "cell_extras" , reason = "recently added" ) ]
700
+ #[ inline]
701
+ pub fn filter_map < U : ?Sized , F > ( orig : RefMut < ' b , T > , f : F ) -> Option < RefMut < ' b , U > >
702
+ where F : FnOnce ( & mut T ) -> Option < & mut U >
703
+ {
704
+ let RefMut { _value, _borrow } = orig;
705
+ f ( _value) . map ( move |new| RefMut {
706
+ _value : new,
707
+ _borrow : _borrow,
708
+ } )
561
709
}
562
710
}
563
711
0 commit comments