@@ -146,7 +146,7 @@ use clone::Clone;
146146use cmp:: { PartialEq , Eq } ;
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
@@ -576,6 +576,137 @@ impl<'b, T: ?Sized> Ref<'b, T> {
576576 _borrow : orig. _borrow . clone ( ) ,
577577 }
578578 }
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+ } )
709+ }
579710}
580711
581712struct BorrowRefMut < ' b > {
0 commit comments