@@ -241,110 +241,165 @@ pub fn append(lhs: ~str, rhs: &str) -> ~str {
241
241
}
242
242
243
243
/// Concatenate a vector of strings
244
- pub fn concat ( v : & [ ~str ] ) -> ~str {
245
- if v. is_empty ( ) { return ~""; }
244
+ pub fn concat ( v : & [ ~str ] ) -> ~str { v. concat ( ) }
246
245
247
- let mut len = 0 ;
248
- for v. each |ss| {
249
- len += ss. len ( ) ;
250
- }
251
- let mut s = ~"";
252
-
253
- reserve ( & mut s, len) ;
246
+ /// Concatenate a vector of strings
247
+ pub fn concat_slices ( v : & [ & str ] ) -> ~str { v. concat ( ) }
254
248
255
- unsafe {
256
- do as_buf ( s) |buf, _len| {
257
- let mut buf = :: cast:: transmute_mut_unsafe ( buf) ;
258
- for v. each |ss| {
259
- do as_buf( * ss) |ssbuf, sslen| {
260
- let sslen = sslen - 1 ;
261
- ptr:: copy_memory ( buf, ssbuf, sslen) ;
262
- buf = buf. offset ( sslen) ;
263
- }
264
- }
265
- }
266
- raw:: set_len ( & mut s, len) ;
267
- }
268
- s
269
- }
249
+ /// Concatenate a vector of strings, placing a given separator between each
250
+ pub fn connect ( v : & [ ~str ] , sep : & str ) -> ~str { v. connect ( sep) }
270
251
271
252
/// Concatenate a vector of strings, placing a given separator between each
272
- pub fn connect ( v : & [ ~str ] , sep : & str ) -> ~str {
273
- if v. is_empty ( ) { return ~""; }
253
+ pub fn connect_slices ( v : & [ & str ] , sep : & str ) -> ~str { v. connect ( sep) }
274
254
275
- // concat is faster
276
- if sep. is_empty ( ) { return concat ( v) ; }
255
+ #[ allow( missing_doc) ]
256
+ pub trait StrVector {
257
+ pub fn concat ( & self ) -> ~str ;
258
+ pub fn connect ( & self , sep : & str ) -> ~str ;
259
+ }
277
260
278
- // this is wrong without the guarantee that v is non-empty
279
- let mut len = sep. len ( ) * ( v. len ( ) - 1 ) ;
280
- for v. each |ss| {
281
- len += ss. len ( ) ;
282
- }
283
- let mut s = ~"", first = true ;
261
+ impl < ' self > StrVector for & ' self [ ~str ] {
262
+ /// Concatenate a vector of strings.
263
+ pub fn concat ( & self ) -> ~str {
264
+ if self . is_empty ( ) { return ~""; }
265
+
266
+ let mut len = 0 ;
267
+ for self . each |ss| {
268
+ len += ss. len ( ) ;
269
+ }
270
+ let mut s = ~"";
284
271
285
- reserve ( & mut s, len) ;
272
+ reserve ( & mut s, len) ;
286
273
287
- unsafe {
288
- do as_buf ( s) |buf, _len| {
289
- do as_buf ( sep) |sepbuf, seplen| {
290
- let seplen = seplen - 1 ;
274
+ unsafe {
275
+ do as_buf ( s) |buf, _| {
291
276
let mut buf = :: cast:: transmute_mut_unsafe ( buf) ;
292
- for v . each |ss| {
277
+ for self . each |ss| {
293
278
do as_buf ( * ss) |ssbuf, sslen| {
294
279
let sslen = sslen - 1 ;
295
- if first {
296
- first = false ;
297
- } else {
298
- ptr:: copy_memory ( buf, sepbuf, seplen) ;
299
- buf = buf. offset ( seplen) ;
300
- }
301
280
ptr:: copy_memory ( buf, ssbuf, sslen) ;
302
281
buf = buf. offset ( sslen) ;
303
282
}
304
283
}
305
284
}
285
+ raw:: set_len ( & mut s, len) ;
306
286
}
307
- raw :: set_len ( & mut s , len ) ;
287
+ s
308
288
}
309
- s
310
- }
311
289
312
- /// Concatenate a vector of strings, placing a given separator between each
313
- pub fn connect_slices ( v : & [ & str ] , sep : & str ) -> ~str {
314
- if v. is_empty ( ) { return ~""; }
290
+ /// Concatenate a vector of strings, placing a given separator between each.
291
+ pub fn connect ( & self , sep : & str ) -> ~str {
292
+ if self . is_empty ( ) { return ~""; }
293
+
294
+ // concat is faster
295
+ if sep. is_empty ( ) { return self . concat ( ) ; }
315
296
316
- // this is wrong without the guarantee that v is non-empty
317
- let mut len = sep. len ( ) * ( v. len ( ) - 1 ) ;
318
- for v. each |ss| {
319
- len += ss. len ( ) ;
297
+ // this is wrong without the guarantee that `self` is non-empty
298
+ let mut len = sep. len ( ) * ( self . len ( ) - 1 ) ;
299
+ for self . each |ss| {
300
+ len += ss. len ( ) ;
301
+ }
302
+ let mut s = ~"";
303
+ let mut first = true ;
304
+
305
+ reserve ( & mut s, len) ;
306
+
307
+ unsafe {
308
+ do as_buf ( s) |buf, _| {
309
+ do as_buf ( sep) |sepbuf, seplen| {
310
+ let seplen = seplen - 1 ;
311
+ let mut buf = :: cast:: transmute_mut_unsafe ( buf) ;
312
+ for self . each |ss| {
313
+ do as_buf( * ss) |ssbuf, sslen| {
314
+ let sslen = sslen - 1 ;
315
+ if first {
316
+ first = false ;
317
+ } else {
318
+ ptr:: copy_memory ( buf, sepbuf, seplen) ;
319
+ buf = buf. offset ( seplen) ;
320
+ }
321
+ ptr:: copy_memory ( buf, ssbuf, sslen) ;
322
+ buf = buf. offset ( sslen) ;
323
+ }
324
+ }
325
+ }
326
+ }
327
+ raw:: set_len ( & mut s, len) ;
328
+ }
329
+ s
320
330
}
321
- let mut s = ~"" , first = true ;
331
+ }
322
332
323
- reserve ( & mut s, len) ;
333
+ impl < ' self > StrVector for & ' self [ & ' self str ] {
334
+ /// Concatenate a vector of strings.
335
+ pub fn concat ( & self ) -> ~str {
336
+ if self . is_empty ( ) { return ~""; }
324
337
325
- unsafe {
326
- do as_buf ( s) |buf, _len| {
327
- do as_buf ( sep) |sepbuf, seplen| {
328
- let seplen = seplen - 1 ;
338
+ let mut len = 0 ;
339
+ for self . each |ss| {
340
+ len += ss. len ( ) ;
341
+ }
342
+ let mut s = ~"";
343
+
344
+ reserve ( & mut s, len) ;
345
+
346
+ unsafe {
347
+ do as_buf ( s) |buf, _| {
329
348
let mut buf = :: cast:: transmute_mut_unsafe ( buf) ;
330
- for v . each |ss| {
349
+ for self . each |ss| {
331
350
do as_buf ( * ss) |ssbuf, sslen| {
332
351
let sslen = sslen - 1 ;
333
- if first {
334
- first = false ;
335
- } else if seplen > 0 {
336
- ptr:: copy_memory ( buf, sepbuf, seplen) ;
337
- buf = buf. offset ( seplen) ;
338
- }
339
352
ptr:: copy_memory ( buf, ssbuf, sslen) ;
340
353
buf = buf. offset ( sslen) ;
341
354
}
342
355
}
343
356
}
357
+ raw:: set_len ( & mut s, len) ;
344
358
}
345
- raw:: set_len ( & mut s, len) ;
359
+ s
360
+ }
361
+
362
+ /// Concatenate a vector of strings, placing a given separator between each.
363
+ pub fn connect ( & self , sep : & str ) -> ~str {
364
+ if self . is_empty ( ) { return ~""; }
365
+
366
+ // concat is faster
367
+ if sep. is_empty ( ) { return self . concat ( ) ; }
368
+
369
+ // this is wrong without the guarantee that `self` is non-empty
370
+ let mut len = sep. len ( ) * ( self . len ( ) - 1 ) ;
371
+ for self . each |ss| {
372
+ len += ss. len ( ) ;
373
+ }
374
+ let mut s = ~"";
375
+ let mut first = true ;
376
+
377
+ reserve ( & mut s, len) ;
378
+
379
+ unsafe {
380
+ do as_buf ( s) |buf, _| {
381
+ do as_buf ( sep) |sepbuf, seplen| {
382
+ let seplen = seplen - 1 ;
383
+ let mut buf = :: cast:: transmute_mut_unsafe ( buf) ;
384
+ for self . each |ss| {
385
+ do as_buf( * ss) |ssbuf, sslen| {
386
+ let sslen = sslen - 1 ;
387
+ if first {
388
+ first = false ;
389
+ } else {
390
+ ptr:: copy_memory ( buf, sepbuf, seplen) ;
391
+ buf = buf. offset ( seplen) ;
392
+ }
393
+ ptr:: copy_memory ( buf, ssbuf, sslen) ;
394
+ buf = buf. offset ( sslen) ;
395
+ }
396
+ }
397
+ }
398
+ }
399
+ raw:: set_len ( & mut s, len) ;
400
+ }
401
+ s
346
402
}
347
- s
348
403
}
349
404
350
405
/// Given a string, make a new string with repeated copies of it
@@ -3184,6 +3239,7 @@ mod tests {
3184
3239
fn test_concat() {
3185
3240
fn t(v: &[~str], s: &str) {
3186
3241
assert_eq!(concat(v), s.to_str());
3242
+ assert_eq!(v.concat(), s.to_str());
3187
3243
}
3188
3244
t([~" you", ~" know", ~" I ' m", ~" no", ~" good"], " youknowI' mnogood");
3189
3245
let v: &[~str] = [];
@@ -3195,6 +3251,7 @@ mod tests {
3195
3251
fn test_connect() {
3196
3252
fn t(v: &[~str], sep: &str, s: &str) {
3197
3253
assert_eq!(connect(v, sep), s.to_str());
3254
+ assert_eq!(v.connect(sep), s.to_str());
3198
3255
}
3199
3256
t([~" you", ~" know", ~" I ' m", ~" no", ~" good"],
3200
3257
" ", " you know I ' m no good");
@@ -3203,10 +3260,23 @@ mod tests {
3203
3260
t([~" hi"], " ", " hi");
3204
3261
}
3205
3262
3263
+ #[test]
3264
+ fn test_concat_slices() {
3265
+ fn t(v: &[&str], s: &str) {
3266
+ assert_eq!(concat_slices(v), s.to_str());
3267
+ assert_eq!(v.concat(), s.to_str());
3268
+ }
3269
+ t([" you", " know", " I ' m", " no", " good"], " youknowI' mnogood");
3270
+ let v: &[&str] = [];
3271
+ t(v, " ");
3272
+ t([" hi"], " hi");
3273
+ }
3274
+
3206
3275
#[test]
3207
3276
fn test_connect_slices() {
3208
3277
fn t(v: &[&str], sep: &str, s: &str) {
3209
3278
assert_eq!(connect_slices(v, sep), s.to_str());
3279
+ assert_eq!(v.connect(sep), s.to_str());
3210
3280
}
3211
3281
t([" you", " know", " I ' m", " no", " good"],
3212
3282
" ", " you know I ' m no good");
0 commit comments