pgrx/slice.rs
1//LICENSE Portions Copyright 2019-2021 ZomboDB, LLC.
2//LICENSE
3//LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc.
4//LICENSE
5//LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. <contact@pgcentral.org>
6//LICENSE
7//LICENSE All rights reserved.
8//LICENSE
9//LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file.
10#![allow(dead_code)]
11use crate::prelude::*;
12use core::marker::PhantomData;
13use core::ptr;
14
15/// PallocSlice is between slice and Vec: PallocSlice does not assume the underlying T is valid for all indices
16/// and so does not implement the safe trait Index, but does let you call an `unsafe fn get` to do so,
17/// and manages its own Drop implementation for the pallocation.
18///
19/// Note that while it's technically not lifetime-bound, it's still bound to the lifetime of the memory context.
20/// You should use this inside types that are themselves lifetime-bound to prevent inappropriate "escape".
21pub struct PallocSlice<T> {
22 pallocd: ptr::NonNull<[T]>,
23 _phantom: PhantomData<Box<[T]>>,
24}
25
26impl<T> PallocSlice<T> {
27 pub unsafe fn from_raw_parts(ptr: ptr::NonNull<T>, len: usize) -> Self {
28 PallocSlice {
29 pallocd: ptr::NonNull::new_unchecked(ptr::slice_from_raw_parts_mut(ptr.as_ptr(), len)),
30 _phantom: PhantomData,
31 }
32 }
33
34 /// # Safety
35 /// You must know the underlying type at that index is validly initialized in Rust.
36 #[inline]
37 pub unsafe fn get(&self, index: usize) -> Option<&T> {
38 index.le(&self.pallocd.len()).then(|| self.get_unchecked(index))
39 }
40
41 /// # Safety
42 /// You must know the underlying type at that index is validly initialized in Rust,
43 /// AND that the index is inbounds.
44 #[inline]
45 pub unsafe fn get_unchecked(&self, index: usize) -> &T {
46 self.pallocd.as_ptr().cast::<T>().add(index).as_ref().unwrap_unchecked()
47 }
48}
49
50impl<T> Drop for PallocSlice<T> {
51 fn drop(&mut self) {
52 unsafe { pg_sys::pfree(self.pallocd.cast().as_ptr()) }
53 }
54}