@@ -394,6 +394,77 @@ impl<T> [T] {
394394 // NB see hack module in this file
395395 hack:: into_vec ( self )
396396 }
397+
398+ /// Creates a vector by repeating a slice `n` times.
399+ ///
400+ /// # Examples
401+ ///
402+ /// Basic usage:
403+ ///
404+ /// ```
405+ /// #![feature(repeat_generic_slice)]
406+ ///
407+ /// fn main() {
408+ /// assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
409+ /// }
410+ /// ```
411+ #[ unstable( feature = "repeat_generic_slice" ,
412+ reason = "it's on str, why not on slice?" ,
413+ issue = "48784" ) ]
414+ pub fn repeat ( & self , n : usize ) -> Vec < T > where T : Copy {
415+ if n == 0 {
416+ return Vec :: new ( ) ;
417+ }
418+
419+ // If `n` is larger than zero, it can be split as
420+ // `n = 2^expn + rem (2^expn > rem, expn >= 0, rem >= 0)`.
421+ // `2^expn` is the number represented by the leftmost '1' bit of `n`,
422+ // and `rem` is the remaining part of `n`.
423+
424+ // Using `Vec` to access `set_len()`.
425+ let mut buf = Vec :: with_capacity ( self . len ( ) * n) ;
426+
427+ // `2^expn` repetition is done by doubling `buf` `expn`-times.
428+ buf. extend ( self ) ;
429+ {
430+ let mut m = n >> 1 ;
431+ // If `m > 0`, there are remaining bits up to the leftmost '1'.
432+ while m > 0 {
433+ // `buf.extend(buf)`:
434+ unsafe {
435+ ptr:: copy_nonoverlapping (
436+ buf. as_ptr ( ) ,
437+ ( buf. as_mut_ptr ( ) as * mut T ) . add ( buf. len ( ) ) ,
438+ buf. len ( ) ,
439+ ) ;
440+ // `buf` has capacity of `self.len() * n`.
441+ let buf_len = buf. len ( ) ;
442+ buf. set_len ( buf_len * 2 ) ;
443+ }
444+
445+ m >>= 1 ;
446+ }
447+ }
448+
449+ // `rem` (`= n - 2^expn`) repetition is done by copying
450+ // first `rem` repetitions from `buf` itself.
451+ let rem_len = self . len ( ) * n - buf. len ( ) ; // `self.len() * rem`
452+ if rem_len > 0 {
453+ // `buf.extend(buf[0 .. rem_len])`:
454+ unsafe {
455+ // This is non-overlapping since `2^expn > rem`.
456+ ptr:: copy_nonoverlapping (
457+ buf. as_ptr ( ) ,
458+ ( buf. as_mut_ptr ( ) as * mut T ) . add ( buf. len ( ) ) ,
459+ rem_len,
460+ ) ;
461+ // `buf.len() + rem_len` equals to `buf.capacity()` (`= self.len() * n`).
462+ let buf_cap = buf. capacity ( ) ;
463+ buf. set_len ( buf_cap) ;
464+ }
465+ }
466+ buf
467+ }
397468}
398469
399470#[ cfg_attr( stage0, lang = "slice_u8" ) ]
0 commit comments