@@ -1880,9 +1880,6 @@ impl FromIterator<String> for String {
18801880 fn from_iter < I : IntoIterator < Item = String > > ( iter : I ) -> String {
18811881 let mut iterator = iter. into_iter ( ) ;
18821882
1883- // Because we're iterating over `String`s, we can avoid at least
1884- // one allocation by getting the first string from the iterator
1885- // and appending to it all the subsequent strings.
18861883 match iterator. next ( ) {
18871884 None => String :: new ( ) ,
18881885 Some ( mut buf) => {
@@ -1897,9 +1894,15 @@ impl FromIterator<String> for String {
18971894#[ stable( feature = "box_str2" , since = "1.45.0" ) ]
18981895impl FromIterator < Box < str > > for String {
18991896 fn from_iter < I : IntoIterator < Item = Box < str > > > ( iter : I ) -> String {
1900- let mut buf = String :: new ( ) ;
1901- buf. extend ( iter) ;
1902- buf
1897+ let mut iterator = iter. into_iter ( ) ;
1898+ match iterator. next ( ) {
1899+ None => String :: new ( ) ,
1900+ Some ( buf) => {
1901+ let mut buf = buf. into_string ( ) ;
1902+ buf. extend ( iter) ;
1903+ buf
1904+ }
1905+ }
19031906 }
19041907}
19051908
@@ -1909,9 +1912,6 @@ impl<'a> FromIterator<Cow<'a, str>> for String {
19091912 fn from_iter < I : IntoIterator < Item = Cow < ' a , str > > > ( iter : I ) -> String {
19101913 let mut iterator = iter. into_iter ( ) ;
19111914
1912- // Because we're iterating over CoWs, we can (potentially) avoid at least
1913- // one allocation by getting the first item and appending to it all the
1914- // subsequent items.
19151915 match iterator. next ( ) {
19161916 None => String :: new ( ) ,
19171917 Some ( cow) => {
@@ -1979,33 +1979,49 @@ impl<'a> Extend<&'a str> for String {
19791979#[ stable( feature = "box_str2" , since = "1.45.0" ) ]
19801980impl Extend < Box < str > > for String {
19811981 fn extend < I : IntoIterator < Item = Box < str > > > ( & mut self , iter : I ) {
1982- iter. into_iter ( ) . for_each ( move |s| self . push_str ( & s) ) ;
1982+ iter. into_iter ( ) . for_each ( move |s| self . extend_one ( s) ) ;
1983+ }
1984+
1985+ #[ inline]
1986+ fn extend_one ( & mut self , s : Box < str > ) {
1987+ if self . is_empty ( ) && s. len ( ) >= self . capacity ( ) {
1988+ * self = s. into_string ( ) ;
1989+ } else {
1990+ self . push_str ( & s) ;
1991+ }
19831992 }
19841993}
19851994
19861995#[ cfg( not( no_global_oom_handling) ) ]
19871996#[ stable( feature = "extend_string" , since = "1.4.0" ) ]
19881997impl Extend < String > for String {
19891998 fn extend < I : IntoIterator < Item = String > > ( & mut self , iter : I ) {
1990- iter. into_iter ( ) . for_each ( move |s| self . push_str ( & s) ) ;
1999+ iter. into_iter ( ) . for_each ( move |s| self . extend_one ( s) )
19912000 }
19922001
19932002 #[ inline]
19942003 fn extend_one ( & mut self , s : String ) {
1995- self . push_str ( & s) ;
2004+ if self . is_empty ( ) && s. capacity ( ) >= self . capacity ( ) {
2005+ * self = s
2006+ } else {
2007+ self . push_str ( & s)
2008+ }
19962009 }
19972010}
19982011
19992012#[ cfg( not( no_global_oom_handling) ) ]
20002013#[ stable( feature = "herd_cows" , since = "1.19.0" ) ]
20012014impl < ' a > Extend < Cow < ' a , str > > for String {
20022015 fn extend < I : IntoIterator < Item = Cow < ' a , str > > > ( & mut self , iter : I ) {
2003- iter. into_iter ( ) . for_each ( move |s| self . push_str ( & s) ) ;
2016+ iter. into_iter ( ) . for_each ( move |s| self . extend_one ( s) )
20042017 }
20052018
20062019 #[ inline]
20072020 fn extend_one ( & mut self , s : Cow < ' a , str > ) {
2008- self . push_str ( & s) ;
2021+ match s {
2022+ Cow :: Owned ( s) => self . extend_one ( s) ,
2023+ Cow :: Borrowed ( s) => self . push_str ( s) ,
2024+ }
20092025 }
20102026}
20112027
0 commit comments