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