@@ -227,6 +227,76 @@ impl<T, A: Allocator> VecDeque<T, A> {
227227 wrap_index ( idx. wrapping_sub ( subtrahend) . wrapping_add ( self . capacity ( ) ) , self . capacity ( ) )
228228 }
229229
230+ /// Get source, destination and count (like the arguments to [`ptr::copy_nonoverlapping`])
231+ /// for copying `count` values from index `src` to index `dst`.
232+ /// One of the ranges can wrap around the physical buffer, for this reason 2 triples are returned.
233+ ///
234+ /// Use of the word "ranges" specifically refers to `src..src + count` and `dst..dst + count`.
235+ ///
236+ /// # Safety
237+ ///
238+ /// - Ranges must not overlap: `src.abs_diff(dst) >= count`.
239+ /// - Ranges must be in bounds of the logical buffer: `src + count <= self.capacity()` and `dst + count <= self.capacity()`.
240+ /// - `head` must be in bounds: `head < self.capacity()`.
241+ #[ cfg( not( no_global_oom_handling) ) ]
242+ unsafe fn nonoverlapping_ranges (
243+ & mut self ,
244+ src : usize ,
245+ dst : usize ,
246+ count : usize ,
247+ head : usize ,
248+ ) -> [ ( * const T , * mut T , usize ) ; 2 ] {
249+ // "`src` and `dst` must be at least as far apart as `count`"
250+ debug_assert ! (
251+ src. abs_diff( dst) >= count,
252+ "`src` and `dst` must not overlap. src={src} dst={dst} count={count}" ,
253+ ) ;
254+ debug_assert ! (
255+ src. max( dst) + count <= self . capacity( ) ,
256+ "ranges must be in bounds. src={src} dst={dst} count={count} cap={}" ,
257+ self . capacity( ) ,
258+ ) ;
259+
260+ let wrapped_src = self . wrap_add ( head, src) ;
261+ let wrapped_dst = self . wrap_add ( head, dst) ;
262+
263+ let room_after_src = self . capacity ( ) - wrapped_src;
264+ let room_after_dst = self . capacity ( ) - wrapped_dst;
265+
266+ let src_wraps = room_after_src < count;
267+ let dst_wraps = room_after_dst < count;
268+
269+ debug_assert ! (
270+ !( src_wraps && dst_wraps) ,
271+ "BUG: at most one of src and dst can wrap. src={src} dst={dst} count={count} cap={}" ,
272+ self . capacity( ) ,
273+ ) ;
274+
275+ unsafe {
276+ let ptr = self . ptr ( ) ;
277+ let src_ptr = ptr. add ( wrapped_src) ;
278+ let dst_ptr = ptr. add ( wrapped_dst) ;
279+
280+ if src_wraps {
281+ [
282+ ( src_ptr, dst_ptr, room_after_src) ,
283+ ( ptr, dst_ptr. add ( room_after_src) , count - room_after_src) ,
284+ ]
285+ } else if dst_wraps {
286+ [
287+ ( src_ptr, dst_ptr, room_after_dst) ,
288+ ( src_ptr. add ( room_after_dst) , ptr, count - room_after_dst) ,
289+ ]
290+ } else {
291+ [
292+ ( src_ptr, dst_ptr, count) ,
293+ // null pointers are fine as long as the count is 0
294+ ( ptr:: null ( ) , ptr:: null_mut ( ) , 0 ) ,
295+ ]
296+ }
297+ }
298+ }
299+
230300 /// Copies a contiguous block of memory len long from src to dst
231301 #[ inline]
232302 unsafe fn copy ( & mut self , src : usize , dst : usize , len : usize ) {
@@ -2971,6 +3041,208 @@ impl<T: Clone, A: Allocator> VecDeque<T, A> {
29713041 self . truncate ( new_len) ;
29723042 }
29733043 }
3044+
3045+ /// Clones the elements at the range `src` and appends them to the end.
3046+ ///
3047+ /// # Panics
3048+ ///
3049+ /// Panics if the starting index is greater than the end index
3050+ /// or if either index is greater than the length of the vector.
3051+ ///
3052+ /// # Examples
3053+ ///
3054+ /// ```
3055+ /// #![feature(deque_extend_front)]
3056+ /// use std::collections::VecDeque;
3057+ ///
3058+ /// let mut characters = VecDeque::from(['a', 'b', 'c', 'd', 'e']);
3059+ /// characters.extend_from_within(2..);
3060+ /// assert_eq!(characters, ['a', 'b', 'c', 'd', 'e', 'c', 'd', 'e']);
3061+ ///
3062+ /// let mut numbers = VecDeque::from([0, 1, 2, 3, 4]);
3063+ /// numbers.extend_from_within(..2);
3064+ /// assert_eq!(numbers, [0, 1, 2, 3, 4, 0, 1]);
3065+ ///
3066+ /// let mut strings = VecDeque::from([String::from("hello"), String::from("world"), String::from("!")]);
3067+ /// strings.extend_from_within(1..=2);
3068+ /// assert_eq!(strings, ["hello", "world", "!", "world", "!"]);
3069+ /// ```
3070+ #[ cfg( not( no_global_oom_handling) ) ]
3071+ #[ unstable( feature = "deque_extend_front" , issue = "146975" ) ]
3072+ pub fn extend_from_within < R > ( & mut self , src : R )
3073+ where
3074+ R : RangeBounds < usize > ,
3075+ {
3076+ let range = slice:: range ( src, ..self . len ( ) ) ;
3077+ self . reserve ( range. len ( ) ) ;
3078+
3079+ // SAFETY:
3080+ // - `slice::range` guarantees that the given range is valid for indexing self
3081+ // - at least `range.len()` additional space is available
3082+ unsafe {
3083+ self . spec_extend_from_within ( range) ;
3084+ }
3085+ }
3086+
3087+ /// Clones the elements at the range `src` and prepends them to the front.
3088+ ///
3089+ /// # Panics
3090+ ///
3091+ /// Panics if the starting index is greater than the end index
3092+ /// or if either index is greater than the length of the vector.
3093+ ///
3094+ /// # Examples
3095+ ///
3096+ /// ```
3097+ /// #![feature(deque_extend_front)]
3098+ /// use std::collections::VecDeque;
3099+ ///
3100+ /// let mut characters = VecDeque::from(['a', 'b', 'c', 'd', 'e']);
3101+ /// characters.prepend_from_within(2..);
3102+ /// assert_eq!(characters, ['c', 'd', 'e', 'a', 'b', 'c', 'd', 'e']);
3103+ ///
3104+ /// let mut numbers = VecDeque::from([0, 1, 2, 3, 4]);
3105+ /// numbers.prepend_from_within(..2);
3106+ /// assert_eq!(numbers, [0, 1, 0, 1, 2, 3, 4]);
3107+ ///
3108+ /// let mut strings = VecDeque::from([String::from("hello"), String::from("world"), String::from("!")]);
3109+ /// strings.prepend_from_within(1..=2);
3110+ /// assert_eq!(strings, ["world", "!", "hello", "world", "!"]);
3111+ /// ```
3112+ #[ cfg( not( no_global_oom_handling) ) ]
3113+ #[ unstable( feature = "deque_extend_front" , issue = "146975" ) ]
3114+ pub fn prepend_from_within < R > ( & mut self , src : R )
3115+ where
3116+ R : RangeBounds < usize > ,
3117+ {
3118+ let range = slice:: range ( src, ..self . len ( ) ) ;
3119+ self . reserve ( range. len ( ) ) ;
3120+
3121+ // SAFETY:
3122+ // - `slice::range` guarantees that the given range is valid for indexing self
3123+ // - at least `range.len()` additional space is available
3124+ unsafe {
3125+ self . spec_prepend_from_within ( range) ;
3126+ }
3127+ }
3128+ }
3129+
3130+ /// Associated functions have the following preconditions:
3131+ ///
3132+ /// - `src` needs to be a valid range: `src.start <= src.end <= self.len()`.
3133+ /// - The buffer must have enough spare capacity: `self.capacity() - self.len() >= src.len()`.
3134+ #[ cfg( not( no_global_oom_handling) ) ]
3135+ trait SpecExtendFromWithin {
3136+ unsafe fn spec_extend_from_within ( & mut self , src : Range < usize > ) ;
3137+
3138+ unsafe fn spec_prepend_from_within ( & mut self , src : Range < usize > ) ;
3139+ }
3140+
3141+ #[ cfg( not( no_global_oom_handling) ) ]
3142+ impl < T : Clone , A : Allocator > SpecExtendFromWithin for VecDeque < T , A > {
3143+ default unsafe fn spec_extend_from_within ( & mut self , src : Range < usize > ) {
3144+ let dst = self . len ( ) ;
3145+ let count = src. end - src. start ;
3146+ let src = src. start ;
3147+
3148+ unsafe {
3149+ // SAFETY:
3150+ // - Ranges do not overlap: src entirely spans initialized values, dst entirely spans uninitialized values.
3151+ // - Ranges are in bounds: guaranteed by the caller.
3152+ let ranges = self . nonoverlapping_ranges ( src, dst, count, self . head ) ;
3153+ for ( src, dst, count) in ranges {
3154+ for offset in 0 ..count {
3155+ dst. add ( offset) . write ( ( * src. add ( offset) ) . clone ( ) ) ;
3156+ self . len += 1 ;
3157+ }
3158+ }
3159+ }
3160+ }
3161+
3162+ default unsafe fn spec_prepend_from_within ( & mut self , src : Range < usize > ) {
3163+ let dst = 0 ;
3164+ let count = src. end - src. start ;
3165+ let src = src. start + count;
3166+
3167+ let new_head = self . wrap_sub ( self . head , count) ;
3168+ let cap = self . capacity ( ) ;
3169+
3170+ unsafe {
3171+ // SAFETY:
3172+ // - Ranges do not overlap: src entirely spans initialized values, dst entirely spans uninitialized values.
3173+ // - Ranges are in bounds: guaranteed by the caller.
3174+ let ranges = self . nonoverlapping_ranges ( src, dst, count, new_head) ;
3175+ let ( src, dst, count) = ranges[ 1 ] ;
3176+ for offset in ( 0 ..count) . rev ( ) {
3177+ dst. add ( offset) . write ( ( * src. add ( offset) ) . clone ( ) ) ;
3178+ self . head -= 1 ;
3179+ self . len += 1 ;
3180+ }
3181+
3182+ let ( src, dst, count) = ranges[ 0 ] ;
3183+ let mut iter = ( 0 ..count) . rev ( ) ;
3184+ if let Some ( offset) = iter. next ( ) {
3185+ dst. add ( offset) . write ( ( * src. add ( offset) ) . clone ( ) ) ;
3186+ if self . head == 0 {
3187+ self . head = cap;
3188+ }
3189+ self . head -= 1 ;
3190+ self . len += 1 ;
3191+
3192+ for offset in iter {
3193+ dst. add ( offset) . write ( ( * src. add ( offset) ) . clone ( ) ) ;
3194+ self . head -= 1 ;
3195+ self . len += 1 ;
3196+ }
3197+ }
3198+ }
3199+ }
3200+ }
3201+
3202+ #[ cfg( not( no_global_oom_handling) ) ]
3203+ impl < T : Copy , A : Allocator > SpecExtendFromWithin for VecDeque < T , A > {
3204+ unsafe fn spec_extend_from_within ( & mut self , src : Range < usize > ) {
3205+ let dst = self . len ( ) ;
3206+ let count = src. end - src. start ;
3207+ let src = src. start ;
3208+
3209+ unsafe {
3210+ // SAFETY:
3211+ // - Ranges do not overlap: src entirely spans initialized values, dst entirely spans uninitialized values.
3212+ // - Ranges are in bounds: guaranteed by the caller.
3213+ let ranges = self . nonoverlapping_ranges ( src, dst, count, self . head ) ;
3214+ for ( src, dst, count) in ranges {
3215+ ptr:: copy_nonoverlapping ( src, dst, count) ;
3216+ }
3217+ }
3218+
3219+ // SAFETY:
3220+ // - The elements were just initialized by `copy_nonoverlapping`
3221+ self . len += count;
3222+ }
3223+
3224+ unsafe fn spec_prepend_from_within ( & mut self , src : Range < usize > ) {
3225+ let dst = 0 ;
3226+ let count = src. end - src. start ;
3227+ let src = src. start + count;
3228+
3229+ let new_head = self . wrap_sub ( self . head , count) ;
3230+
3231+ unsafe {
3232+ // SAFETY:
3233+ // - Ranges do not overlap: src entirely spans initialized values, dst entirely spans uninitialized values.
3234+ // - Ranges are in bounds: guaranteed by the caller.
3235+ let ranges = self . nonoverlapping_ranges ( src, dst, count, new_head) ;
3236+ for ( src, dst, count) in ranges {
3237+ ptr:: copy_nonoverlapping ( src, dst, count) ;
3238+ }
3239+ }
3240+
3241+ // SAFETY:
3242+ // - The elements were just initialized by `copy_nonoverlapping`
3243+ self . head = new_head;
3244+ self . len += count;
3245+ }
29743246}
29753247
29763248/// Returns the index in the underlying buffer for a given logical element index.
0 commit comments