rune_alloc/
slice.rs
1pub use self::iter::{RawIter, RawIterMut};
2pub(crate) mod iter;
3
4use crate::alloc::{Allocator, Global};
5use crate::borrow::TryToOwned;
6use crate::clone::TryClone;
7use crate::error::Error;
8use crate::{Box, Vec};
9
10cfg_if! {
11 if #[cfg(rune_nightly)] {
12 pub(crate) use core::slice::range;
13 } else {
14 use core::ops;
15
16 #[must_use]
17 pub(crate) fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
18 where
19 R: ops::RangeBounds<usize>,
20 {
21 let len = bounds.end;
22
23 let start: ops::Bound<&usize> = range.start_bound();
24 let start = match start {
25 ops::Bound::Included(&start) => start,
26 ops::Bound::Excluded(start) => start
27 .checked_add(1)
28 .unwrap_or_else(|| slice_start_index_overflow_fail()),
29 ops::Bound::Unbounded => 0,
30 };
31
32 let end: ops::Bound<&usize> = range.end_bound();
33 let end = match end {
34 ops::Bound::Included(end) => end
35 .checked_add(1)
36 .unwrap_or_else(|| slice_end_index_overflow_fail()),
37 ops::Bound::Excluded(&end) => end,
38 ops::Bound::Unbounded => len,
39 };
40
41 if start > end {
42 slice_index_order_fail(start, end);
43 }
44 if end > len {
45 slice_end_index_len_fail(end, len);
46 }
47
48 ops::Range { start, end }
49 }
50
51 const fn slice_start_index_overflow_fail() -> ! {
52 panic!("attempted to index slice from after maximum usize");
53 }
54
55 const fn slice_end_index_overflow_fail() -> ! {
56 panic!("attempted to index slice up to maximum usize");
57 }
58
59 fn slice_index_order_fail(index: usize, end: usize) -> ! {
60 panic!("slice index starts at {index} but ends at {end}");
61 }
62
63 fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
64 panic!("range end index {index} out of range for slice of length {len}");
65 }
66 }
67}
68
69#[inline]
74#[doc(hidden)]
75pub fn into_vec<T, A: Allocator>(this: Box<[T], A>) -> Vec<T, A> {
76 hack::into_vec(this)
78}
79
80#[inline]
81pub(crate) fn to_vec<T, A: Allocator>(s: &[T], alloc: A) -> Result<Vec<T, A>, Error>
82where
83 T: TryClone,
84{
85 hack::to_vec(s, alloc)
86}
87
88impl<T> TryToOwned for [T]
89where
90 T: TryClone,
91{
92 type Owned = Vec<T, Global>;
93
94 #[inline]
95 fn try_to_owned(&self) -> Result<Self::Owned, Error> {
96 hack::to_vec(self, Global)
97 }
98}
99
100pub(crate) mod hack {
105 use crate::alloc::Allocator;
106 use crate::clone::TryClone;
107 use crate::error::Error;
108 use crate::{Box, Vec};
109
110 pub(crate) fn into_vec<T, A: Allocator>(b: Box<[T], A>) -> Vec<T, A> {
114 unsafe {
115 let len = b.len();
116 let (b, alloc) = Box::into_raw_with_allocator(b);
117 Vec::from_raw_parts_in(b as *mut T, len, len, alloc)
118 }
119 }
120
121 #[inline]
122 pub(crate) fn to_vec<T: ConvertVec, A: Allocator>(
123 s: &[T],
124 alloc: A,
125 ) -> Result<Vec<T, A>, Error> {
126 T::to_vec(s, alloc)
127 }
128
129 pub(crate) trait ConvertVec {
130 fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Result<Vec<Self, A>, Error>
131 where
132 Self: Sized;
133 }
134
135 impl<T> ConvertVec for T
136 where
137 T: TryClone,
138 {
139 default_fn! {
140 #[inline]
141 fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Result<Vec<Self, A>, Error> {
142 struct DropGuard<'a, T, A: Allocator> {
143 vec: &'a mut Vec<T, A>,
144 num_init: usize,
145 }
146
147 impl<T, A: Allocator> Drop for DropGuard<'_, T, A> {
148 #[inline]
149 fn drop(&mut self) {
150 unsafe {
153 self.vec.set_len(self.num_init);
154 }
155 }
156 }
157 let mut vec = Vec::try_with_capacity_in(s.len(), alloc)?;
158 let mut guard = DropGuard {
159 vec: &mut vec,
160 num_init: 0,
161 };
162 let slots = guard.vec.spare_capacity_mut();
163 for (i, b) in s.iter().enumerate().take(slots.len()) {
166 guard.num_init = i;
167 slots[i].write(b.try_clone()?);
168 }
169 core::mem::forget(guard);
170 unsafe {
173 vec.set_len(s.len());
174 }
175 Ok(vec)
176 }
177 }
178 }
179
180 #[cfg(rune_nightly)]
181 impl<T: crate::clone::TryCopy> ConvertVec for T {
182 #[inline]
183 fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Result<Vec<Self, A>, Error> {
184 let mut v = Vec::try_with_capacity_in(s.len(), alloc)?;
185
186 unsafe {
190 s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), s.len());
191 v.set_len(s.len());
192 }
193 Ok(v)
194 }
195 }
196}