1use std::{fmt, marker::PhantomData, mem, ptr};
4
5use crate::{ffi, translate::*};
6
7const MIN_SIZE: usize = 16;
10
11pub struct PtrSlice<T: TransparentPtrType> {
19 ptr: ptr::NonNull<<T as GlibPtrDefault>::GlibType>,
20 len: usize,
23 capacity: usize,
26}
27
28impl<T: fmt::Debug + TransparentPtrType> fmt::Debug for PtrSlice<T> {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 self.as_slice().fmt(f)
31 }
32}
33
34unsafe impl<T: Send + TransparentPtrType> Send for PtrSlice<T> {}
35
36unsafe impl<T: Sync + TransparentPtrType> Sync for PtrSlice<T> {}
37
38impl<T: PartialEq + TransparentPtrType> PartialEq for PtrSlice<T> {
39 #[inline]
40 fn eq(&self, other: &Self) -> bool {
41 self.as_slice() == other.as_slice()
42 }
43}
44
45impl<T: Eq + TransparentPtrType> Eq for PtrSlice<T> {}
46
47impl<T: PartialOrd + TransparentPtrType> PartialOrd for PtrSlice<T> {
48 #[inline]
49 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
50 self.as_slice().partial_cmp(other.as_slice())
51 }
52}
53
54impl<T: Ord + TransparentPtrType> Ord for PtrSlice<T> {
55 #[inline]
56 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
57 self.as_slice().cmp(other.as_slice())
58 }
59}
60
61impl<T: std::hash::Hash + TransparentPtrType> std::hash::Hash for PtrSlice<T> {
62 #[inline]
63 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
64 self.as_slice().hash(state)
65 }
66}
67
68impl<T: PartialEq + TransparentPtrType> PartialEq<[T]> for PtrSlice<T> {
69 #[inline]
70 fn eq(&self, other: &[T]) -> bool {
71 self.as_slice() == other
72 }
73}
74
75impl<T: PartialEq + TransparentPtrType> PartialEq<PtrSlice<T>> for [T] {
76 #[inline]
77 fn eq(&self, other: &PtrSlice<T>) -> bool {
78 self == other.as_slice()
79 }
80}
81
82impl<T: TransparentPtrType> Drop for PtrSlice<T> {
83 #[inline]
84 fn drop(&mut self) {
85 unsafe {
86 if mem::needs_drop::<T>() {
87 for i in 0..self.len {
88 ptr::drop_in_place::<T>(self.ptr.as_ptr().add(i) as *mut T);
89 }
90 }
91
92 if self.capacity != 0 {
93 ffi::g_free(self.ptr.as_ptr() as ffi::gpointer);
94 }
95 }
96 }
97}
98
99impl<T: TransparentPtrType> AsRef<[T]> for PtrSlice<T> {
100 #[inline]
101 fn as_ref(&self) -> &[T] {
102 self.as_slice()
103 }
104}
105
106impl<T: TransparentPtrType> AsMut<[T]> for PtrSlice<T> {
107 #[inline]
108 fn as_mut(&mut self) -> &mut [T] {
109 self.as_mut_slice()
110 }
111}
112
113impl<T: TransparentPtrType> std::borrow::Borrow<[T]> for PtrSlice<T> {
114 #[inline]
115 fn borrow(&self) -> &[T] {
116 self.as_slice()
117 }
118}
119
120impl<T: TransparentPtrType> std::borrow::BorrowMut<[T]> for PtrSlice<T> {
121 #[inline]
122 fn borrow_mut(&mut self) -> &mut [T] {
123 self.as_mut_slice()
124 }
125}
126
127impl<T: TransparentPtrType> std::ops::Deref for PtrSlice<T> {
128 type Target = [T];
129
130 #[inline]
131 fn deref(&self) -> &[T] {
132 self.as_slice()
133 }
134}
135
136impl<T: TransparentPtrType> std::ops::DerefMut for PtrSlice<T> {
137 #[inline]
138 fn deref_mut(&mut self) -> &mut [T] {
139 self.as_mut_slice()
140 }
141}
142
143impl<T: TransparentPtrType> Default for PtrSlice<T> {
144 #[inline]
145 fn default() -> Self {
146 Self::new()
147 }
148}
149
150impl<T: TransparentPtrType> std::iter::Extend<T> for PtrSlice<T> {
151 #[inline]
152 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
153 let iter = iter.into_iter();
154 self.reserve(iter.size_hint().0);
155
156 for item in iter {
157 self.push(item);
158 }
159 }
160}
161
162impl<'a, T: TransparentPtrType + 'a> std::iter::Extend<&'a T> for PtrSlice<T> {
163 #[inline]
164 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
165 let iter = iter.into_iter();
166 self.reserve(iter.size_hint().0);
167
168 for item in iter {
169 self.push(item.clone());
170 }
171 }
172}
173
174impl<T: TransparentPtrType> std::iter::FromIterator<T> for PtrSlice<T> {
175 #[inline]
176 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
177 let iter = iter.into_iter();
178 let mut s = Self::with_capacity(iter.size_hint().0);
179 for item in iter {
180 s.push(item);
181 }
182 s
183 }
184}
185
186impl<'a, T: TransparentPtrType> std::iter::IntoIterator for &'a PtrSlice<T> {
187 type Item = &'a T;
188 type IntoIter = std::slice::Iter<'a, T>;
189
190 #[inline]
191 fn into_iter(self) -> Self::IntoIter {
192 self.as_slice().iter()
193 }
194}
195
196impl<'a, T: TransparentPtrType> std::iter::IntoIterator for &'a mut PtrSlice<T> {
197 type Item = &'a mut T;
198 type IntoIter = std::slice::IterMut<'a, T>;
199
200 #[inline]
201 fn into_iter(self) -> Self::IntoIter {
202 self.as_mut_slice().iter_mut()
203 }
204}
205
206impl<T: TransparentPtrType> std::iter::IntoIterator for PtrSlice<T> {
207 type Item = T;
208 type IntoIter = IntoIter<T>;
209
210 #[inline]
211 fn into_iter(self) -> Self::IntoIter {
212 IntoIter::new(self)
213 }
214}
215
216pub struct IntoIter<T: TransparentPtrType> {
217 ptr: ptr::NonNull<<T as GlibPtrDefault>::GlibType>,
218 idx: ptr::NonNull<<T as GlibPtrDefault>::GlibType>,
219 len: usize,
220 empty: bool,
221}
222
223impl<T: TransparentPtrType> IntoIter<T> {
224 #[inline]
225 fn new(slice: PtrSlice<T>) -> Self {
226 let slice = mem::ManuallyDrop::new(slice);
227 IntoIter {
228 ptr: slice.ptr,
229 idx: slice.ptr,
230 len: slice.len,
231 empty: slice.capacity == 0,
232 }
233 }
234
235 #[inline]
238 pub fn as_slice(&self) -> &[T] {
239 unsafe {
240 if self.len == 0 {
241 &[]
242 } else {
243 std::slice::from_raw_parts(self.idx.as_ptr() as *mut T, self.len)
244 }
245 }
246 }
247
248 #[inline]
251 pub fn as_mut_slice(&mut self) -> &mut [T] {
252 unsafe {
253 if self.len == 0 {
254 &mut []
255 } else {
256 std::slice::from_raw_parts_mut(self.idx.as_ptr() as *mut T, self.len)
257 }
258 }
259 }
260}
261
262impl<T: TransparentPtrType> Drop for IntoIter<T> {
263 #[inline]
264 fn drop(&mut self) {
265 unsafe {
266 if mem::needs_drop::<T>() {
267 for i in 0..self.len {
268 ptr::drop_in_place::<T>(self.idx.as_ptr().add(i) as *mut T);
269 }
270 }
271
272 if !self.empty {
273 ffi::g_free(self.ptr.as_ptr() as ffi::gpointer);
274 }
275 }
276 }
277}
278
279impl<T: TransparentPtrType> Iterator for IntoIter<T> {
280 type Item = T;
281
282 #[inline]
283 fn next(&mut self) -> Option<Self::Item> {
284 if self.len == 0 {
285 return None;
286 }
287
288 unsafe {
289 let p = self.idx.as_ptr();
290 self.len -= 1;
291 self.idx = ptr::NonNull::new_unchecked(p.add(1));
292 Some(ptr::read(p as *mut T))
293 }
294 }
295
296 #[inline]
297 fn size_hint(&self) -> (usize, Option<usize>) {
298 (self.len, Some(self.len))
299 }
300
301 #[inline]
302 fn count(self) -> usize {
303 self.len
304 }
305
306 #[inline]
307 fn last(mut self) -> Option<T> {
308 if self.len == 0 {
309 None
310 } else {
311 self.len -= 1;
312 Some(unsafe { ptr::read(self.idx.as_ptr().add(self.len) as *mut T) })
313 }
314 }
315}
316
317impl<T: TransparentPtrType> DoubleEndedIterator for IntoIter<T> {
318 #[inline]
319 fn next_back(&mut self) -> Option<T> {
320 if self.len == 0 {
321 None
322 } else {
323 self.len -= 1;
324 Some(unsafe { ptr::read(self.idx.as_ptr().add(self.len) as *mut T) })
325 }
326 }
327}
328
329impl<T: TransparentPtrType> ExactSizeIterator for IntoIter<T> {}
330
331impl<T: TransparentPtrType> std::iter::FusedIterator for IntoIter<T> {}
332
333impl<T: TransparentPtrType> From<PtrSlice<T>> for Vec<T> {
334 #[inline]
335 fn from(mut value: PtrSlice<T>) -> Self {
336 unsafe {
337 let mut s = Vec::with_capacity(value.len);
338 ptr::copy_nonoverlapping(value.ptr.as_ptr() as *const T, s.as_mut_ptr(), value.len);
339 s.set_len(value.len);
340 value.len = 0;
341 s
342 }
343 }
344}
345
346impl<T: TransparentPtrType> From<Vec<T>> for PtrSlice<T> {
347 #[inline]
348 fn from(mut value: Vec<T>) -> Self {
349 unsafe {
350 let mut s = Self::with_capacity(value.len());
351 ptr::copy_nonoverlapping(value.as_ptr(), s.ptr.as_ptr() as *mut T, value.len());
352 s.len = value.len();
353 value.set_len(0);
354 ptr::write(
355 s.ptr.as_ptr().add(s.len),
356 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
357 );
358 s
359 }
360 }
361}
362
363impl<T: TransparentPtrType, const N: usize> From<[T; N]> for PtrSlice<T> {
364 #[inline]
365 fn from(value: [T; N]) -> Self {
366 unsafe {
367 let value = mem::ManuallyDrop::new(value);
368 let len = value.len();
369 let mut s = Self::with_capacity(len);
370 ptr::copy_nonoverlapping(value.as_ptr(), s.ptr.as_ptr() as *mut T, len);
371 s.len = len;
372 ptr::write(
373 s.ptr.as_ptr().add(len),
374 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
375 );
376 s
377 }
378 }
379}
380
381impl<'a, T: TransparentPtrType> From<&'a [T]> for PtrSlice<T> {
382 #[inline]
383 fn from(value: &'a [T]) -> Self {
384 unsafe {
385 let mut s = Self::with_capacity(value.len());
386 for (i, item) in value.iter().enumerate() {
387 ptr::write(s.ptr.as_ptr().add(i) as *mut T, item.clone());
388 }
389 s.len = value.len();
390 ptr::write(
391 s.ptr.as_ptr().add(s.len),
392 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
393 );
394 s
395 }
396 }
397}
398
399impl<'a, T: TransparentPtrType> From<&'a [&'a T]> for PtrSlice<T> {
400 #[inline]
401 fn from(value: &'a [&'a T]) -> Self {
402 unsafe {
403 let mut s = Self::with_capacity(value.len());
404 for (i, item) in value.iter().enumerate() {
405 ptr::write(s.ptr.as_ptr().add(i) as *mut T, (*item).clone());
406 }
407 s.len = value.len();
408 ptr::write(
409 s.ptr.as_ptr().add(s.len),
410 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
411 );
412 s
413 }
414 }
415}
416
417impl<T: TransparentPtrType> Clone for PtrSlice<T> {
418 #[inline]
419 fn clone(&self) -> Self {
420 Self::from(self.as_slice())
421 }
422}
423
424impl<T: TransparentPtrType> PtrSlice<T> {
425 #[inline]
428 pub unsafe fn from_glib_borrow<'a>(ptr: *const <T as GlibPtrDefault>::GlibType) -> &'a [T] {
429 let mut len = 0;
430 if !ptr.is_null() {
431 while !(*ptr.add(len)).is_null() {
432 len += 1;
433 }
434 }
435 Self::from_glib_borrow_num(ptr, len)
436 }
437
438 #[inline]
441 pub unsafe fn from_glib_borrow_num<'a>(
442 ptr: *const <T as GlibPtrDefault>::GlibType,
443 len: usize,
444 ) -> &'a [T] {
445 debug_assert_eq!(
446 mem::size_of::<T>(),
447 mem::size_of::<<T as GlibPtrDefault>::GlibType>()
448 );
449 debug_assert!(!ptr.is_null() || len == 0);
450
451 if len == 0 {
452 &[]
453 } else {
454 std::slice::from_raw_parts(ptr as *const T, len)
455 }
456 }
457
458 #[inline]
461 pub unsafe fn from_glib_none_num(
462 ptr: *const <T as GlibPtrDefault>::GlibType,
463 len: usize,
464 _null_terminated: bool,
465 ) -> Self {
466 debug_assert_eq!(
467 mem::size_of::<T>(),
468 mem::size_of::<<T as GlibPtrDefault>::GlibType>()
469 );
470 debug_assert!(!ptr.is_null() || len == 0);
471
472 if len == 0 {
473 PtrSlice::default()
474 } else {
475 let s = Self::from_glib_borrow_num(ptr, len);
477 Self::from(s)
478 }
479 }
480
481 #[inline]
484 pub unsafe fn from_glib_container_num(
485 ptr: *mut <T as GlibPtrDefault>::GlibType,
486 len: usize,
487 null_terminated: bool,
488 ) -> Self {
489 debug_assert_eq!(
490 mem::size_of::<T>(),
491 mem::size_of::<<T as GlibPtrDefault>::GlibType>()
492 );
493 debug_assert!(!ptr.is_null() || len == 0);
494
495 if len == 0 {
496 ffi::g_free(ptr as ffi::gpointer);
497 PtrSlice::default()
498 } else {
499 for i in 0..len {
501 let p = ptr.add(i) as *mut T;
502 let clone: T = (*p).clone();
503 ptr::write(p, clone);
504 }
505
506 Self::from_glib_full_num(ptr, len, null_terminated)
508 }
509 }
510
511 #[inline]
514 pub unsafe fn from_glib_full_num(
515 ptr: *mut <T as GlibPtrDefault>::GlibType,
516 len: usize,
517 null_terminated: bool,
518 ) -> Self {
519 debug_assert_eq!(
520 mem::size_of::<T>(),
521 mem::size_of::<<T as GlibPtrDefault>::GlibType>()
522 );
523 debug_assert!(!ptr.is_null() || len == 0);
524
525 if len == 0 {
526 ffi::g_free(ptr as ffi::gpointer);
527 PtrSlice::default()
528 } else {
529 if null_terminated {
530 return PtrSlice {
531 ptr: ptr::NonNull::new_unchecked(ptr),
532 len,
533 capacity: len + 1,
534 };
535 }
536
537 let capacity = len + 1;
539 assert_ne!(capacity, 0);
540 let ptr = ffi::g_realloc(
541 ptr as *mut _,
542 mem::size_of::<T>().checked_mul(capacity).unwrap(),
543 ) as *mut <T as GlibPtrDefault>::GlibType;
544
545 ptr::write(
546 ptr.add(len),
547 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
548 );
549
550 PtrSlice {
551 ptr: ptr::NonNull::new_unchecked(ptr),
552 len,
553 capacity,
554 }
555 }
556 }
557
558 #[inline]
561 pub unsafe fn from_glib_none(ptr: *const <T as GlibPtrDefault>::GlibType) -> Self {
562 let mut len = 0;
563 if !ptr.is_null() {
564 while !(*ptr.add(len)).is_null() {
565 len += 1;
566 }
567 }
568
569 PtrSlice::from_glib_none_num(ptr, len, true)
570 }
571
572 #[inline]
575 pub unsafe fn from_glib_container(ptr: *mut <T as GlibPtrDefault>::GlibType) -> Self {
576 let mut len = 0;
577 if !ptr.is_null() {
578 while !(*ptr.add(len)).is_null() {
579 len += 1;
580 }
581 }
582
583 PtrSlice::from_glib_container_num(ptr, len, true)
584 }
585
586 #[inline]
589 pub unsafe fn from_glib_full(ptr: *mut <T as GlibPtrDefault>::GlibType) -> Self {
590 let mut len = 0;
591 if !ptr.is_null() {
592 while !(*ptr.add(len)).is_null() {
593 len += 1;
594 }
595 }
596
597 PtrSlice::from_glib_full_num(ptr, len, true)
598 }
599
600 #[inline]
603 pub fn new() -> Self {
604 debug_assert_eq!(
605 mem::size_of::<T>(),
606 mem::size_of::<<T as GlibPtrDefault>::GlibType>()
607 );
608
609 PtrSlice {
610 ptr: ptr::NonNull::dangling(),
611 len: 0,
612 capacity: 0,
613 }
614 }
615
616 #[inline]
619 pub fn with_capacity(capacity: usize) -> Self {
620 let mut s = Self::new();
621 s.reserve(capacity);
622 s
623 }
624
625 #[inline]
630 pub fn as_ptr(&self) -> *const <T as GlibPtrDefault>::GlibType {
631 if self.len == 0 {
632 static EMPTY: [usize; 1] = [0];
633
634 EMPTY.as_ptr() as *const _
635 } else {
636 self.ptr.as_ptr()
637 }
638 }
639
640 #[inline]
645 pub fn as_mut_ptr(&mut self) -> *mut <T as GlibPtrDefault>::GlibType {
646 if self.len == 0 {
647 static EMPTY: [usize; 1] = [0];
648
649 EMPTY.as_ptr() as *mut _
650 } else {
651 self.ptr.as_ptr()
652 }
653 }
654
655 #[inline]
660 pub fn into_raw(mut self) -> *mut <T as GlibPtrDefault>::GlibType {
661 if self.len == 0 {
664 self.reserve(0);
665 unsafe {
666 ptr::write(
667 self.ptr.as_ptr().add(0),
668 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
669 );
670 }
671 }
672
673 self.len = 0;
674 self.capacity = 0;
675 self.ptr.as_ptr()
676 }
677
678 #[inline]
681 pub fn len(&self) -> usize {
682 self.len
683 }
684
685 #[inline]
688 pub fn is_empty(&self) -> bool {
689 self.len == 0
690 }
691
692 #[inline]
697 pub fn capacity(&self) -> usize {
698 self.capacity
699 }
700
701 pub unsafe fn set_len(&mut self, len: usize) {
708 self.len = len;
709 }
710
711 #[allow(clippy::int_plus_one)]
714 pub fn reserve(&mut self, additional: usize) {
715 if self.len + additional + 1 <= self.capacity {
717 return;
718 }
719
720 let new_capacity =
721 usize::next_power_of_two(std::cmp::max(self.len + additional, MIN_SIZE) + 1);
722 assert_ne!(new_capacity, 0);
723 assert!(new_capacity > self.capacity);
724
725 unsafe {
726 let ptr = if self.capacity == 0 {
727 ptr::null_mut()
728 } else {
729 self.ptr.as_ptr() as *mut _
730 };
731 let new_ptr =
732 ffi::g_realloc(ptr, mem::size_of::<T>().checked_mul(new_capacity).unwrap())
733 as *mut <T as GlibPtrDefault>::GlibType;
734 if self.capacity == 0 {
735 ptr::write(
736 new_ptr,
737 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
738 );
739 }
740 self.ptr = ptr::NonNull::new_unchecked(new_ptr);
741 self.capacity = new_capacity;
742 }
743 }
744
745 #[inline]
748 pub fn as_slice(&self) -> &[T] {
749 unsafe {
750 if self.len == 0 {
751 &[]
752 } else {
753 std::slice::from_raw_parts(self.ptr.as_ptr() as *const T, self.len)
754 }
755 }
756 }
757
758 #[inline]
761 pub fn as_mut_slice(&mut self) -> &mut [T] {
762 unsafe {
763 if self.len == 0 {
764 &mut []
765 } else {
766 std::slice::from_raw_parts_mut(self.ptr.as_ptr() as *mut T, self.len)
767 }
768 }
769 }
770
771 #[inline]
774 pub fn clear(&mut self) {
775 unsafe {
776 if mem::needs_drop::<T>() {
777 for i in 0..self.len {
778 ptr::drop_in_place::<T>(self.ptr.as_ptr().add(i) as *mut T);
779 }
780 }
781
782 self.len = 0;
783 }
784 }
785
786 #[inline]
789 pub fn extend_from_slice(&mut self, other: &[T]) {
790 if self.len + other.len() + 1 > self.capacity {
792 self.reserve(other.len());
793 }
794
795 unsafe {
796 for item in other {
797 ptr::write(self.ptr.as_ptr().add(self.len) as *mut T, item.clone());
798 self.len += 1;
799 }
800
801 ptr::write(
802 self.ptr.as_ptr().add(self.len),
803 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
804 );
805 }
806 }
807
808 #[inline]
812 pub fn insert(&mut self, index: usize, item: T) {
813 assert!(index <= self.len);
814
815 if self.len + 1 + 1 > self.capacity {
817 self.reserve(1);
818 }
819
820 unsafe {
821 if index == self.len {
822 ptr::write(self.ptr.as_ptr().add(self.len) as *mut T, item);
823 } else {
824 let p = self.ptr.as_ptr().add(index);
825 ptr::copy(p, p.add(1), self.len - index);
826 ptr::write(self.ptr.as_ptr().add(index) as *mut T, item);
827 }
828
829 self.len += 1;
830
831 ptr::write(
832 self.ptr.as_ptr().add(self.len),
833 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
834 );
835 }
836 }
837
838 #[inline]
841 pub fn push(&mut self, item: T) {
842 if self.len + 1 + 1 > self.capacity {
844 self.reserve(1);
845 }
846
847 unsafe {
848 ptr::write(self.ptr.as_ptr().add(self.len) as *mut T, item);
849 self.len += 1;
850
851 ptr::write(
852 self.ptr.as_ptr().add(self.len),
853 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
854 );
855 }
856 }
857
858 #[inline]
862 pub fn remove(&mut self, index: usize) -> T {
863 assert!(index < self.len);
864
865 unsafe {
866 let p = self.ptr.as_ptr().add(index);
867 let item = ptr::read(p as *mut T);
868 ptr::copy(p.add(1), p, self.len - index - 1);
869
870 self.len -= 1;
871
872 ptr::write(
873 self.ptr.as_ptr().add(self.len),
874 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
875 );
876
877 item
878 }
879 }
880
881 #[inline]
884 pub fn pop(&mut self) -> Option<T> {
885 if self.len == 0 {
886 return None;
887 }
888
889 unsafe {
890 self.len -= 1;
891 let p = self.ptr.as_ptr().add(self.len);
892 let item = ptr::read(p as *mut T);
893
894 ptr::write(
895 self.ptr.as_ptr().add(self.len),
896 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
897 );
898
899 Some(item)
900 }
901 }
902
903 #[inline]
908 pub fn truncate(&mut self, len: usize) {
909 if self.len <= len {
910 return;
911 }
912
913 unsafe {
914 while self.len > len {
915 self.len -= 1;
916 let p = self.ptr.as_ptr().add(self.len);
917 ptr::drop_in_place::<T>(p as *mut T);
918 ptr::write(
919 p,
920 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
921 );
922 }
923 }
924 }
925}
926
927impl<T: TransparentPtrType>
928 FromGlibContainer<<T as GlibPtrDefault>::GlibType, *mut <T as GlibPtrDefault>::GlibType>
929 for PtrSlice<T>
930{
931 #[inline]
932 unsafe fn from_glib_none_num(ptr: *mut <T as GlibPtrDefault>::GlibType, num: usize) -> Self {
933 Self::from_glib_none_num(ptr, num, false)
934 }
935
936 #[inline]
937 unsafe fn from_glib_container_num(
938 ptr: *mut <T as GlibPtrDefault>::GlibType,
939 num: usize,
940 ) -> Self {
941 Self::from_glib_container_num(ptr, num, false)
942 }
943
944 #[inline]
945 unsafe fn from_glib_full_num(ptr: *mut <T as GlibPtrDefault>::GlibType, num: usize) -> Self {
946 Self::from_glib_full_num(ptr, num, false)
947 }
948}
949
950impl<T: TransparentPtrType>
951 FromGlibContainer<<T as GlibPtrDefault>::GlibType, *const <T as GlibPtrDefault>::GlibType>
952 for PtrSlice<T>
953{
954 unsafe fn from_glib_none_num(ptr: *const <T as GlibPtrDefault>::GlibType, num: usize) -> Self {
955 Self::from_glib_none_num(ptr, num, false)
956 }
957
958 unsafe fn from_glib_container_num(
959 _ptr: *const <T as GlibPtrDefault>::GlibType,
960 _num: usize,
961 ) -> Self {
962 unimplemented!();
963 }
964
965 unsafe fn from_glib_full_num(
966 _ptr: *const <T as GlibPtrDefault>::GlibType,
967 _num: usize,
968 ) -> Self {
969 unimplemented!();
970 }
971}
972
973impl<T: TransparentPtrType>
974 FromGlibPtrContainer<<T as GlibPtrDefault>::GlibType, *mut <T as GlibPtrDefault>::GlibType>
975 for PtrSlice<T>
976{
977 #[inline]
978 unsafe fn from_glib_none(ptr: *mut <T as GlibPtrDefault>::GlibType) -> Self {
979 Self::from_glib_none(ptr)
980 }
981
982 #[inline]
983 unsafe fn from_glib_container(ptr: *mut <T as GlibPtrDefault>::GlibType) -> Self {
984 Self::from_glib_container(ptr)
985 }
986
987 #[inline]
988 unsafe fn from_glib_full(ptr: *mut <T as GlibPtrDefault>::GlibType) -> Self {
989 Self::from_glib_full(ptr)
990 }
991}
992
993impl<T: TransparentPtrType>
994 FromGlibPtrContainer<<T as GlibPtrDefault>::GlibType, *const <T as GlibPtrDefault>::GlibType>
995 for PtrSlice<T>
996{
997 #[inline]
998 unsafe fn from_glib_none(ptr: *const <T as GlibPtrDefault>::GlibType) -> Self {
999 Self::from_glib_none(ptr)
1000 }
1001
1002 unsafe fn from_glib_container(_ptr: *const <T as GlibPtrDefault>::GlibType) -> Self {
1003 unimplemented!();
1004 }
1005
1006 unsafe fn from_glib_full(_ptr: *const <T as GlibPtrDefault>::GlibType) -> Self {
1007 unimplemented!();
1008 }
1009}
1010
1011impl<'a, T: TransparentPtrType + 'a> ToGlibPtr<'a, *mut <T as GlibPtrDefault>::GlibType>
1012 for PtrSlice<T>
1013{
1014 type Storage = PhantomData<&'a Self>;
1015
1016 #[inline]
1017 fn to_glib_none(&'a self) -> Stash<'a, *mut <T as GlibPtrDefault>::GlibType, Self> {
1018 Stash(self.as_ptr() as *mut _, PhantomData)
1019 }
1020
1021 #[inline]
1022 fn to_glib_container(&'a self) -> Stash<'a, *mut <T as GlibPtrDefault>::GlibType, Self> {
1023 unsafe {
1024 let ptr = ffi::g_malloc(mem::size_of::<T>().checked_mul(self.len() + 1).unwrap())
1025 as *mut <T as GlibPtrDefault>::GlibType;
1026 ptr::copy_nonoverlapping(self.as_ptr(), ptr, self.len() + 1);
1027 Stash(ptr, PhantomData)
1028 }
1029 }
1030
1031 #[inline]
1032 fn to_glib_full(&self) -> *mut <T as GlibPtrDefault>::GlibType {
1033 self.clone().into_raw()
1034 }
1035}
1036
1037impl<'a, T: TransparentPtrType + 'a> ToGlibPtr<'a, *const <T as GlibPtrDefault>::GlibType>
1038 for PtrSlice<T>
1039{
1040 type Storage = PhantomData<&'a Self>;
1041
1042 #[inline]
1043 fn to_glib_none(&'a self) -> Stash<'a, *const <T as GlibPtrDefault>::GlibType, Self> {
1044 Stash(self.as_ptr(), PhantomData)
1045 }
1046}
1047
1048impl<'a, T: TransparentPtrType + 'a> ToGlibPtrMut<'a, *mut <T as GlibPtrDefault>::GlibType>
1049 for PtrSlice<T>
1050{
1051 type Storage = PhantomData<&'a mut Self>;
1052
1053 #[inline]
1054 fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut <T as GlibPtrDefault>::GlibType, Self> {
1055 StashMut(self.as_mut_ptr(), PhantomData)
1056 }
1057}
1058
1059impl<T: TransparentPtrType> IntoGlibPtr<*mut <T as GlibPtrDefault>::GlibType> for PtrSlice<T> {
1060 #[inline]
1061 unsafe fn into_glib_ptr(self) -> *mut <T as GlibPtrDefault>::GlibType {
1062 self.into_raw()
1063 }
1064}
1065
1066impl<T: TransparentPtrType> From<super::Slice<T>> for PtrSlice<T> {
1067 fn from(value: super::Slice<T>) -> Self {
1068 let len = value.len();
1069 let capacity = value.capacity();
1070 unsafe {
1071 let ptr = value.into_raw();
1072 let mut s = PtrSlice::<T> {
1073 ptr: ptr::NonNull::new_unchecked(ptr),
1074 len,
1075 capacity,
1076 };
1077
1078 if len == capacity {
1080 s.reserve(0);
1081 }
1082
1083 ptr::write(
1084 s.ptr.as_ptr().add(s.len()),
1085 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
1086 );
1087
1088 s
1089 }
1090 }
1091}
1092
1093pub trait IntoPtrSlice<T: TransparentPtrType> {
1096 fn run_with_ptr_slice<R, F: FnOnce(&[<T as GlibPtrDefault>::GlibType]) -> R>(self, f: F) -> R;
1099}
1100
1101impl<T: TransparentPtrType> IntoPtrSlice<T> for PtrSlice<T> {
1102 #[inline]
1103 fn run_with_ptr_slice<R, F: FnOnce(&[<T as GlibPtrDefault>::GlibType]) -> R>(self, f: F) -> R {
1104 <&Self>::run_with_ptr_slice(&self, f)
1105 }
1106}
1107
1108impl<T: TransparentPtrType> IntoPtrSlice<T> for &'_ PtrSlice<T> {
1109 #[inline]
1110 fn run_with_ptr_slice<R, F: FnOnce(&[<T as GlibPtrDefault>::GlibType]) -> R>(self, f: F) -> R {
1111 f(unsafe { std::slice::from_raw_parts(self.as_ptr() as *mut _, self.len() + 1) })
1112 }
1113}
1114
1115const MAX_STACK_ALLOCATION: usize = 16;
1118
1119impl<T: TransparentPtrType> IntoPtrSlice<T> for Vec<T> {
1120 #[inline]
1121 fn run_with_ptr_slice<R, F: FnOnce(&[<T as GlibPtrDefault>::GlibType]) -> R>(self, f: F) -> R {
1122 if self.len() < MAX_STACK_ALLOCATION {
1123 unsafe {
1124 let mut s = mem::MaybeUninit::<
1125 [<T as GlibPtrDefault>::GlibType; MAX_STACK_ALLOCATION],
1126 >::uninit();
1127 let ptr = s.as_mut_ptr() as *mut <T as GlibPtrDefault>::GlibType;
1128 ptr::copy_nonoverlapping(
1129 self.as_ptr() as *mut <T as GlibPtrDefault>::GlibType,
1130 ptr,
1131 self.len(),
1132 );
1133 ptr::write(
1134 ptr.add(self.len()),
1135 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
1136 );
1137 f(std::slice::from_raw_parts(ptr, self.len() + 1))
1138 }
1139 } else {
1140 PtrSlice::<T>::from(self).run_with_ptr_slice(f)
1141 }
1142 }
1143}
1144
1145impl<T: TransparentPtrType, const N: usize> IntoPtrSlice<T> for [T; N] {
1146 #[inline]
1147 fn run_with_ptr_slice<R, F: FnOnce(&[<T as GlibPtrDefault>::GlibType]) -> R>(self, f: F) -> R {
1148 if self.len() < MAX_STACK_ALLOCATION {
1149 unsafe {
1150 let mut s = mem::MaybeUninit::<
1151 [<T as GlibPtrDefault>::GlibType; MAX_STACK_ALLOCATION],
1152 >::uninit();
1153 let ptr = s.as_mut_ptr() as *mut <T as GlibPtrDefault>::GlibType;
1154 ptr::copy_nonoverlapping(
1155 self.as_ptr() as *mut <T as GlibPtrDefault>::GlibType,
1156 ptr,
1157 self.len(),
1158 );
1159 ptr::write(
1160 ptr.add(self.len()),
1161 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
1162 );
1163 f(std::slice::from_raw_parts(ptr, self.len() + 1))
1164 }
1165 } else {
1166 PtrSlice::<T>::from(self).run_with_ptr_slice(f)
1167 }
1168 }
1169}
1170
1171impl<T: TransparentPtrType> IntoPtrSlice<T> for &'_ [T] {
1172 #[inline]
1173 fn run_with_ptr_slice<R, F: FnOnce(&[<T as GlibPtrDefault>::GlibType]) -> R>(self, f: F) -> R {
1174 if self.len() < MAX_STACK_ALLOCATION {
1175 unsafe {
1176 let mut s = mem::MaybeUninit::<
1177 [<T as GlibPtrDefault>::GlibType; MAX_STACK_ALLOCATION],
1178 >::uninit();
1179 let ptr = s.as_mut_ptr() as *mut <T as GlibPtrDefault>::GlibType;
1180 ptr::copy_nonoverlapping(
1181 self.as_ptr() as *mut <T as GlibPtrDefault>::GlibType,
1182 ptr,
1183 self.len(),
1184 );
1185 ptr::write(
1186 ptr.add(self.len()),
1187 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
1188 );
1189 f(std::slice::from_raw_parts(ptr, self.len() + 1))
1190 }
1191 } else {
1192 PtrSlice::<T>::from(self).run_with_ptr_slice(f)
1193 }
1194 }
1195}
1196
1197#[cfg(test)]
1198mod test {
1199 use super::*;
1200
1201 #[test]
1202 fn test_from_glib_full() {
1203 let items = [
1204 crate::Error::new(crate::FileError::Failed, "Failed 1"),
1205 crate::Error::new(crate::FileError::Noent, "Failed 2"),
1206 crate::Error::new(crate::FileError::Io, "Failed 3"),
1207 crate::Error::new(crate::FileError::Perm, "Failed 4"),
1208 ];
1209
1210 let slice = unsafe {
1211 let ptr = ffi::g_malloc(mem::size_of::<ffi::GDate>() * 4) as *mut *mut ffi::GError;
1212 ptr::write(ptr.add(0), items[0].to_glib_full());
1213 ptr::write(ptr.add(1), items[1].to_glib_full());
1214 ptr::write(ptr.add(2), items[2].to_glib_full());
1215 ptr::write(ptr.add(3), items[3].to_glib_full());
1216
1217 PtrSlice::<crate::Error>::from_glib_full_num(ptr, 4, false)
1218 };
1219
1220 for (a, b) in Iterator::zip(items.iter(), slice.iter()) {
1221 assert_eq!(a.message(), b.message());
1222 assert_eq!(
1223 a.kind::<crate::FileError>().unwrap(),
1224 b.kind::<crate::FileError>().unwrap()
1225 );
1226 }
1227 }
1228
1229 #[test]
1230 fn test_from_glib_none() {
1231 let items = [
1232 crate::Error::new(crate::FileError::Failed, "Failed 1"),
1233 crate::Error::new(crate::FileError::Noent, "Failed 2"),
1234 crate::Error::new(crate::FileError::Io, "Failed 3"),
1235 crate::Error::new(crate::FileError::Perm, "Failed 4"),
1236 ];
1237
1238 let slice = unsafe {
1239 PtrSlice::<crate::Error>::from_glib_none_num(
1240 items.as_ptr() as *const *mut ffi::GError,
1241 4,
1242 false,
1243 )
1244 };
1245
1246 for (a, b) in Iterator::zip(items.iter(), slice.iter()) {
1247 assert_eq!(a.message(), b.message());
1248 assert_eq!(
1249 a.kind::<crate::FileError>().unwrap(),
1250 b.kind::<crate::FileError>().unwrap()
1251 );
1252 }
1253 }
1254
1255 #[test]
1256 fn test_safe_api() {
1257 let items = [
1258 crate::Error::new(crate::FileError::Failed, "Failed 1"),
1259 crate::Error::new(crate::FileError::Noent, "Failed 2"),
1260 crate::Error::new(crate::FileError::Io, "Failed 3"),
1261 ];
1262
1263 let mut slice = PtrSlice::from(&items[..]);
1264 assert_eq!(slice.len(), 3);
1265 slice.push(crate::Error::new(crate::FileError::Perm, "Failed 4"));
1266 assert_eq!(slice.len(), 4);
1267
1268 for (a, b) in Iterator::zip(items.iter(), slice.iter()) {
1269 assert_eq!(a.message(), b.message());
1270 assert_eq!(
1271 a.kind::<crate::FileError>().unwrap(),
1272 b.kind::<crate::FileError>().unwrap()
1273 );
1274 }
1275 assert_eq!(slice[3].message(), "Failed 4");
1276
1277 let vec = Vec::from(slice);
1278 assert_eq!(vec.len(), 4);
1279 for (a, b) in Iterator::zip(items.iter(), vec.iter()) {
1280 assert_eq!(a.message(), b.message());
1281 assert_eq!(
1282 a.kind::<crate::FileError>().unwrap(),
1283 b.kind::<crate::FileError>().unwrap()
1284 );
1285 }
1286 assert_eq!(vec[3].message(), "Failed 4");
1287
1288 let mut slice = PtrSlice::from(vec);
1289 assert_eq!(slice.len(), 4);
1290 let e = slice.pop().unwrap();
1291 assert_eq!(e.message(), "Failed 4");
1292 assert_eq!(slice.len(), 3);
1293 slice.insert(2, e);
1294 assert_eq!(slice.len(), 4);
1295 assert_eq!(slice[0].message(), "Failed 1");
1296 assert_eq!(slice[1].message(), "Failed 2");
1297 assert_eq!(slice[2].message(), "Failed 4");
1298 assert_eq!(slice[3].message(), "Failed 3");
1299 let e = slice.remove(2);
1300 assert_eq!(e.message(), "Failed 4");
1301 assert_eq!(slice.len(), 3);
1302 slice.push(e);
1303 assert_eq!(slice.len(), 4);
1304
1305 let slice2 = crate::Slice::from(slice.clone());
1306
1307 for (a, b) in Iterator::zip(items.iter(), slice.into_iter()) {
1308 assert_eq!(a.message(), b.message());
1309 assert_eq!(
1310 a.kind::<crate::FileError>().unwrap(),
1311 b.kind::<crate::FileError>().unwrap()
1312 );
1313 }
1314
1315 let slice3 = crate::PtrSlice::from(slice2.clone());
1316
1317 for (a, b) in Iterator::zip(items.iter(), slice2.into_iter()) {
1318 assert_eq!(a.message(), b.message());
1319 assert_eq!(
1320 a.kind::<crate::FileError>().unwrap(),
1321 b.kind::<crate::FileError>().unwrap()
1322 );
1323 }
1324
1325 for (a, b) in Iterator::zip(items.iter(), slice3.into_iter()) {
1326 assert_eq!(a.message(), b.message());
1327 assert_eq!(
1328 a.kind::<crate::FileError>().unwrap(),
1329 b.kind::<crate::FileError>().unwrap()
1330 );
1331 }
1332 }
1333
1334 #[test]
1335 fn test_into_ptrslice() {
1336 let items = [
1337 crate::Error::new(crate::FileError::Failed, "Failed 1"),
1338 crate::Error::new(crate::FileError::Noent, "Failed 2"),
1339 crate::Error::new(crate::FileError::Io, "Failed 3"),
1340 crate::Error::new(crate::FileError::Perm, "Failed 4"),
1341 ];
1342
1343 items[..].run_with_ptr_slice(|s| unsafe {
1344 assert!(s[4].is_null());
1345 assert_eq!(s.len(), items.len() + 1);
1346 let s = std::slice::from_raw_parts(s.as_ptr() as *const crate::Error, items.len());
1347 assert_eq!(s, items);
1348 });
1349
1350 Vec::from(&items[..]).run_with_ptr_slice(|s| unsafe {
1351 assert!(s[4].is_null());
1352 assert_eq!(s.len(), items.len() + 1);
1353 let s = std::slice::from_raw_parts(s.as_ptr() as *const crate::Error, items.len());
1354 for (a, b) in Iterator::zip(items.iter(), s.iter()) {
1355 assert_eq!(a.message(), b.message());
1356 assert_eq!(
1357 a.kind::<crate::FileError>().unwrap(),
1358 b.kind::<crate::FileError>().unwrap()
1359 );
1360 }
1361 });
1362
1363 PtrSlice::<crate::Error>::from(&items[..]).run_with_ptr_slice(|s| unsafe {
1364 assert!(s[4].is_null());
1365 assert_eq!(s.len(), items.len() + 1);
1366 let s = std::slice::from_raw_parts(s.as_ptr() as *const crate::Error, items.len());
1367 for (a, b) in Iterator::zip(items.iter(), s.iter()) {
1368 assert_eq!(a.message(), b.message());
1369 assert_eq!(
1370 a.kind::<crate::FileError>().unwrap(),
1371 b.kind::<crate::FileError>().unwrap()
1372 );
1373 }
1374 });
1375
1376 let v = Vec::from(&items[..]);
1377 items.run_with_ptr_slice(|s| unsafe {
1378 assert!(s[4].is_null());
1379 assert_eq!(s.len(), v.len() + 1);
1380 let s = std::slice::from_raw_parts(s.as_ptr() as *const crate::Error, v.len());
1381 for (a, b) in Iterator::zip(v.iter(), s.iter()) {
1382 assert_eq!(a.message(), b.message());
1383 assert_eq!(
1384 a.kind::<crate::FileError>().unwrap(),
1385 b.kind::<crate::FileError>().unwrap()
1386 );
1387 }
1388 });
1389 }
1390}