rune_alloc/vec/
spec_from_elem.rs

1#[cfg(rune_nightly)]
2use core::ptr;
3
4use crate::alloc::Allocator;
5use crate::clone::TryClone;
6use crate::error::Error;
7#[cfg(rune_nightly)]
8use crate::raw_vec::RawVec;
9
10#[cfg(rune_nightly)]
11use super::IsZero;
12use super::Vec;
13
14// Specialization trait used for Vec::from_elem
15pub(super) trait SpecFromElem: Sized {
16    fn from_elem<A: Allocator>(elem: Self, n: usize, alloc: A) -> Result<Vec<Self, A>, Error>;
17}
18
19impl<T> SpecFromElem for T
20where
21    T: TryClone,
22{
23    default_fn! {
24        fn from_elem<A: Allocator>(elem: Self, n: usize, alloc: A) -> Result<Vec<Self, A>, Error> {
25            let mut v = Vec::try_with_capacity_in(n, alloc)?;
26            v.try_extend_with(n, elem)?;
27            Ok(v)
28        }
29    }
30}
31
32#[cfg(rune_nightly)]
33impl<T> SpecFromElem for T
34where
35    T: TryClone + IsZero,
36{
37    #[inline]
38    default fn from_elem<A: Allocator>(elem: T, n: usize, alloc: A) -> Result<Vec<T, A>, Error> {
39        if elem.is_zero() {
40            return Ok(Vec {
41                buf: RawVec::try_with_capacity_zeroed_in(n, alloc)?,
42                len: n,
43            });
44        }
45
46        let mut v = Vec::try_with_capacity_in(n, alloc)?;
47        v.try_extend_with(n, elem)?;
48        Ok(v)
49    }
50}
51
52#[cfg(rune_nightly)]
53impl SpecFromElem for i8 {
54    #[inline]
55    fn from_elem<A: Allocator>(elem: i8, n: usize, alloc: A) -> Result<Vec<i8, A>, Error> {
56        if elem == 0 {
57            return Ok(Vec {
58                buf: RawVec::try_with_capacity_zeroed_in(n, alloc)?,
59                len: n,
60            });
61        }
62
63        unsafe {
64            let mut v = Vec::try_with_capacity_in(n, alloc)?;
65            ptr::write_bytes(v.as_mut_ptr(), elem as u8, n);
66            v.set_len(n);
67            Ok(v)
68        }
69    }
70}
71
72#[cfg(rune_nightly)]
73impl SpecFromElem for u8 {
74    #[inline]
75    fn from_elem<A: Allocator>(elem: u8, n: usize, alloc: A) -> Result<Vec<u8, A>, Error> {
76        if elem == 0 {
77            return Ok(Vec {
78                buf: RawVec::try_with_capacity_zeroed_in(n, alloc)?,
79                len: n,
80            });
81        }
82
83        unsafe {
84            let mut v = Vec::try_with_capacity_in(n, alloc)?;
85            ptr::write_bytes(v.as_mut_ptr(), elem, n);
86            v.set_len(n);
87            Ok(v)
88        }
89    }
90}