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 unsafe {
430 let mut len = 0;
431 if !ptr.is_null() {
432 while !(*ptr.add(len)).is_null() {
433 len += 1;
434 }
435 }
436 Self::from_glib_borrow_num(ptr, len)
437 }
438 }
439
440 #[inline]
443 pub unsafe fn from_glib_borrow_num<'a>(
444 ptr: *const <T as GlibPtrDefault>::GlibType,
445 len: usize,
446 ) -> &'a [T] {
447 unsafe {
448 debug_assert_eq!(
449 mem::size_of::<T>(),
450 mem::size_of::<<T as GlibPtrDefault>::GlibType>()
451 );
452 debug_assert!(!ptr.is_null() || len == 0);
453
454 if len == 0 {
455 &[]
456 } else {
457 std::slice::from_raw_parts(ptr as *const T, len)
458 }
459 }
460 }
461
462 #[inline]
465 pub unsafe fn from_glib_none_num(
466 ptr: *const <T as GlibPtrDefault>::GlibType,
467 len: usize,
468 _null_terminated: bool,
469 ) -> Self {
470 unsafe {
471 debug_assert_eq!(
472 mem::size_of::<T>(),
473 mem::size_of::<<T as GlibPtrDefault>::GlibType>()
474 );
475 debug_assert!(!ptr.is_null() || len == 0);
476
477 if len == 0 {
478 PtrSlice::default()
479 } else {
480 let s = Self::from_glib_borrow_num(ptr, len);
482 Self::from(s)
483 }
484 }
485 }
486
487 #[inline]
490 pub unsafe fn from_glib_container_num(
491 ptr: *mut <T as GlibPtrDefault>::GlibType,
492 len: usize,
493 null_terminated: bool,
494 ) -> Self {
495 unsafe {
496 debug_assert_eq!(
497 mem::size_of::<T>(),
498 mem::size_of::<<T as GlibPtrDefault>::GlibType>()
499 );
500 debug_assert!(!ptr.is_null() || len == 0);
501
502 if len == 0 {
503 ffi::g_free(ptr as ffi::gpointer);
504 PtrSlice::default()
505 } else {
506 for i in 0..len {
508 let p = ptr.add(i) as *mut T;
509 let clone: T = (*p).clone();
510 ptr::write(p, clone);
511 }
512
513 Self::from_glib_full_num(ptr, len, null_terminated)
515 }
516 }
517 }
518
519 #[inline]
522 pub unsafe fn from_glib_full_num(
523 ptr: *mut <T as GlibPtrDefault>::GlibType,
524 len: usize,
525 null_terminated: bool,
526 ) -> Self {
527 unsafe {
528 debug_assert_eq!(
529 mem::size_of::<T>(),
530 mem::size_of::<<T as GlibPtrDefault>::GlibType>()
531 );
532 debug_assert!(!ptr.is_null() || len == 0);
533
534 if len == 0 {
535 ffi::g_free(ptr as ffi::gpointer);
536 PtrSlice::default()
537 } else {
538 if null_terminated {
539 return PtrSlice {
540 ptr: ptr::NonNull::new_unchecked(ptr),
541 len,
542 capacity: len + 1,
543 };
544 }
545
546 let capacity = len + 1;
548 assert_ne!(capacity, 0);
549 let ptr = ffi::g_realloc(
550 ptr as *mut _,
551 mem::size_of::<T>().checked_mul(capacity).unwrap(),
552 ) as *mut <T as GlibPtrDefault>::GlibType;
553
554 ptr::write(
555 ptr.add(len),
556 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
557 );
558
559 PtrSlice {
560 ptr: ptr::NonNull::new_unchecked(ptr),
561 len,
562 capacity,
563 }
564 }
565 }
566 }
567
568 #[inline]
571 pub unsafe fn from_glib_none(ptr: *const <T as GlibPtrDefault>::GlibType) -> Self {
572 unsafe {
573 let mut len = 0;
574 if !ptr.is_null() {
575 while !(*ptr.add(len)).is_null() {
576 len += 1;
577 }
578 }
579
580 PtrSlice::from_glib_none_num(ptr, len, true)
581 }
582 }
583
584 #[inline]
587 pub unsafe fn from_glib_container(ptr: *mut <T as GlibPtrDefault>::GlibType) -> Self {
588 unsafe {
589 let mut len = 0;
590 if !ptr.is_null() {
591 while !(*ptr.add(len)).is_null() {
592 len += 1;
593 }
594 }
595
596 PtrSlice::from_glib_container_num(ptr, len, true)
597 }
598 }
599
600 #[inline]
603 pub unsafe fn from_glib_full(ptr: *mut <T as GlibPtrDefault>::GlibType) -> Self {
604 unsafe {
605 let mut len = 0;
606 if !ptr.is_null() {
607 while !(*ptr.add(len)).is_null() {
608 len += 1;
609 }
610 }
611
612 PtrSlice::from_glib_full_num(ptr, len, true)
613 }
614 }
615
616 #[inline]
619 pub fn new() -> Self {
620 debug_assert_eq!(
621 mem::size_of::<T>(),
622 mem::size_of::<<T as GlibPtrDefault>::GlibType>()
623 );
624
625 PtrSlice {
626 ptr: ptr::NonNull::dangling(),
627 len: 0,
628 capacity: 0,
629 }
630 }
631
632 #[inline]
635 pub fn with_capacity(capacity: usize) -> Self {
636 let mut s = Self::new();
637 s.reserve(capacity);
638 s
639 }
640
641 #[inline]
646 pub fn as_ptr(&self) -> *const <T as GlibPtrDefault>::GlibType {
647 if self.len == 0 {
648 static EMPTY: [usize; 1] = [0];
649
650 EMPTY.as_ptr() as *const _
651 } else {
652 self.ptr.as_ptr()
653 }
654 }
655
656 #[inline]
661 pub fn as_mut_ptr(&mut self) -> *mut <T as GlibPtrDefault>::GlibType {
662 if self.len == 0 {
663 static EMPTY: [usize; 1] = [0];
664
665 EMPTY.as_ptr() as *mut _
666 } else {
667 self.ptr.as_ptr()
668 }
669 }
670
671 #[inline]
676 pub fn into_raw(mut self) -> *mut <T as GlibPtrDefault>::GlibType {
677 if self.len == 0 {
680 self.reserve(0);
681 unsafe {
682 ptr::write(
683 self.ptr.as_ptr().add(0),
684 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
685 );
686 }
687 }
688
689 self.len = 0;
690 self.capacity = 0;
691 self.ptr.as_ptr()
692 }
693
694 #[inline]
697 pub fn len(&self) -> usize {
698 self.len
699 }
700
701 #[inline]
704 pub fn is_empty(&self) -> bool {
705 self.len == 0
706 }
707
708 #[inline]
713 pub fn capacity(&self) -> usize {
714 self.capacity
715 }
716
717 pub unsafe fn set_len(&mut self, len: usize) {
724 self.len = len;
725 }
726
727 #[allow(clippy::int_plus_one)]
730 pub fn reserve(&mut self, additional: usize) {
731 if additional < self.capacity - self.len {
733 return;
734 }
735
736 let new_capacity =
737 usize::next_power_of_two(std::cmp::max(self.len + additional, MIN_SIZE) + 1);
738 assert_ne!(new_capacity, 0);
739 assert!(new_capacity > self.capacity);
740
741 unsafe {
742 let ptr = if self.capacity == 0 {
743 ptr::null_mut()
744 } else {
745 self.ptr.as_ptr() as *mut _
746 };
747 let new_ptr =
748 ffi::g_realloc(ptr, mem::size_of::<T>().checked_mul(new_capacity).unwrap())
749 as *mut <T as GlibPtrDefault>::GlibType;
750 if self.capacity == 0 {
751 ptr::write(
752 new_ptr,
753 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
754 );
755 }
756 self.ptr = ptr::NonNull::new_unchecked(new_ptr);
757 self.capacity = new_capacity;
758 }
759 }
760
761 #[inline]
764 pub fn as_slice(&self) -> &[T] {
765 unsafe {
766 if self.len == 0 {
767 &[]
768 } else {
769 std::slice::from_raw_parts(self.ptr.as_ptr() as *const T, self.len)
770 }
771 }
772 }
773
774 #[inline]
777 pub fn as_mut_slice(&mut self) -> &mut [T] {
778 unsafe {
779 if self.len == 0 {
780 &mut []
781 } else {
782 std::slice::from_raw_parts_mut(self.ptr.as_ptr() as *mut T, self.len)
783 }
784 }
785 }
786
787 #[inline]
790 pub fn clear(&mut self) {
791 unsafe {
792 if mem::needs_drop::<T>() {
793 for i in 0..self.len {
794 ptr::drop_in_place::<T>(self.ptr.as_ptr().add(i) as *mut T);
795 }
796 }
797
798 self.len = 0;
799 }
800 }
801
802 #[inline]
805 pub fn extend_from_slice(&mut self, other: &[T]) {
806 if other.len() >= self.capacity - self.len {
808 self.reserve(other.len());
809 }
810
811 unsafe {
812 for item in other {
813 ptr::write(self.ptr.as_ptr().add(self.len) as *mut T, item.clone());
814 self.len += 1;
815
816 ptr::write(
819 self.ptr.as_ptr().add(self.len),
820 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
821 );
822 }
823 }
824 }
825
826 #[inline]
830 pub fn insert(&mut self, index: usize, item: T) {
831 assert!(index <= self.len);
832
833 if 1 >= self.capacity - self.len {
835 self.reserve(1);
836 }
837
838 unsafe {
839 if index == self.len {
840 ptr::write(self.ptr.as_ptr().add(self.len) as *mut T, item);
841 } else {
842 let p = self.ptr.as_ptr().add(index);
843 ptr::copy(p, p.add(1), self.len - index);
844 ptr::write(self.ptr.as_ptr().add(index) as *mut T, item);
845 }
846
847 self.len += 1;
848
849 ptr::write(
850 self.ptr.as_ptr().add(self.len),
851 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
852 );
853 }
854 }
855
856 #[inline]
859 pub fn push(&mut self, item: T) {
860 if 1 >= self.capacity - self.len {
862 self.reserve(1);
863 }
864
865 unsafe {
866 ptr::write(self.ptr.as_ptr().add(self.len) as *mut T, item);
867 self.len += 1;
868
869 ptr::write(
870 self.ptr.as_ptr().add(self.len),
871 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
872 );
873 }
874 }
875
876 #[inline]
880 pub fn remove(&mut self, index: usize) -> T {
881 assert!(index < self.len);
882
883 unsafe {
884 let p = self.ptr.as_ptr().add(index);
885 let item = ptr::read(p as *mut T);
886 ptr::copy(p.add(1), p, self.len - index - 1);
887
888 self.len -= 1;
889
890 ptr::write(
891 self.ptr.as_ptr().add(self.len),
892 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
893 );
894
895 item
896 }
897 }
898
899 #[inline]
902 pub fn pop(&mut self) -> Option<T> {
903 if self.len == 0 {
904 return None;
905 }
906
907 unsafe {
908 self.len -= 1;
909 let p = self.ptr.as_ptr().add(self.len);
910 let item = ptr::read(p as *mut T);
911
912 ptr::write(
913 self.ptr.as_ptr().add(self.len),
914 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
915 );
916
917 Some(item)
918 }
919 }
920
921 #[inline]
926 pub fn truncate(&mut self, len: usize) {
927 if self.len <= len {
928 return;
929 }
930
931 unsafe {
932 while self.len > len {
933 self.len -= 1;
934 let p = self.ptr.as_ptr().add(self.len);
935 ptr::drop_in_place::<T>(p as *mut T);
936 ptr::write(
937 p,
938 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
939 );
940 }
941 }
942 }
943}
944
945impl<T: TransparentPtrType>
946 FromGlibContainer<<T as GlibPtrDefault>::GlibType, *mut <T as GlibPtrDefault>::GlibType>
947 for PtrSlice<T>
948{
949 #[inline]
950 unsafe fn from_glib_none_num(ptr: *mut <T as GlibPtrDefault>::GlibType, num: usize) -> Self {
951 unsafe { Self::from_glib_none_num(ptr, num, false) }
952 }
953
954 #[inline]
955 unsafe fn from_glib_container_num(
956 ptr: *mut <T as GlibPtrDefault>::GlibType,
957 num: usize,
958 ) -> Self {
959 unsafe { Self::from_glib_container_num(ptr, num, false) }
960 }
961
962 #[inline]
963 unsafe fn from_glib_full_num(ptr: *mut <T as GlibPtrDefault>::GlibType, num: usize) -> Self {
964 unsafe { Self::from_glib_full_num(ptr, num, false) }
965 }
966}
967
968impl<T: TransparentPtrType>
969 FromGlibContainer<<T as GlibPtrDefault>::GlibType, *const <T as GlibPtrDefault>::GlibType>
970 for PtrSlice<T>
971{
972 unsafe fn from_glib_none_num(ptr: *const <T as GlibPtrDefault>::GlibType, num: usize) -> Self {
973 unsafe { Self::from_glib_none_num(ptr, num, false) }
974 }
975
976 unsafe fn from_glib_container_num(
977 _ptr: *const <T as GlibPtrDefault>::GlibType,
978 _num: usize,
979 ) -> Self {
980 unimplemented!();
981 }
982
983 unsafe fn from_glib_full_num(
984 _ptr: *const <T as GlibPtrDefault>::GlibType,
985 _num: usize,
986 ) -> Self {
987 unimplemented!();
988 }
989}
990
991impl<T: TransparentPtrType>
992 FromGlibPtrContainer<<T as GlibPtrDefault>::GlibType, *mut <T as GlibPtrDefault>::GlibType>
993 for PtrSlice<T>
994{
995 #[inline]
996 unsafe fn from_glib_none(ptr: *mut <T as GlibPtrDefault>::GlibType) -> Self {
997 unsafe { Self::from_glib_none(ptr) }
998 }
999
1000 #[inline]
1001 unsafe fn from_glib_container(ptr: *mut <T as GlibPtrDefault>::GlibType) -> Self {
1002 unsafe { Self::from_glib_container(ptr) }
1003 }
1004
1005 #[inline]
1006 unsafe fn from_glib_full(ptr: *mut <T as GlibPtrDefault>::GlibType) -> Self {
1007 unsafe { Self::from_glib_full(ptr) }
1008 }
1009}
1010
1011impl<T: TransparentPtrType>
1012 FromGlibPtrContainer<<T as GlibPtrDefault>::GlibType, *const <T as GlibPtrDefault>::GlibType>
1013 for PtrSlice<T>
1014{
1015 #[inline]
1016 unsafe fn from_glib_none(ptr: *const <T as GlibPtrDefault>::GlibType) -> Self {
1017 unsafe { Self::from_glib_none(ptr) }
1018 }
1019
1020 unsafe fn from_glib_container(_ptr: *const <T as GlibPtrDefault>::GlibType) -> Self {
1021 unimplemented!();
1022 }
1023
1024 unsafe fn from_glib_full(_ptr: *const <T as GlibPtrDefault>::GlibType) -> Self {
1025 unimplemented!();
1026 }
1027}
1028
1029impl<'a, T: TransparentPtrType + 'a> ToGlibPtr<'a, *mut <T as GlibPtrDefault>::GlibType>
1030 for PtrSlice<T>
1031{
1032 type Storage = PhantomData<&'a Self>;
1033
1034 #[inline]
1035 fn to_glib_none(&'a self) -> Stash<'a, *mut <T as GlibPtrDefault>::GlibType, Self> {
1036 Stash(self.as_ptr() as *mut _, PhantomData)
1037 }
1038
1039 #[inline]
1040 fn to_glib_container(&'a self) -> Stash<'a, *mut <T as GlibPtrDefault>::GlibType, Self> {
1041 unsafe {
1042 let ptr = ffi::g_malloc(mem::size_of::<T>().checked_mul(self.len() + 1).unwrap())
1043 as *mut <T as GlibPtrDefault>::GlibType;
1044 ptr::copy_nonoverlapping(self.as_ptr(), ptr, self.len() + 1);
1045 Stash(ptr, PhantomData)
1046 }
1047 }
1048
1049 #[inline]
1050 fn to_glib_full(&self) -> *mut <T as GlibPtrDefault>::GlibType {
1051 self.clone().into_raw()
1052 }
1053}
1054
1055impl<'a, T: TransparentPtrType + 'a> ToGlibPtr<'a, *const <T as GlibPtrDefault>::GlibType>
1056 for PtrSlice<T>
1057{
1058 type Storage = PhantomData<&'a Self>;
1059
1060 #[inline]
1061 fn to_glib_none(&'a self) -> Stash<'a, *const <T as GlibPtrDefault>::GlibType, Self> {
1062 Stash(self.as_ptr(), PhantomData)
1063 }
1064}
1065
1066impl<'a, T: TransparentPtrType + 'a> ToGlibPtrMut<'a, *mut <T as GlibPtrDefault>::GlibType>
1067 for PtrSlice<T>
1068{
1069 type Storage = PhantomData<&'a mut Self>;
1070
1071 #[inline]
1072 fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut <T as GlibPtrDefault>::GlibType, Self> {
1073 StashMut(self.as_mut_ptr(), PhantomData)
1074 }
1075}
1076
1077impl<T: TransparentPtrType> IntoGlibPtr<*mut <T as GlibPtrDefault>::GlibType> for PtrSlice<T> {
1078 #[inline]
1079 fn into_glib_ptr(self) -> *mut <T as GlibPtrDefault>::GlibType {
1080 self.into_raw()
1081 }
1082}
1083
1084impl<T: TransparentPtrType> From<super::Slice<T>> for PtrSlice<T> {
1085 fn from(value: super::Slice<T>) -> Self {
1086 let len = value.len();
1087 let capacity = value.capacity();
1088 unsafe {
1089 let ptr = value.into_raw();
1090 let mut s = PtrSlice::<T> {
1091 ptr: ptr::NonNull::new_unchecked(ptr),
1092 len,
1093 capacity,
1094 };
1095
1096 if len == capacity {
1098 s.reserve(0);
1099 }
1100
1101 ptr::write(
1102 s.ptr.as_ptr().add(s.len()),
1103 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
1104 );
1105
1106 s
1107 }
1108 }
1109}
1110
1111pub trait IntoPtrSlice<T: TransparentPtrType> {
1114 fn run_with_ptr_slice<R, F: FnOnce(&[<T as GlibPtrDefault>::GlibType]) -> R>(self, f: F) -> R;
1117}
1118
1119impl<T: TransparentPtrType> IntoPtrSlice<T> for PtrSlice<T> {
1120 #[inline]
1121 fn run_with_ptr_slice<R, F: FnOnce(&[<T as GlibPtrDefault>::GlibType]) -> R>(self, f: F) -> R {
1122 <&Self>::run_with_ptr_slice(&self, f)
1123 }
1124}
1125
1126impl<T: TransparentPtrType> IntoPtrSlice<T> for &'_ PtrSlice<T> {
1127 #[inline]
1128 fn run_with_ptr_slice<R, F: FnOnce(&[<T as GlibPtrDefault>::GlibType]) -> R>(self, f: F) -> R {
1129 f(unsafe { std::slice::from_raw_parts(self.as_ptr() as *mut _, self.len() + 1) })
1130 }
1131}
1132
1133const MAX_STACK_ALLOCATION: usize = 16;
1136
1137impl<T: TransparentPtrType> IntoPtrSlice<T> for Vec<T> {
1138 #[inline]
1139 fn run_with_ptr_slice<R, F: FnOnce(&[<T as GlibPtrDefault>::GlibType]) -> R>(self, f: F) -> R {
1140 if self.len() < MAX_STACK_ALLOCATION {
1141 unsafe {
1142 let mut s = mem::MaybeUninit::<
1143 [<T as GlibPtrDefault>::GlibType; MAX_STACK_ALLOCATION],
1144 >::uninit();
1145 let ptr = s.as_mut_ptr() as *mut <T as GlibPtrDefault>::GlibType;
1146 ptr::copy_nonoverlapping(
1147 self.as_ptr() as *mut <T as GlibPtrDefault>::GlibType,
1148 ptr,
1149 self.len(),
1150 );
1151 ptr::write(
1152 ptr.add(self.len()),
1153 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
1154 );
1155 f(std::slice::from_raw_parts(ptr, self.len() + 1))
1156 }
1157 } else {
1158 PtrSlice::<T>::from(self).run_with_ptr_slice(f)
1159 }
1160 }
1161}
1162
1163impl<T: TransparentPtrType, const N: usize> IntoPtrSlice<T> for [T; N] {
1164 #[inline]
1165 fn run_with_ptr_slice<R, F: FnOnce(&[<T as GlibPtrDefault>::GlibType]) -> R>(self, f: F) -> R {
1166 if self.len() < MAX_STACK_ALLOCATION {
1167 unsafe {
1168 let mut s = mem::MaybeUninit::<
1169 [<T as GlibPtrDefault>::GlibType; MAX_STACK_ALLOCATION],
1170 >::uninit();
1171 let ptr = s.as_mut_ptr() as *mut <T as GlibPtrDefault>::GlibType;
1172 ptr::copy_nonoverlapping(
1173 self.as_ptr() as *mut <T as GlibPtrDefault>::GlibType,
1174 ptr,
1175 self.len(),
1176 );
1177 ptr::write(
1178 ptr.add(self.len()),
1179 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
1180 );
1181 f(std::slice::from_raw_parts(ptr, self.len() + 1))
1182 }
1183 } else {
1184 PtrSlice::<T>::from(self).run_with_ptr_slice(f)
1185 }
1186 }
1187}
1188
1189impl<T: TransparentPtrType> IntoPtrSlice<T> for &'_ [T] {
1190 #[inline]
1191 fn run_with_ptr_slice<R, F: FnOnce(&[<T as GlibPtrDefault>::GlibType]) -> R>(self, f: F) -> R {
1192 if self.len() < MAX_STACK_ALLOCATION {
1193 unsafe {
1194 let mut s = mem::MaybeUninit::<
1195 [<T as GlibPtrDefault>::GlibType; MAX_STACK_ALLOCATION],
1196 >::uninit();
1197 let ptr = s.as_mut_ptr() as *mut <T as GlibPtrDefault>::GlibType;
1198 ptr::copy_nonoverlapping(
1199 self.as_ptr() as *mut <T as GlibPtrDefault>::GlibType,
1200 ptr,
1201 self.len(),
1202 );
1203 ptr::write(
1204 ptr.add(self.len()),
1205 Ptr::from(ptr::null_mut::<<T as GlibPtrDefault>::GlibType>()),
1206 );
1207 f(std::slice::from_raw_parts(ptr, self.len() + 1))
1208 }
1209 } else {
1210 PtrSlice::<T>::from(self).run_with_ptr_slice(f)
1211 }
1212 }
1213}
1214
1215#[cfg(test)]
1216mod test {
1217 use super::*;
1218
1219 #[test]
1220 fn test_from_glib_full() {
1221 let items = [
1222 crate::Error::new(crate::FileError::Failed, "Failed 1"),
1223 crate::Error::new(crate::FileError::Noent, "Failed 2"),
1224 crate::Error::new(crate::FileError::Io, "Failed 3"),
1225 crate::Error::new(crate::FileError::Perm, "Failed 4"),
1226 ];
1227
1228 let slice = unsafe {
1229 let ptr = ffi::g_malloc(mem::size_of::<ffi::GDate>() * 4) as *mut *mut ffi::GError;
1230 ptr::write(ptr.add(0), items[0].to_glib_full());
1231 ptr::write(ptr.add(1), items[1].to_glib_full());
1232 ptr::write(ptr.add(2), items[2].to_glib_full());
1233 ptr::write(ptr.add(3), items[3].to_glib_full());
1234
1235 PtrSlice::<crate::Error>::from_glib_full_num(ptr, 4, false)
1236 };
1237
1238 for (a, b) in Iterator::zip(items.iter(), slice.iter()) {
1239 assert_eq!(a.message(), b.message());
1240 assert_eq!(
1241 a.kind::<crate::FileError>().unwrap(),
1242 b.kind::<crate::FileError>().unwrap()
1243 );
1244 }
1245 }
1246
1247 #[test]
1248 fn test_from_glib_none() {
1249 let items = [
1250 crate::Error::new(crate::FileError::Failed, "Failed 1"),
1251 crate::Error::new(crate::FileError::Noent, "Failed 2"),
1252 crate::Error::new(crate::FileError::Io, "Failed 3"),
1253 crate::Error::new(crate::FileError::Perm, "Failed 4"),
1254 ];
1255
1256 let slice = unsafe {
1257 PtrSlice::<crate::Error>::from_glib_none_num(
1258 items.as_ptr() as *const *mut ffi::GError,
1259 4,
1260 false,
1261 )
1262 };
1263
1264 for (a, b) in Iterator::zip(items.iter(), slice.iter()) {
1265 assert_eq!(a.message(), b.message());
1266 assert_eq!(
1267 a.kind::<crate::FileError>().unwrap(),
1268 b.kind::<crate::FileError>().unwrap()
1269 );
1270 }
1271 }
1272
1273 #[test]
1274 fn test_safe_api() {
1275 let items = [
1276 crate::Error::new(crate::FileError::Failed, "Failed 1"),
1277 crate::Error::new(crate::FileError::Noent, "Failed 2"),
1278 crate::Error::new(crate::FileError::Io, "Failed 3"),
1279 ];
1280
1281 let mut slice = PtrSlice::from(&items[..]);
1282 assert_eq!(slice.len(), 3);
1283 slice.push(crate::Error::new(crate::FileError::Perm, "Failed 4"));
1284 assert_eq!(slice.len(), 4);
1285
1286 for (a, b) in Iterator::zip(items.iter(), slice.iter()) {
1287 assert_eq!(a.message(), b.message());
1288 assert_eq!(
1289 a.kind::<crate::FileError>().unwrap(),
1290 b.kind::<crate::FileError>().unwrap()
1291 );
1292 }
1293 assert_eq!(slice[3].message(), "Failed 4");
1294
1295 let vec = Vec::from(slice);
1296 assert_eq!(vec.len(), 4);
1297 for (a, b) in Iterator::zip(items.iter(), vec.iter()) {
1298 assert_eq!(a.message(), b.message());
1299 assert_eq!(
1300 a.kind::<crate::FileError>().unwrap(),
1301 b.kind::<crate::FileError>().unwrap()
1302 );
1303 }
1304 assert_eq!(vec[3].message(), "Failed 4");
1305
1306 let mut slice = PtrSlice::from(vec);
1307 assert_eq!(slice.len(), 4);
1308 let e = slice.pop().unwrap();
1309 assert_eq!(e.message(), "Failed 4");
1310 assert_eq!(slice.len(), 3);
1311 slice.insert(2, e);
1312 assert_eq!(slice.len(), 4);
1313 assert_eq!(slice[0].message(), "Failed 1");
1314 assert_eq!(slice[1].message(), "Failed 2");
1315 assert_eq!(slice[2].message(), "Failed 4");
1316 assert_eq!(slice[3].message(), "Failed 3");
1317 let e = slice.remove(2);
1318 assert_eq!(e.message(), "Failed 4");
1319 assert_eq!(slice.len(), 3);
1320 slice.push(e);
1321 assert_eq!(slice.len(), 4);
1322
1323 let slice2 = crate::Slice::from(slice.clone());
1324
1325 for (a, b) in Iterator::zip(items.iter(), slice.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 let slice3 = crate::PtrSlice::from(slice2.clone());
1334
1335 for (a, b) in Iterator::zip(items.iter(), slice2.into_iter()) {
1336 assert_eq!(a.message(), b.message());
1337 assert_eq!(
1338 a.kind::<crate::FileError>().unwrap(),
1339 b.kind::<crate::FileError>().unwrap()
1340 );
1341 }
1342
1343 for (a, b) in Iterator::zip(items.iter(), slice3.into_iter()) {
1344 assert_eq!(a.message(), b.message());
1345 assert_eq!(
1346 a.kind::<crate::FileError>().unwrap(),
1347 b.kind::<crate::FileError>().unwrap()
1348 );
1349 }
1350 }
1351
1352 #[test]
1353 fn test_into_ptrslice() {
1354 let items = [
1355 crate::Error::new(crate::FileError::Failed, "Failed 1"),
1356 crate::Error::new(crate::FileError::Noent, "Failed 2"),
1357 crate::Error::new(crate::FileError::Io, "Failed 3"),
1358 crate::Error::new(crate::FileError::Perm, "Failed 4"),
1359 ];
1360
1361 items[..].run_with_ptr_slice(|s| unsafe {
1362 assert!(s[4].is_null());
1363 assert_eq!(s.len(), items.len() + 1);
1364 let s = std::slice::from_raw_parts(s.as_ptr() as *const crate::Error, items.len());
1365 assert_eq!(s, items);
1366 });
1367
1368 Vec::from(&items[..]).run_with_ptr_slice(|s| unsafe {
1369 assert!(s[4].is_null());
1370 assert_eq!(s.len(), items.len() + 1);
1371 let s = std::slice::from_raw_parts(s.as_ptr() as *const crate::Error, items.len());
1372 for (a, b) in Iterator::zip(items.iter(), s.iter()) {
1373 assert_eq!(a.message(), b.message());
1374 assert_eq!(
1375 a.kind::<crate::FileError>().unwrap(),
1376 b.kind::<crate::FileError>().unwrap()
1377 );
1378 }
1379 });
1380
1381 PtrSlice::<crate::Error>::from(&items[..]).run_with_ptr_slice(|s| unsafe {
1382 assert!(s[4].is_null());
1383 assert_eq!(s.len(), items.len() + 1);
1384 let s = std::slice::from_raw_parts(s.as_ptr() as *const crate::Error, items.len());
1385 for (a, b) in Iterator::zip(items.iter(), s.iter()) {
1386 assert_eq!(a.message(), b.message());
1387 assert_eq!(
1388 a.kind::<crate::FileError>().unwrap(),
1389 b.kind::<crate::FileError>().unwrap()
1390 );
1391 }
1392 });
1393
1394 let v = Vec::from(&items[..]);
1395 items.run_with_ptr_slice(|s| unsafe {
1396 assert!(s[4].is_null());
1397 assert_eq!(s.len(), v.len() + 1);
1398 let s = std::slice::from_raw_parts(s.as_ptr() as *const crate::Error, v.len());
1399 for (a, b) in Iterator::zip(v.iter(), s.iter()) {
1400 assert_eq!(a.message(), b.message());
1401 assert_eq!(
1402 a.kind::<crate::FileError>().unwrap(),
1403 b.kind::<crate::FileError>().unwrap()
1404 );
1405 }
1406 });
1407 }
1408}