@@ -727,37 +727,80 @@ impl String {
727
727
self . vec . remove ( 0 )
728
728
}
729
729
730
- /// Removes the first character from the string buffer and returns it.
731
- /// Returns `None` if this string buffer is empty.
730
+ /// Deprecated, call `remove(0)` instead
731
+ #[ deprecated = "call .remove(0) instead" ]
732
+ pub fn shift_char ( & mut self ) -> Option < char > {
733
+ self . remove ( 0 )
734
+ }
735
+
736
+ /// Removes the character from the string buffer at byte position `idx` and
737
+ /// returns it. Returns `None` if `idx` is out of bounds.
732
738
///
733
739
/// # Warning
734
740
///
735
- /// This is a O(n) operation as it requires copying every element in the buffer.
741
+ /// This is a O(n) operation as it requires copying every element in the
742
+ /// buffer.
743
+ ///
744
+ /// # Failure
745
+ ///
746
+ /// If `idx` does not lie on a character boundary, then this function will
747
+ /// fail.
736
748
///
737
749
/// # Example
738
750
///
739
751
/// ```
740
752
/// let mut s = String::from_str("foo");
741
- /// assert_eq!(s.shift_char( ), Some('f'));
742
- /// assert_eq!(s.shift_char( ), Some('o'));
743
- /// assert_eq!(s.shift_char( ), Some('o'));
744
- /// assert_eq!(s.shift_char( ), None);
753
+ /// assert_eq!(s.remove(0 ), Some('f'));
754
+ /// assert_eq!(s.remove(1 ), Some('o'));
755
+ /// assert_eq!(s.remove(0 ), Some('o'));
756
+ /// assert_eq!(s.remove(0 ), None);
745
757
/// ```
746
- pub fn shift_char ( & mut self ) -> Option < char > {
758
+ #[ unstable = "the failure semantics of this function and return type \
759
+ may change"]
760
+ pub fn remove ( & mut self , idx : uint ) -> Option < char > {
747
761
let len = self . len ( ) ;
748
- if len == 0 {
749
- return None
750
- }
762
+ if idx >= len { return None }
751
763
752
- let CharRange { ch, next} = self . as_slice ( ) . char_range_at ( 0 ) ;
753
- let new_len = len - next;
764
+ let CharRange { ch, next } = self . as_slice ( ) . char_range_at ( idx) ;
754
765
unsafe {
755
- ptr:: copy_memory ( self . vec . as_mut_ptr ( ) , self . vec . as_ptr ( ) . offset ( next as int ) , new_len) ;
756
- self . vec . set_len ( new_len) ;
766
+ ptr:: copy_memory ( self . vec . as_mut_ptr ( ) . offset ( idx as int ) ,
767
+ self . vec . as_ptr ( ) . offset ( next as int ) ,
768
+ len - next) ;
769
+ self . vec . set_len ( len - ( next - idx) ) ;
757
770
}
758
771
Some ( ch)
759
772
}
760
773
774
+ /// Insert a character into the string buffer at byte position `idx`.
775
+ ///
776
+ /// # Warning
777
+ ///
778
+ /// This is a O(n) operation as it requires copying every element in the
779
+ /// buffer.
780
+ ///
781
+ /// # Failure
782
+ ///
783
+ /// If `idx` does not lie on a character boundary or is out of bounds, then
784
+ /// this function will fail.
785
+ pub fn insert ( & mut self , idx : uint , ch : char ) {
786
+ let len = self . len ( ) ;
787
+ assert ! ( idx <= len) ;
788
+ assert ! ( self . as_slice( ) . is_char_boundary( idx) ) ;
789
+ self . vec . reserve_additional ( 4 ) ;
790
+ let mut bits = [ 0 , ..4 ] ;
791
+ let amt = ch. encode_utf8 ( bits) . unwrap ( ) ;
792
+
793
+ unsafe {
794
+ ptr:: copy_memory ( self . vec . as_mut_ptr ( ) . offset ( ( idx + amt) as int ) ,
795
+ self . vec . as_ptr ( ) . offset ( idx as int ) ,
796
+ len - idx) ;
797
+ ptr:: copy_memory ( self . vec . as_mut_ptr ( ) . offset ( idx as int ) ,
798
+ bits. as_ptr ( ) ,
799
+ amt) ;
800
+ self . vec . set_len ( len + amt) ;
801
+ }
802
+ }
803
+
761
804
/// Views the string buffer as a mutable sequence of bytes.
762
805
///
763
806
/// This is unsafe because it does not check
@@ -1209,6 +1252,35 @@ mod tests {
1209
1252
assert_eq ! ( b. as_slice( ) , "1234522" ) ;
1210
1253
}
1211
1254
1255
+ #[ test]
1256
+ fn remove ( ) {
1257
+ let mut s = "ศไทย中华Việt Nam; foobar" . to_string ( ) ; ;
1258
+ assert_eq ! ( s. remove( 0 ) , Some ( 'ศ' ) ) ;
1259
+ assert_eq ! ( s. len( ) , 33 ) ;
1260
+ assert_eq ! ( s. as_slice( ) , "ไทย中华Việt Nam; foobar" ) ;
1261
+ assert_eq ! ( s. remove( 33 ) , None ) ;
1262
+ assert_eq ! ( s. remove( 300 ) , None ) ;
1263
+ assert_eq ! ( s. remove( 17 ) , Some ( 'ệ' ) ) ;
1264
+ assert_eq ! ( s. as_slice( ) , "ไทย中华Vit Nam; foobar" ) ;
1265
+ }
1266
+
1267
+ #[ test] #[ should_fail]
1268
+ fn remove_bad ( ) {
1269
+ "ศ" . to_string ( ) . remove ( 1 ) ;
1270
+ }
1271
+
1272
+ #[ test]
1273
+ fn insert ( ) {
1274
+ let mut s = "foobar" . to_string ( ) ;
1275
+ s. insert ( 0 , 'ệ' ) ;
1276
+ assert_eq ! ( s. as_slice( ) , "ệfoobar" ) ;
1277
+ s. insert ( 6 , 'ย' ) ;
1278
+ assert_eq ! ( s. as_slice( ) , "ệfooยbar" ) ;
1279
+ }
1280
+
1281
+ #[ test] #[ should_fail] fn insert_bad1 ( ) { "" . to_string ( ) . insert ( 1 , 't' ) ; }
1282
+ #[ test] #[ should_fail] fn insert_bad2 ( ) { "ệ" . to_string ( ) . insert ( 1 , 't' ) ; }
1283
+
1212
1284
#[ bench]
1213
1285
fn bench_with_capacity ( b : & mut Bencher ) {
1214
1286
b. iter ( || {
0 commit comments