@@ -26,7 +26,7 @@ use clone::Clone;
26
26
use cmp:: { TotalOrd , Ordering , Less , Equal , Greater } ;
27
27
use container:: Container ;
28
28
use iter:: Times ;
29
- use iterator:: { Iterator , IteratorUtil , FilterIterator } ;
29
+ use iterator:: { Iterator , IteratorUtil , FilterIterator , AdditiveIterator } ;
30
30
use libc;
31
31
use option:: { None , Option , Some } ;
32
32
use old_iter:: { BaseIter , EqIter } ;
@@ -160,96 +160,22 @@ pub trait StrVector {
160
160
pub fn connect ( & self , sep : & str ) -> ~str ;
161
161
}
162
162
163
- impl < ' self > StrVector for & ' self [ ~ str ] {
163
+ impl < ' self , S : Str > StrVector for & ' self [ S ] {
164
164
/// Concatenate a vector of strings.
165
165
pub fn concat ( & self ) -> ~str {
166
166
if self . is_empty ( ) { return ~""; }
167
167
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 ( ) ;
173
169
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
- }
244
170
let mut s = ~"";
245
171
246
172
s. reserve ( len) ;
247
173
248
174
unsafe {
249
175
do as_buf ( s) |buf, _| {
250
176
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| {
253
179
let sslen = sslen - 1 ;
254
180
ptr:: copy_memory ( buf, ssbuf, sslen) ;
255
181
buf = buf. offset ( sslen) ;
@@ -269,10 +195,8 @@ impl<'self> StrVector for &'self [&'self str] {
269
195
if sep. is_empty ( ) { return self . concat ( ) ; }
270
196
271
197
// 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 ( ) ;
276
200
let mut s = ~"";
277
201
let mut first = true ;
278
202
@@ -283,8 +207,8 @@ impl<'self> StrVector for &'self [&'self str] {
283
207
do as_buf ( sep) |sepbuf, seplen| {
284
208
let seplen = seplen - 1 ;
285
209
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| {
288
212
let sslen = sslen - 1 ;
289
213
if first {
290
214
first = false ;
@@ -1267,6 +1191,29 @@ pub mod traits {
1267
1191
#[cfg(test)]
1268
1192
pub mod traits {}
1269
1193
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
+
1270
1217
#[allow(missing_doc)]
1271
1218
pub trait StrSlice<'self> {
1272
1219
fn contains<'a>(&self, needle: &'a str) -> bool;
0 commit comments