@@ -77,6 +77,7 @@ pub fn from_bytes_slice<'a>(vector: &'a [u8]) -> &'a str {
77
77
}
78
78
79
79
/// Copy a slice into a new unique str
80
+ #[ inline( always) ]
80
81
pub fn from_slice ( s : & str ) -> ~str {
81
82
unsafe { raw:: slice_bytes_owned ( s, 0 , len ( s) ) }
82
83
}
@@ -240,38 +241,132 @@ pub fn append(lhs: ~str, rhs: &str) -> ~str {
240
241
241
242
/// Concatenate a vector of strings
242
243
pub fn concat ( v : & [ ~str ] ) -> ~str {
243
- let mut s: ~str = ~"";
244
- for vec:: each( v) |ss| {
245
- push_str ( & mut s, * ss) ;
244
+ if v. is_empty ( ) { return ~""; }
245
+
246
+ let mut len = 0 ;
247
+ for v. each |ss| {
248
+ len += ss. len ( ) ;
249
+ }
250
+ let mut s = ~"";
251
+
252
+ reserve ( & mut s, len) ;
253
+
254
+ unsafe {
255
+ do as_buf ( s) |buf, _len| {
256
+ let mut buf = :: cast:: transmute_mut_unsafe ( buf) ;
257
+ for v. each |ss| {
258
+ do as_buf( * ss) |ssbuf, sslen| {
259
+ let sslen = sslen - 1 ;
260
+ ptr:: copy_memory ( buf, ssbuf, sslen) ;
261
+ buf = buf. offset ( sslen) ;
262
+ }
263
+ }
264
+ }
265
+ raw:: set_len ( & mut s, len) ;
246
266
}
247
267
s
248
268
}
249
269
250
270
/// Concatenate a vector of strings, placing a given separator between each
251
271
pub fn connect ( v : & [ ~str ] , sep : & str ) -> ~str {
272
+ if v. is_empty ( ) { return ~""; }
273
+
274
+ // concat is faster
275
+ if sep. is_empty ( ) { return concat ( v) ; }
276
+
277
+ // this is wrong without the guarantee that v is non-empty
278
+ let mut len = sep. len ( ) * ( v. len ( ) - 1 ) ;
279
+ for v. each |ss| {
280
+ len += ss. len ( ) ;
281
+ }
252
282
let mut s = ~"", first = true ;
253
- for vec:: each( v) |ss| {
254
- if first { first = false ; } else { push_str ( & mut s, sep) ; }
255
- push_str ( & mut s, * ss) ;
283
+
284
+ reserve ( & mut s, len) ;
285
+
286
+ unsafe {
287
+ do as_buf ( s) |buf, _len| {
288
+ do as_buf ( sep) |sepbuf, seplen| {
289
+ let seplen = seplen - 1 ;
290
+ let mut buf = :: cast:: transmute_mut_unsafe ( buf) ;
291
+ for v. each |ss| {
292
+ do as_buf( * ss) |ssbuf, sslen| {
293
+ let sslen = sslen - 1 ;
294
+ if first {
295
+ first = false ;
296
+ } else {
297
+ ptr:: copy_memory ( buf, sepbuf, seplen) ;
298
+ buf = buf. offset ( seplen) ;
299
+ }
300
+ ptr:: copy_memory ( buf, ssbuf, sslen) ;
301
+ buf = buf. offset ( sslen) ;
302
+ }
303
+ }
304
+ }
305
+ }
306
+ raw:: set_len ( & mut s, len) ;
256
307
}
257
308
s
258
309
}
259
310
260
311
/// Concatenate a vector of strings, placing a given separator between each
261
312
pub fn connect_slices ( v : & [ & str ] , sep : & str ) -> ~str {
313
+ if v. is_empty ( ) { return ~""; }
314
+
315
+ // this is wrong without the guarantee that v is non-empty
316
+ let mut len = sep. len ( ) * ( v. len ( ) - 1 ) ;
317
+ for v. each |ss| {
318
+ len += ss. len ( ) ;
319
+ }
262
320
let mut s = ~"", first = true ;
263
- for vec:: each( v) |ss| {
264
- if first { first = false ; } else { push_str ( & mut s, sep) ; }
265
- push_str ( & mut s, * ss) ;
321
+
322
+ reserve ( & mut s, len) ;
323
+
324
+ unsafe {
325
+ do as_buf ( s) |buf, _len| {
326
+ do as_buf ( sep) |sepbuf, seplen| {
327
+ let seplen = seplen - 1 ;
328
+ let mut buf = :: cast:: transmute_mut_unsafe ( buf) ;
329
+ for vec:: each( v) |ss| {
330
+ do as_buf( * ss) |ssbuf, sslen| {
331
+ let sslen = sslen - 1 ;
332
+ if first {
333
+ first = false ;
334
+ } else if seplen > 0 {
335
+ ptr:: copy_memory ( buf, sepbuf, seplen) ;
336
+ buf = buf. offset ( seplen) ;
337
+ }
338
+ ptr:: copy_memory ( buf, ssbuf, sslen) ;
339
+ buf = buf. offset ( sslen) ;
340
+ }
341
+ }
342
+ }
343
+ }
344
+ raw:: set_len ( & mut s, len) ;
266
345
}
267
346
s
268
347
}
269
348
270
349
/// Given a string, make a new string with repeated copies of it
271
350
pub fn repeat( ss : & str , nn : uint ) -> ~str {
272
- let mut acc = ~"";
273
- for nn. times { acc += ss; }
274
- acc
351
+ do as_buf ( ss) |buf, len| {
352
+ let mut ret = ~"";
353
+ // ignore the NULL terminator
354
+ let len = len - 1 ;
355
+ reserve ( & mut ret, nn * len) ;
356
+
357
+ unsafe {
358
+ do as_buf ( ret) |rbuf, _len| {
359
+ let mut rbuf = :: cast:: transmute_mut_unsafe ( rbuf) ;
360
+
361
+ for nn. times {
362
+ ptr : : copy_memory( rbuf, buf, len) ;
363
+ rbuf = rbuf. offset( len) ;
364
+ }
365
+ }
366
+ raw :: set_len( & mut ret, nn * len) ;
367
+ }
368
+ ret
369
+ }
275
370
}
276
371
277
372
/*
@@ -820,6 +915,7 @@ Section: Comparing strings
820
915
/// Bytewise slice equality
821
916
#[ cfg( notest) ]
822
917
#[ lang="str_eq" ]
918
+ #[ inline]
823
919
pub fn eq_slice ( a : & str , b : & str ) -> bool {
824
920
do as_buf ( a) |ap, alen| {
825
921
do as_buf ( b) |bp, blen| {
@@ -836,6 +932,7 @@ pub fn eq_slice(a: &str, b: &str) -> bool {
836
932
}
837
933
838
934
#[ cfg( test) ]
935
+ #[ inline]
839
936
pub fn eq_slice ( a : & str , b : & str ) -> bool {
840
937
do as_buf ( a) |ap, alen| {
841
938
do as_buf ( b) |bp, blen| {
@@ -854,15 +951,18 @@ pub fn eq_slice(a: &str, b: &str) -> bool {
854
951
/// Bytewise string equality
855
952
#[ cfg( notest) ]
856
953
#[ lang="uniq_str_eq" ]
954
+ #[ inline]
857
955
pub fn eq ( a : & ~str , b : & ~str ) -> bool {
858
956
eq_slice ( * a, * b)
859
957
}
860
958
861
959
#[ cfg( test) ]
960
+ #[ inline]
862
961
pub fn eq ( a : & ~str , b : & ~str ) -> bool {
863
962
eq_slice ( * a, * b)
864
963
}
865
964
965
+ #[ inline]
866
966
fn cmp ( a : & str , b : & str ) -> Ordering {
867
967
let low = uint:: min ( a. len ( ) , b. len ( ) ) ;
868
968
@@ -879,20 +979,24 @@ fn cmp(a: &str, b: &str) -> Ordering {
879
979
880
980
#[ cfg( notest) ]
881
981
impl < ' self > TotalOrd for & ' self str {
982
+ #[ inline]
882
983
fn cmp ( & self , other : & & ' self str ) -> Ordering { cmp ( * self , * other) }
883
984
}
884
985
885
986
#[ cfg( notest) ]
886
987
impl TotalOrd for ~str {
988
+ #[ inline]
887
989
fn cmp ( & self , other : & ~str ) -> Ordering { cmp ( * self , * other) }
888
990
}
889
991
890
992
#[ cfg( notest) ]
891
993
impl TotalOrd for @str {
994
+ #[ inline]
892
995
fn cmp ( & self , other : & @str ) -> Ordering { cmp ( * self , * other) }
893
996
}
894
997
895
998
/// Bytewise slice less than
999
+ #[ inline]
896
1000
fn lt ( a : & str , b : & str ) -> bool {
897
1001
let ( a_len, b_len) = ( a. len ( ) , b. len ( ) ) ;
898
1002
let end = uint:: min ( a_len, b_len) ;
@@ -909,16 +1013,19 @@ fn lt(a: &str, b: &str) -> bool {
909
1013
}
910
1014
911
1015
/// Bytewise less than or equal
1016
+ #[ inline]
912
1017
pub fn le ( a : & str , b : & str ) -> bool {
913
1018
!lt ( b, a)
914
1019
}
915
1020
916
1021
/// Bytewise greater than or equal
1022
+ #[ inline]
917
1023
fn ge ( a : & str , b : & str ) -> bool {
918
1024
!lt ( a, b)
919
1025
}
920
1026
921
1027
/// Bytewise greater than
1028
+ #[ inline]
922
1029
fn gt ( a : & str , b : & str ) -> bool {
923
1030
!le ( a, b)
924
1031
}
@@ -1595,6 +1702,7 @@ Section: String properties
1595
1702
*/
1596
1703
1597
1704
/// Returns true if the string has length 0
1705
+ #[ inline( always) ]
1598
1706
pub fn is_empty ( s : & str ) -> bool { len ( s) == 0 u }
1599
1707
1600
1708
/**
@@ -1616,11 +1724,13 @@ fn is_alphanumeric(s: &str) -> bool {
1616
1724
}
1617
1725
1618
1726
/// Returns the string length/size in bytes not counting the null terminator
1727
+ #[ inline( always) ]
1619
1728
pub fn len ( s : & str ) -> uint {
1620
1729
do as_buf ( s) |_p, n| { n - 1 u }
1621
1730
}
1622
1731
1623
1732
/// Returns the number of characters that a string holds
1733
+ #[ inline( always) ]
1624
1734
pub fn char_len ( s : & str ) -> uint { count_chars ( s, 0 u, len ( s) ) }
1625
1735
1626
1736
/*
@@ -1752,7 +1862,8 @@ pub fn count_chars(s: &str, start: uint, end: uint) -> uint {
1752
1862
return len;
1753
1863
}
1754
1864
1755
- /// Counts the number of bytes taken by the `n` in `s` starting from `start`.
1865
+ /// Counts the number of bytes taken by the first `n` chars in `s`
1866
+ /// starting from `start`.
1756
1867
pub fn count_bytes < ' b > ( s : & ' b str , start : uint , n : uint ) -> uint {
1757
1868
assert ! ( is_char_boundary( s, start) ) ;
1758
1869
let mut end = start, cnt = n;
@@ -1988,6 +2099,7 @@ static tag_six_b: uint = 252u;
1988
2099
* let i = str::as_bytes("Hello World") { |bytes| vec::len(bytes) };
1989
2100
* ~~~
1990
2101
*/
2102
+ #[ inline]
1991
2103
pub fn as_bytes < T > ( s : & const ~str , f : & fn ( & ~[ u8 ] ) -> T ) -> T {
1992
2104
unsafe {
1993
2105
let v: * ~[ u8 ] = cast:: transmute ( copy s) ;
@@ -2023,6 +2135,7 @@ pub fn as_bytes_slice<'a>(s: &'a str) -> &'a [u8] {
2023
2135
* let s = str::as_c_str("PATH", { |path| libc::getenv(path) });
2024
2136
* ~~~
2025
2137
*/
2138
+ #[ inline]
2026
2139
pub fn as_c_str < T > ( s : & str , f : & fn ( * libc:: c_char ) -> T ) -> T {
2027
2140
do as_buf ( s) |buf, len| {
2028
2141
// NB: len includes the trailing null.
@@ -2099,6 +2212,7 @@ pub fn subslice_offset(outer: &str, inner: &str) -> uint {
2099
2212
* * s - A string
2100
2213
* * n - The number of bytes to reserve space for
2101
2214
*/
2215
+ #[ inline( always) ]
2102
2216
pub fn reserve ( s : & mut ~str , n : uint ) {
2103
2217
unsafe {
2104
2218
let v: * mut ~[ u8 ] = cast:: transmute ( s) ;
@@ -2126,6 +2240,7 @@ pub fn reserve(s: &mut ~str, n: uint) {
2126
2240
* * s - A string
2127
2241
* * n - The number of bytes to reserve space for
2128
2242
*/
2243
+ #[ inline( always) ]
2129
2244
pub fn reserve_at_least ( s : & mut ~str , n : uint ) {
2130
2245
reserve ( s, uint:: next_power_of_two ( n + 1 u) - 1 u)
2131
2246
}
@@ -2314,6 +2429,7 @@ pub mod raw {
2314
2429
}
2315
2430
2316
2431
/// Sets the length of the string and adds the null terminator
2432
+ #[ inline]
2317
2433
pub unsafe fn set_len ( v : & mut ~str , new_len : uint ) {
2318
2434
let v: * * mut vec:: raw:: VecRepr = cast:: transmute ( v) ;
2319
2435
let repr: * mut vec:: raw:: VecRepr = * v;
@@ -2489,7 +2605,7 @@ impl<'self> StrSlice<'self> for &'self str {
2489
2605
#[inline]
2490
2606
fn is_alphanumeric(&self) -> bool { is_alphanumeric(*self) }
2491
2607
/// Returns the size in bytes not counting the null terminator
2492
- #[inline]
2608
+ #[inline(always) ]
2493
2609
fn len(&self) -> uint { len(*self) }
2494
2610
/// Returns the number of characters that a string holds
2495
2611
#[inline]
@@ -2599,10 +2715,11 @@ pub trait OwnedStr {
2599
2715
}
2600
2716
2601
2717
impl OwnedStr for ~str {
2718
+ #[inline]
2602
2719
fn push_str(&mut self, v: &str) {
2603
2720
push_str(self, v);
2604
2721
}
2605
-
2722
+ #[inline]
2606
2723
fn push_char(&mut self, c: char) {
2607
2724
push_char(self, c);
2608
2725
}
0 commit comments