@@ -26,7 +26,7 @@ use clone::Clone;
2626use cmp:: { TotalOrd , Ordering , Less , Equal , Greater } ;
2727use container:: Container ;
2828use iter:: Times ;
29- use iterator:: { Iterator , IteratorUtil , FilterIterator } ;
29+ use iterator:: { Iterator , IteratorUtil , FilterIterator , AdditiveIterator } ;
3030use libc;
3131use option:: { None , Option , Some } ;
3232use old_iter:: { BaseIter , EqIter } ;
@@ -160,96 +160,22 @@ pub trait StrVector {
160160 pub fn connect ( & self , sep : & str ) -> ~str ;
161161}
162162
163- impl < ' self > StrVector for & ' self [ ~ str ] {
163+ impl < ' self , S : Str > StrVector for & ' self [ S ] {
164164 /// Concatenate a vector of strings.
165165 pub fn concat ( & self ) -> ~str {
166166 if self . is_empty ( ) { return ~""; }
167167
168- let mut len = 0 ;
169- for self . each |ss| {
170- len += ss. len ( ) ;
171- }
172- let mut s = ~"";
168+ let len = self . iter ( ) . transform ( |s| s. as_slice ( ) . len ( ) ) . sum ( ) ;
173169
174- s. reserve ( len) ;
175-
176- unsafe {
177- do as_buf ( s) |buf, _| {
178- let mut buf = :: cast:: transmute_mut_unsafe ( buf) ;
179- for self . each |ss| {
180- do as_buf ( * ss) |ssbuf, sslen| {
181- let sslen = sslen - 1 ;
182- ptr:: copy_memory ( buf, ssbuf, sslen) ;
183- buf = buf. offset ( sslen) ;
184- }
185- }
186- }
187- raw:: set_len ( & mut s, len) ;
188- }
189- s
190- }
191-
192- /// Concatenate a vector of strings, placing a given separator between each.
193- pub fn connect ( & self , sep : & str ) -> ~str {
194- if self . is_empty ( ) { return ~""; }
195-
196- // concat is faster
197- if sep. is_empty ( ) { return self . concat ( ) ; }
198-
199- // this is wrong without the guarantee that `self` is non-empty
200- let mut len = sep. len ( ) * ( self . len ( ) - 1 ) ;
201- for self . each |ss| {
202- len += ss. len ( ) ;
203- }
204- let mut s = ~"";
205- let mut first = true ;
206-
207- s. reserve ( len) ;
208-
209- unsafe {
210- do as_buf ( s) |buf, _| {
211- do as_buf ( sep) |sepbuf, seplen| {
212- let seplen = seplen - 1 ;
213- let mut buf = :: cast:: transmute_mut_unsafe ( buf) ;
214- for self . each |ss| {
215- do as_buf( * ss) |ssbuf, sslen| {
216- let sslen = sslen - 1 ;
217- if first {
218- first = false ;
219- } else {
220- ptr:: copy_memory ( buf, sepbuf, seplen) ;
221- buf = buf. offset ( seplen) ;
222- }
223- ptr:: copy_memory ( buf, ssbuf, sslen) ;
224- buf = buf. offset ( sslen) ;
225- }
226- }
227- }
228- }
229- raw:: set_len ( & mut s, len) ;
230- }
231- s
232- }
233- }
234-
235- impl < ' self > StrVector for & ' self [ & ' self str ] {
236- /// Concatenate a vector of strings.
237- pub fn concat ( & self ) -> ~str {
238- if self . is_empty ( ) { return ~""; }
239-
240- let mut len = 0 ;
241- for self . each |ss| {
242- len += ss. len ( ) ;
243- }
244170 let mut s = ~"";
245171
246172 s. reserve ( len) ;
247173
248174 unsafe {
249175 do as_buf ( s) |buf, _| {
250176 let mut buf = :: cast:: transmute_mut_unsafe ( buf) ;
251- for self . each |ss| {
252- do as_buf ( * ss ) |ssbuf, sslen| {
177+ for self . iter ( ) . advance |ss| {
178+ do as_buf ( ss . as_slice ( ) ) |ssbuf, sslen| {
253179 let sslen = sslen - 1 ;
254180 ptr:: copy_memory ( buf, ssbuf, sslen) ;
255181 buf = buf. offset ( sslen) ;
@@ -269,10 +195,8 @@ impl<'self> StrVector for &'self [&'self str] {
269195 if sep. is_empty ( ) { return self . concat ( ) ; }
270196
271197 // this is wrong without the guarantee that `self` is non-empty
272- let mut len = sep. len ( ) * ( self . len ( ) - 1 ) ;
273- for self . each |ss| {
274- len += ss. len ( ) ;
275- }
198+ let len = sep. len ( ) * ( self . len ( ) - 1 )
199+ + self . iter ( ) . transform ( |s| s. as_slice ( ) . len ( ) ) . sum ( ) ;
276200 let mut s = ~"";
277201 let mut first = true ;
278202
@@ -283,8 +207,8 @@ impl<'self> StrVector for &'self [&'self str] {
283207 do as_buf ( sep) |sepbuf, seplen| {
284208 let seplen = seplen - 1 ;
285209 let mut buf = :: cast:: transmute_mut_unsafe ( buf) ;
286- for self . each |ss| {
287- do as_buf( * ss ) |ssbuf, sslen| {
210+ for self . iter ( ) . advance |ss| {
211+ do as_buf( ss . as_slice ( ) ) |ssbuf, sslen| {
288212 let sslen = sslen - 1 ;
289213 if first {
290214 first = false ;
@@ -1267,6 +1191,29 @@ pub mod traits {
12671191#[cfg(test)]
12681192pub mod traits {}
12691193
1194+ /// Any string that can be represented as a slice
1195+ pub trait Str {
1196+ /// Work with `self` as a slice.
1197+ fn as_slice<'a>(&'a self) -> &'a str;
1198+ }
1199+
1200+ impl<'self> Str for &'self str {
1201+ #[inline(always)]
1202+ fn as_slice<'a>(&'a self) -> &'a str { *self }
1203+ }
1204+ impl<'self> Str for ~str {
1205+ #[inline(always)]
1206+ fn as_slice<'a>(&'a self) -> &'a str {
1207+ let s: &'a str = *self; s
1208+ }
1209+ }
1210+ impl<'self> Str for @str {
1211+ #[inline(always)]
1212+ fn as_slice<'a>(&'a self) -> &'a str {
1213+ let s: &'a str = *self; s
1214+ }
1215+ }
1216+
12701217#[allow(missing_doc)]
12711218pub trait StrSlice<'self> {
12721219 fn contains<'a>(&self, needle: &'a str) -> bool;
0 commit comments