1use alloc::vec::Vec;
2use core::borrow::Borrow;
3use core::cmp::Ordering;
4use core::hash::{Hash, Hasher};
5use core::ops::Deref;
6use core::ptr;
7
8use super::types::EcoVec;
9use crate::allocator::{AllocatorProvider, Global};
10
11impl<T, A> Deref for EcoVec<T, A>
14where
15 A: AllocatorProvider,
16{
17 type Target = [T];
18
19 #[inline]
20 fn deref(&self) -> &Self::Target {
21 self.as_slice()
22 }
23}
24
25impl<T, A> Borrow<[T]> for EcoVec<T, A>
26where
27 A: AllocatorProvider,
28{
29 #[inline]
30 fn borrow(&self) -> &[T] {
31 self.as_slice()
32 }
33}
34
35impl<T, A> AsRef<[T]> for EcoVec<T, A>
36where
37 A: AllocatorProvider,
38{
39 #[inline]
40 fn as_ref(&self) -> &[T] {
41 self.as_slice()
42 }
43}
44
45impl<T, A> Hash for EcoVec<T, A>
48where
49 T: Hash,
50 A: AllocatorProvider,
51{
52 #[inline]
53 fn hash<H: Hasher>(&self, state: &mut H) {
54 self.as_slice().hash(state);
55 }
56}
57
58impl<T, A> Eq for EcoVec<T, A>
59where
60 T: Eq,
61 A: AllocatorProvider,
62{
63}
64
65impl<T, A> PartialEq for EcoVec<T, A>
66where
67 T: PartialEq,
68 A: AllocatorProvider,
69{
70 #[inline]
71 fn eq(&self, other: &Self) -> bool {
72 (self.ptr == other.ptr && self.len == other.len)
75 || self.as_slice() == other.as_slice()
76 }
77}
78
79impl<T, A> PartialEq<[T]> for EcoVec<T, A>
80where
81 T: PartialEq,
82 A: AllocatorProvider,
83{
84 #[inline]
85 fn eq(&self, other: &[T]) -> bool {
86 self.as_slice() == other
87 }
88}
89
90impl<T, A> PartialEq<&[T]> for EcoVec<T, A>
91where
92 T: PartialEq,
93 A: AllocatorProvider,
94{
95 #[inline]
96 fn eq(&self, other: &&[T]) -> bool {
97 self.as_slice() == *other
98 }
99}
100
101impl<T, A, const N: usize> PartialEq<[T; N]> for EcoVec<T, A>
102where
103 T: PartialEq,
104 A: AllocatorProvider,
105{
106 #[inline]
107 fn eq(&self, other: &[T; N]) -> bool {
108 self.as_slice() == other
109 }
110}
111
112impl<T, A, const N: usize> PartialEq<&[T; N]> for EcoVec<T, A>
113where
114 T: PartialEq,
115 A: AllocatorProvider,
116{
117 #[inline]
118 fn eq(&self, other: &&[T; N]) -> bool {
119 self.as_slice() == *other
120 }
121}
122
123impl<T, A> PartialEq<EcoVec<T, A>> for [T]
124where
125 T: PartialEq,
126 A: AllocatorProvider,
127{
128 #[inline]
129 fn eq(&self, other: &EcoVec<T, A>) -> bool {
130 self == other.as_slice()
131 }
132}
133
134impl<T, A, const N: usize> PartialEq<EcoVec<T, A>> for [T; N]
135where
136 T: PartialEq,
137 A: AllocatorProvider,
138{
139 #[inline]
140 fn eq(&self, other: &EcoVec<T, A>) -> bool {
141 self == other.as_slice()
142 }
143}
144
145impl<T, A> PartialEq<Vec<T>> for EcoVec<T, A>
146where
147 T: PartialEq,
148 A: AllocatorProvider,
149{
150 #[inline]
151 fn eq(&self, other: &Vec<T>) -> bool {
152 self.as_slice() == other.as_slice()
153 }
154}
155
156impl<T, A> PartialEq<EcoVec<T, A>> for Vec<T>
157where
158 T: PartialEq,
159 A: AllocatorProvider,
160{
161 #[inline]
162 fn eq(&self, other: &EcoVec<T, A>) -> bool {
163 self.as_slice() == other.as_slice()
164 }
165}
166
167impl<T, A> Ord for EcoVec<T, A>
168where
169 T: Ord,
170 A: AllocatorProvider,
171{
172 #[inline]
173 fn cmp(&self, other: &Self) -> Ordering {
174 self.as_slice().cmp(other.as_slice())
175 }
176}
177
178impl<T, A> PartialOrd for EcoVec<T, A>
179where
180 T: PartialOrd,
181 A: AllocatorProvider,
182{
183 #[inline]
184 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
185 self.as_slice().partial_cmp(other.as_slice())
186 }
187}
188
189impl<T> Default for EcoVec<T, Global> {
192 #[inline]
193 fn default() -> Self {
194 Self::new()
195 }
196}
197
198impl<T> From<&[T]> for EcoVec<T, Global>
199where
200 T: Clone,
201{
202 fn from(slice: &[T]) -> Self {
203 let mut vec = Self::with_capacity(slice.len());
204 vec.extend_from_slice(slice);
205 vec
206 }
207}
208
209impl<T, const N: usize> From<[T; N]> for EcoVec<T, Global>
210where
211 T: Clone,
212{
213 fn from(array: [T; N]) -> Self {
214 let mut vec = Self::with_capacity(N);
215 unsafe {
216 vec.extend_from_trusted(array);
218 }
219 vec
220 }
221}
222
223impl<T> From<Vec<T>> for EcoVec<T, Global>
224where
225 T: Clone,
226{
227 fn from(mut other: Vec<T>) -> Self {
229 let len = other.len();
230 let mut vec = Self::with_capacity(len);
231 unsafe {
232 other.set_len(0);
237
238 core::ptr::copy_nonoverlapping(other.as_ptr(), vec.data_mut(), len);
245
246 vec.len = len;
251 }
252 vec
253 }
254}
255
256impl<T, A, const N: usize> TryFrom<EcoVec<T, A>> for [T; N]
257where
258 T: Clone,
259 A: AllocatorProvider,
260{
261 type Error = EcoVec<T, A>;
262
263 fn try_from(mut vec: EcoVec<T, A>) -> Result<Self, Self::Error> {
264 if vec.len() != N {
265 return Err(vec);
266 }
267
268 Ok(if vec.is_unique() {
269 vec.len = 0;
271
272 unsafe { ptr::read(vec.data() as *const [T; N]) }
274 } else {
275 unsafe { core::array::from_fn(|i| vec.get_unchecked(i).clone()) }
277 })
278 }
279}
280
281impl<T, A> Extend<T> for EcoVec<T, A>
284where
285 T: Clone,
286 A: AllocatorProvider + Clone,
287{
288 fn extend<I>(&mut self, iter: I)
289 where
290 I: IntoIterator<Item = T>,
291 {
292 let iter = iter.into_iter();
293 let hint = iter.size_hint().0;
294 if hint > 0 {
295 self.reserve(hint);
296 }
297 for value in iter {
301 if self.len < self.capacity() && self.is_unique() {
302 unsafe { self.push_unchecked(value) };
303 } else {
304 self.push(value);
305 }
306 }
307 }
308}
309
310impl<T> FromIterator<T> for EcoVec<T, Global>
311where
312 T: Clone,
313{
314 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
315 let iter = iter.into_iter();
316 let hint = iter.size_hint().0;
317 let mut vec = Self::with_capacity(hint);
318 vec.extend(iter);
319 vec
320 }
321}
322
323impl<'a, T, A> IntoIterator for &'a EcoVec<T, A>
324where
325 A: AllocatorProvider,
326{
327 type IntoIter = core::slice::Iter<'a, T>;
328 type Item = &'a T;
329
330 #[inline]
331 fn into_iter(self) -> Self::IntoIter {
332 self.as_slice().iter()
333 }
334}
335
336impl<T, A> IntoIterator for EcoVec<T, A>
337where
338 T: Clone,
339 A: AllocatorProvider,
340{
341 type IntoIter = IntoIter<T, A>;
342 type Item = T;
343
344 #[inline]
345 fn into_iter(mut self) -> Self::IntoIter {
346 IntoIter {
347 unique: self.is_unique(),
348 front: 0,
349 back: self.len,
350 vec: self,
351 }
352 }
353}
354
355pub struct IntoIter<T, A = Global>
364where
365 A: AllocatorProvider,
366{
367 vec: EcoVec<T, A>,
368 unique: bool,
369 front: usize,
370 back: usize,
371}
372
373impl<T, A> IntoIter<T, A>
374where
375 A: AllocatorProvider,
376{
377 #[inline]
379 pub fn as_slice(&self) -> &[T] {
380 unsafe {
381 core::slice::from_raw_parts(
382 self.vec.data().add(self.front),
383 self.back - self.front,
384 )
385 }
386 }
387}
388
389impl<T, A> Iterator for IntoIter<T, A>
390where
391 T: Clone,
392 A: AllocatorProvider,
393{
394 type Item = T;
395
396 #[inline]
397 fn next(&mut self) -> Option<Self::Item> {
398 (self.front < self.back).then(|| {
399 let prev = self.front;
400 self.front += 1;
401 if self.unique {
402 unsafe { ptr::read(self.vec.data().add(prev)) }
403 } else {
404 unsafe { self.vec.get_unchecked(prev).clone() }
405 }
406 })
407 }
408
409 #[inline]
410 fn size_hint(&self) -> (usize, Option<usize>) {
411 let len = self.back - self.front;
412 (len, Some(len))
413 }
414
415 #[inline]
416 fn count(self) -> usize {
417 self.len()
418 }
419}
420
421impl<T, A> DoubleEndedIterator for IntoIter<T, A>
422where
423 T: Clone,
424 A: AllocatorProvider,
425{
426 #[inline]
427 fn next_back(&mut self) -> Option<Self::Item> {
428 (self.back > self.front).then(|| {
429 self.back -= 1;
430 if self.unique {
431 unsafe { ptr::read(self.vec.data().add(self.back)) }
432 } else {
433 unsafe { self.vec.get_unchecked(self.back).clone() }
434 }
435 })
436 }
437}
438
439impl<T, A> ExactSizeIterator for IntoIter<T, A>
440where
441 T: Clone,
442 A: AllocatorProvider,
443{
444}
445
446impl<T, A> Drop for IntoIter<T, A>
447where
448 A: AllocatorProvider,
449{
450 fn drop(&mut self) {
451 if !self.unique || !self.vec.is_allocated() {
452 return;
453 }
454
455 unsafe {
456 self.vec.len = 0;
459
460 ptr::drop_in_place(ptr::slice_from_raw_parts_mut(
462 self.vec.data_mut().add(self.front),
463 self.back - self.front,
464 ));
465 }
466 }
467}
468
469impl<T, A> core::fmt::Debug for IntoIter<T, A>
470where
471 T: core::fmt::Debug,
472 A: AllocatorProvider,
473{
474 #[inline]
475 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
476 f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
477 }
478}