Skip to content

Instantly share code, notes, and snippets.

@DutchGhost
Last active February 17, 2023 12:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DutchGhost/fcee4e9074860eac5d3c5538aae96c6d to your computer and use it in GitHub Desktop.
Save DutchGhost/fcee4e9074860eac5d3c5538aae96c6d to your computer and use it in GitHub Desktop.
const vec
#![feature(const_ptr_is_null)]
#![feature(const_ptr_write)]
#![feature(const_mut_refs)]
#![feature(core_intrinsics)]
#![feature(inline_const)]
#![feature(const_heap)]
use core::intrinsics::{const_allocate, const_deallocate};
struct CVec<T> {
ptr: *mut T,
len: usize,
cap: usize,
}
impl<T> CVec<T> {
const fn new() -> Self {
Self {
ptr: core::ptr::null_mut(),
len: 0,
cap: 0,
}
}
const fn push(&mut self, elem: T) {
if self.needs_grow() {
self.grow()
}
unsafe {
let offset = self.ptr.offset(self.len as isize);
core::ptr::write(offset, elem);
self.len += 1;
}
}
const fn as_slice(self) -> &'static [T] {
unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
}
const fn needs_grow(&self) -> bool {
self.len == self.cap
}
const fn grow(&mut self) {
unsafe {
let new_cap = if self.cap == 0 { 4 } else { self.cap * 2 };
self.cap = new_cap;
let ptr = const_allocate(
core::mem::size_of::<T>() * self.cap,
core::mem::align_of::<T>(),
);
if ptr.is_null() {
panic!("OH NO")
}
let ptr = ptr.cast();
if self.len != 0 {
core::ptr::copy(self.ptr, ptr, self.len);
}
if !self.ptr.is_null() {
const_deallocate(
self.ptr.cast(),
core::mem::size_of::<T>() * self.len,
core::mem::align_of::<T>(),
);
}
self.ptr = ptr;
}
}
}
const X: &[i32] = {
let mut v = CVec::<i32>::new();
v.push(20);
v.push(30);
v.push(40);
v.push(50);
v.push(60);
v.as_slice()
};
fn main() {
dbg!(X);
}
#![feature(nonnull_slice_from_raw_parts)]
#![feature(ptr_as_uninit)]
#![feature(core_intrinsics)]
#![feature(const_slice_from_raw_parts_mut)]
#![feature(const_mut_refs)]
use core::{
mem::MaybeUninit,
ptr::NonNull,
slice,
intrinsics::{const_allocate, const_deallocate}
};
struct CVec<T> {
vec: NonNull<[MaybeUninit<T>]>,
idx: usize,
}
impl <T> CVec<T> {
pub const fn new() -> Self {
Self {
vec: NonNull::<[MaybeUninit<T>; 0]>::dangling(),
idx: 0
}
}
pub const fn len(&self) -> usize {
self.idx
}
pub const fn capacity(&self) -> usize {
self.vec.len()
}
pub const fn push(&mut self, elem: T) {
if self.needs_grow() {
self.grow()
}
let mut slice = self.as_uninit_slice_mut();
let place = self.idx;
slice[place] = MaybeUninit::new(elem);
}
}
impl <T> CVec<T> {
const fn needs_grow(&self) -> bool {
self.idx == self.vec.len()
}
const fn as_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] {
unsafe { slice::from_raw_parts_mut(self.vec.cast().as_ptr(), self.vec.len()) }
}
const unsafe fn grow(&mut self) {
let new_cap = match self.capacity() {
0 => 4,
n => n * 2
};
let ptr = const_allocate(
core::mem::size_of::<T>() * self.cap,
core::mem::align_of::<T>(),
);
if ptr.is_null() {
panic!("Not in const environment!");
}
let ptr = ptr.cast();
let ptr = NonNull::new_unchecked(ptr);
let slice = NonNull::slice_from_raw_parts(ptr, new_cap);
let new_slice = slice.as_uninit_slice_mut();
let old_slice = self.vec.as_uninit_slice_mut();
// memcpy
}
}
#![feature(const_for)]
#![feature(slice_ptr_get)]
#![feature(const_trait_impl)]
#![feature(const_ptr_as_ref)]
#![feature(const_nonnull_slice_from_raw_parts)]
#![feature(const_ptr_is_null)]
#![feature(const_heap)]
#![feature(nonnull_slice_from_raw_parts)]
#![feature(ptr_as_uninit)]
#![feature(core_intrinsics)]
#![feature(const_slice_from_raw_parts_mut)]
#![feature(const_mut_refs)]
use core::{
intrinsics::{const_allocate, const_deallocate},
mem::MaybeUninit,
ops::{Deref, DerefMut},
ptr::NonNull,
slice,
};
struct CVec<T> {
vec: NonNull<[MaybeUninit<T>]>,
idx: usize,
}
impl<T> CVec<T> {
pub const fn new() -> Self {
Self {
vec: NonNull::<[MaybeUninit<T>; 0]>::dangling(),
idx: 0,
}
}
pub const fn len(&self) -> usize {
self.idx
}
pub const fn capacity(&self) -> usize {
self.vec.len()
}
pub const fn push(&mut self, elem: T) {
if self.needs_grow() {
unsafe { self.grow() }
}
let place = self.idx;
let slice = self.as_uninit_slice_mut();
slice[place] = MaybeUninit::new(elem);
self.idx += 1;
}
pub const fn into_slice(self) -> &'static [T] {
unsafe {
let ptr = self.vec.as_ptr().cast::<T>();
core::slice::from_raw_parts(ptr, self.len())
}
}
}
impl<T> const Deref for CVec<T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
self.as_slice_ref()
}
}
impl<T> const DerefMut for CVec<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_slice_ref_mut()
}
}
impl<T> CVec<T> {
const fn needs_grow(&self) -> bool {
self.idx == self.vec.len()
}
const fn as_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] {
unsafe { slice::from_raw_parts_mut(self.vec.cast().as_ptr(), self.vec.len()) }
}
const fn as_slice_ref(&self) -> &[T] {
unsafe {
let ptr = self.vec.as_ptr().cast::<T>();
core::slice::from_raw_parts(ptr, self.len())
}
}
const fn as_slice_ref_mut(&mut self) -> &mut [T] {
unsafe {
let ptr = self.vec.as_mut_ptr().cast::<T>();
core::slice::from_raw_parts_mut(ptr, self.len())
}
}
const unsafe fn grow(&mut self) {
let new_cap = match self.capacity() {
0 => 4,
n => n * 2,
};
let ptr = const_allocate(
core::mem::size_of::<T>() * new_cap,
core::mem::align_of::<T>(),
);
if ptr.is_null() {
panic!("Not in const environment!");
}
let ptr = ptr.cast();
let ptr = NonNull::new_unchecked(ptr);
let slice = NonNull::slice_from_raw_parts(ptr, new_cap);
let new_slice = slice.as_uninit_slice_mut();
let old_slice = self.vec.as_uninit_slice_mut();
let new_ptr = new_slice.as_mut_ptr();
let old_ptr = old_slice.as_mut_ptr();
core::ptr::copy(old_ptr, new_ptr, self.idx);
self.vec = slice;
// if self.len() is 0 there were no elements pushed,
// nothing to deallocate!!
if !old_ptr.is_null() && self.len() != 0 {
const_deallocate(
old_ptr.cast(),
core::mem::size_of::<T>() * self.len(),
core::mem::align_of::<T>(),
);
}
}
}
const X: &[i32] = {
let mut cv = CVec::new();
cv.push(10);
cv.push(30);
cv.push(40);
cv.push(50);
cv.push(60);
cv.into_slice()
};
fn main() {
dbg!(X);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment