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