1 // SPDX-License-Identifier: Apache-2.0 OR MIT 2 3 use crate::alloc::Allocator; 4 use crate::collections::TryReserveError; 5 use core::iter::TrustedLen; 6 use core::slice::{self}; 7 8 use super::{IntoIter, Vec}; 9 10 // Specialization trait used for Vec::extend 11 #[cfg(not(no_global_oom_handling))] 12 pub(super) trait SpecExtend<T, I> { spec_extend(&mut self, iter: I)13 fn spec_extend(&mut self, iter: I); 14 } 15 16 // Specialization trait used for Vec::try_extend 17 pub(super) trait TrySpecExtend<T, I> { try_spec_extend(&mut self, iter: I) -> Result<(), TryReserveError>18 fn try_spec_extend(&mut self, iter: I) -> Result<(), TryReserveError>; 19 } 20 21 #[cfg(not(no_global_oom_handling))] 22 impl<T, I, A: Allocator> SpecExtend<T, I> for Vec<T, A> 23 where 24 I: Iterator<Item = T>, 25 { spec_extend(&mut self, iter: I)26 default fn spec_extend(&mut self, iter: I) { 27 self.extend_desugared(iter) 28 } 29 } 30 31 impl<T, I, A: Allocator> TrySpecExtend<T, I> for Vec<T, A> 32 where 33 I: Iterator<Item = T>, 34 { try_spec_extend(&mut self, iter: I) -> Result<(), TryReserveError>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))] 41 impl<T, I, A: Allocator> SpecExtend<T, I> for Vec<T, A> 42 where 43 I: TrustedLen<Item = T>, 44 { spec_extend(&mut self, iterator: I)45 default fn spec_extend(&mut self, iterator: I) { 46 self.extend_trusted(iterator) 47 } 48 } 49 50 impl<T, I, A: Allocator> TrySpecExtend<T, I> for Vec<T, A> 51 where 52 I: TrustedLen<Item = T>, 53 { try_spec_extend(&mut self, iterator: I) -> Result<(), TryReserveError>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))] 60 impl<T, A: Allocator> SpecExtend<T, IntoIter<T>> for Vec<T, A> { spec_extend(&mut self, mut iterator: IntoIter<T>)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 69 impl<T, A: Allocator> TrySpecExtend<T, IntoIter<T>> for Vec<T, A> { try_spec_extend(&mut self, mut iterator: IntoIter<T>) -> Result<(), TryReserveError>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))] 80 impl<'a, T: 'a, I, A: Allocator> SpecExtend<&'a T, I> for Vec<T, A> 81 where 82 I: Iterator<Item = &'a T>, 83 T: Clone, 84 { spec_extend(&mut self, iterator: I)85 default fn spec_extend(&mut self, iterator: I) { 86 self.spec_extend(iterator.cloned()) 87 } 88 } 89 90 impl<'a, T: 'a, I, A: Allocator> TrySpecExtend<&'a T, I> for Vec<T, A> 91 where 92 I: Iterator<Item = &'a T>, 93 T: Clone, 94 { try_spec_extend(&mut self, iterator: I) -> Result<(), TryReserveError>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))] 101 impl<'a, T: 'a, A: Allocator> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec<T, A> 102 where 103 T: Copy, 104 { spec_extend(&mut self, iterator: slice::Iter<'a, T>)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 111 impl<'a, T: 'a, A: Allocator> TrySpecExtend<&'a T, slice::Iter<'a, T>> for Vec<T, A> 112 where 113 T: Copy, 114 { try_spec_extend(&mut self, iterator: slice::Iter<'a, T>) -> Result<(), TryReserveError>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