xref: /openbmc/linux/rust/alloc/vec/spec_extend.rs (revision 9429b12d)
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> {
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> {
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 {
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 {
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 {
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 {
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> {
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> {
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 {
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 {
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 {
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 {
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