1// SPDX-License-Identifier: Apache-2.0 OR MIT 2 3use crate::alloc::Allocator; 4use crate::collections::TryReserveError; 5use core::iter::TrustedLen; 6use core::slice::{self}; 7 8use super::{IntoIter, Vec}; 9 10// Specialization trait used for Vec::extend 11#[cfg(not(no_global_oom_handling))] 12pub(super) trait SpecExtend<T, I> { 13 fn spec_extend(&mut self, iter: I); 14} 15 16// Specialization trait used for Vec::try_extend 17pub(super) trait TrySpecExtend<T, I> { 18 fn try_spec_extend(&mut self, iter: I) -> Result<(), TryReserveError>; 19} 20 21#[cfg(not(no_global_oom_handling))] 22impl<T, I, A: Allocator> SpecExtend<T, I> for Vec<T, A> 23where 24 I: Iterator<Item = T>, 25{ 26 default fn spec_extend(&mut self, iter: I) { 27 self.extend_desugared(iter) 28 } 29} 30 31impl<T, I, A: Allocator> TrySpecExtend<T, I> for Vec<T, A> 32where 33 I: Iterator<Item = T>, 34{ 35 default fn try_spec_extend(&mut self, iter: I) -> Result<(), TryReserveError> { 36 self.try_extend_desugared(iter) 37 } 38} 39 40#[cfg(not(no_global_oom_handling))] 41impl<T, I, A: Allocator> SpecExtend<T, I> for Vec<T, A> 42where 43 I: TrustedLen<Item = T>, 44{ 45 default fn spec_extend(&mut self, iterator: I) { 46 self.extend_trusted(iterator) 47 } 48} 49 50impl<T, I, A: Allocator> TrySpecExtend<T, I> for Vec<T, A> 51where 52 I: TrustedLen<Item = T>, 53{ 54 default fn try_spec_extend(&mut self, iterator: I) -> Result<(), TryReserveError> { 55 self.try_extend_trusted(iterator) 56 } 57} 58 59#[cfg(not(no_global_oom_handling))] 60impl<T, A: Allocator> SpecExtend<T, IntoIter<T>> for Vec<T, A> { 61 fn spec_extend(&mut self, mut iterator: IntoIter<T>) { 62 unsafe { 63 self.append_elements(iterator.as_slice() as _); 64 } 65 iterator.forget_remaining_elements(); 66 } 67} 68 69impl<T, A: Allocator> TrySpecExtend<T, IntoIter<T>> for Vec<T, A> { 70 fn try_spec_extend(&mut self, mut iterator: IntoIter<T>) -> Result<(), TryReserveError> { 71 unsafe { 72 self.try_append_elements(iterator.as_slice() as _)?; 73 } 74 iterator.forget_remaining_elements(); 75 Ok(()) 76 } 77} 78 79#[cfg(not(no_global_oom_handling))] 80impl<'a, T: 'a, I, A: Allocator> SpecExtend<&'a T, I> for Vec<T, A> 81where 82 I: Iterator<Item = &'a T>, 83 T: Clone, 84{ 85 default fn spec_extend(&mut self, iterator: I) { 86 self.spec_extend(iterator.cloned()) 87 } 88} 89 90impl<'a, T: 'a, I, A: Allocator> TrySpecExtend<&'a T, I> for Vec<T, A> 91where 92 I: Iterator<Item = &'a T>, 93 T: Clone, 94{ 95 default fn try_spec_extend(&mut self, iterator: I) -> Result<(), TryReserveError> { 96 self.try_spec_extend(iterator.cloned()) 97 } 98} 99 100#[cfg(not(no_global_oom_handling))] 101impl<'a, T: 'a, A: Allocator> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec<T, A> 102where 103 T: Copy, 104{ 105 fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) { 106 let slice = iterator.as_slice(); 107 unsafe { self.append_elements(slice) }; 108 } 109} 110 111impl<'a, T: 'a, A: Allocator> TrySpecExtend<&'a T, slice::Iter<'a, T>> for Vec<T, A> 112where 113 T: Copy, 114{ 115 fn try_spec_extend(&mut self, iterator: slice::Iter<'a, T>) -> Result<(), TryReserveError> { 116 let slice = iterator.as_slice(); 117 unsafe { self.try_append_elements(slice) } 118 } 119} 120