Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #main.rs
- use core::{ptr::NonNull, ops::{Deref, DerefMut}, marker::PhantomData, mem::transmute, mem::size_of};
- use core::mem::swap;
- use generativity::*;
- pub mod weak_ref;
- pub use weak_ref::weak;
- pub trait Promote<'a, T> {
- type Output<'b> where Self : 'b;
- fn promote(&self, wk : weak<'a, T>) -> &Self::Output<'a>;
- unsafe fn bind<'b>(&self, wk : weak<'b, T>) -> weak<'a, T> {
- weak::from_nonnull(wk.into())
- }
- }
- trait PromoteMut<'a, T> : Promote<'a, T> {
- fn promote_mut(&mut self, wk : weak<'a, T>) -> &mut Self::Output<'a>;
- fn promote_many_mut<const SIZE : usize>(&'_ mut self, ids : [weak<'a, T>; SIZE]) -> Option<[&'_ mut Self::Output<'a>; SIZE]> {
- for i in 0..SIZE - 1 {
- for j in i + 1..SIZE {
- if ids[i] == ids[j] {
- return None;
- }
- }
- }
- let res = core::array::from_fn(|i| unsafe {
- transmute(self.promote_mut(ids[i]))
- });
- Some(res)
- }
- }
- trait IntoAnchor<'a> : Sized {
- type Anchor;
- fn into_anchor(self, g : Guard<'a>) -> Self::Anchor;
- }
- #[derive(Clone, Copy)]
- struct WeakIter<'a, T> {
- _id : PhantomData<Id<'a>>,
- current : NonNull<T>,
- end : *const T
- }
- impl <'a, T> Iterator for WeakIter<'a, T> {
- type Item = weak<'a, T>;
- fn next(&mut self) -> Option<Self::Item> {
- if self.current.as_ptr() as *const _ == self.end {
- None
- } else {
- if size_of::<T>() == 0 {
- let res = unsafe {
- weak::from_nonnull(NonNull::dangling())
- };
- unsafe {
- self.current = NonNull::new_unchecked((self.current.as_ptr() as *mut u8).add(1) as * mut _)
- }
- Some(res)
- } else {
- let res = unsafe {
- weak::from_nonnull(self.current)
- };
- unsafe {
- self.current = NonNull::new_unchecked(self.current.as_ptr().add(1));
- }
- Some(res)
- }
- }
- }
- }
- impl <'a, T> WeakIter<'a, T> {
- pub fn new<'b>(src : &Anchored<'a, [T]>) -> Self {
- unsafe {
- if size_of::<T>() == 0 {
- let current = NonNull::new_unchecked(src.as_ptr() as *mut _);
- let end = (src.as_ptr() as *const u8).add(src.len()) as *const _;
- WeakIter { _id: PhantomData, current, end }
- } else {
- let current = NonNull::new_unchecked(src.as_ptr() as *mut _);
- let end = src.as_ptr().add(src.len());
- WeakIter { _id: PhantomData, current, end }
- }
- }
- }
- }
- #[repr(transparent)]
- #[derive(Debug)]
- struct Anchored<'a, T : ?Sized> {
- _id : PhantomData<Id<'a>>,
- content : T
- }
- impl <'a, T : ?Sized> Anchored<'a, T> {
- pub unsafe fn inner(&self) -> &T {
- &self.content
- }
- pub unsafe fn inner_mut(&mut self) -> &mut T {
- &mut self.content
- }
- }
- impl <'a, T> Deref for Anchored<'a, [T]> {
- type Target = [T];
- fn deref(&self) -> &Self::Target {
- &self.content
- }
- }
- impl <'a, T> DerefMut for Anchored<'a, [T]> {
- fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.content
- }
- }
- impl <'a, V, T : TriviallyAnchored + ?Sized + 'a> Promote<'a, V> for Anchored<'a, T> {
- type Output<'b> = V where Self : 'b;
- fn promote(&self, wk : weak<'a, V>) -> &Self::Output<'a> {
- unsafe {
- let ptr : NonNull<_> = wk.into();
- ptr.as_ref()
- }
- }
- }
- impl <'a, V, T : TriviallyAnchored + ?Sized + 'a> PromoteMut<'a, V> for Anchored<'a, T> {
- fn promote_mut(&mut self, wk : weak<'a, V>) -> &mut Self::Output<'a> {
- unsafe {
- let mut ptr : NonNull<_> = wk.into();
- ptr.as_mut()
- }
- }
- }
- impl <'a, T> Anchored<'a, [T]> {
- pub fn get_weak(&self, index : usize) -> Option<weak<'a, T>> {
- unsafe {
- self.content.get(index).map(|a| {
- weak::from_nonnull(NonNull::new_unchecked(a as *const _ as *mut _))
- })
- }
- }
- pub fn iter_weak(&self) -> WeakIter<'a, T> {
- WeakIter::new(self)
- }
- }
- impl <'a, const SIZE: usize, T> Anchored<'a, [T;SIZE]> {
- pub fn get_weak(&self, index : usize) -> Option<weak<'a, T>> {
- unsafe {
- self.content.get(index).map(|a| {
- weak::from_nonnull(NonNull::new_unchecked(a as *const _ as *mut _))
- })
- }
- }
- pub fn iter_weak(&self) -> WeakIter<'a, T> {
- WeakIter::new(self)
- }
- }
- impl <'a, T, Array : Deref<Target = [T]>> Deref for Anchored<'a, Array> {
- type Target = Anchored<'a, [T]>;
- fn deref(&self) -> &Self::Target {
- unsafe {
- transmute(self.inner().deref())
- }
- }
- }
- impl <'a, T, Array : DerefMut<Target = [T]>> DerefMut for Anchored<'a, Array> {
- fn deref_mut(&mut self) -> &mut Self::Target {
- unsafe {
- transmute(self.inner_mut().deref_mut())
- }
- }
- }
- pub trait TriviallyAnchored {}
- impl <'this, 'a : 'this, T : TriviallyAnchored> IntoAnchor<'a> for &'this T {
- type Anchor = &'this Anchored<'a, T>;
- fn into_anchor(self, _ : Guard<'a>) -> Self::Anchor {
- unsafe {
- transmute(self)
- }
- }
- }
- impl <'this, 'a : 'this, T : TriviallyAnchored> IntoAnchor<'a> for &'this mut T {
- type Anchor = &'this mut Anchored<'a, T>;
- fn into_anchor(self, _ : Guard<'a>) -> Self::Anchor {
- unsafe {
- transmute(self)
- }
- }
- }
- impl <T> TriviallyAnchored for Vec<T> {}
- impl <T> TriviallyAnchored for [T] {}
- impl <const SIZE: usize, T> TriviallyAnchored for [T; SIZE] {}
- fn shuffle<const SIZE : usize>(data : &mut Anchored<'_, [i32; SIZE]>, random : &mut impl FnMut() -> usize) {
- for (id, i) in data.iter_weak().enumerate() {
- let j = id + random() % (SIZE - id);
- assert!(j < SIZE);
- let j = data.get_weak(j).unwrap();
- if let Some([a, b]) = data.promote_many_mut([i, j]) {
- swap(a, b);
- }
- }
- }
- macro_rules! anchor {
- ($name:ident, $src:expr) => {
- make_guard!(guard);
- let $name = IntoAnchor::into_anchor($src, guard);
- };
- }
- macro_rules! anchor_mut {
- ($name:ident, $src:expr) => {
- make_guard!(guard);
- let mut $name = IntoAnchor::into_anchor($src, guard);
- };
- }
- fn main() {
- let mut v0 = vec![1, 2, 3, 4];
- anchor!(v, &mut v0);
- let a = v.get_weak(0).unwrap();
- let b = v.get_weak(1).unwrap();
- let c = v.get_weak(3).unwrap();
- let p = v.promote(a);
- dbg!(p);
- dbg!(v.promote(b));
- dbg!(v.promote(c));
- let p = v.promote_mut(c);
- *p += 3;
- dbg!(v.promote(c));
- let p = v.promote_mut(c);
- dbg!(v.promote(c));
- let mut random_data = [542, 3423, 45, 56, 864, 865, 75, 23, 84, 112444].into_iter();
- //chosen by quantum oscillations inside the synapses of my brain.
- //guaranteed to be random.
- let mut v0 = [1, 2, 3, 4];
- anchor!(v, &mut v0);
- let mut random = || random_data.next().unwrap_or(0);
- shuffle(v, &mut random);
- dbg!(&v);
- shuffle(v, &mut random);
- dbg!(&v0);
- }
- # weak_ref.rs
- use core::marker::PhantomData;
- use core::ptr::NonNull;
- use core::hash::Hash;
- use core::hash::Hasher;
- use generativity::Id;
- #[allow(non_camel_case_types)]
- #[repr(transparent)]
- #[derive(Debug)]
- pub struct weak<'a, T> {
- _id: PhantomData<Id<'a>>,
- ptr: NonNull<T>
- }
- impl <'a, T> PartialEq for weak<'a, T> {
- fn eq(&self, other: &Self) -> bool {
- self.ptr == other.ptr
- }
- }
- impl <'a, T> Eq for weak<'a, T> {}
- impl <'a, T> Clone for weak<'a, T> {
- fn clone(&self) -> Self {
- weak { _id: self._id, ptr: self.ptr }
- }
- }
- impl <'a, T> Hash for weak<'a, T> {
- fn hash<H: Hasher>(&self, state: &mut H) {
- self.ptr.hash(state);
- }
- }
- impl <'a, T> Copy for weak<'a, T> {}
- impl <'a, T> weak<'a, T> {
- pub fn unbind(self) -> weak<'static, T> {
- unsafe {
- weak::from_nonnull(self.into())
- }
- }
- pub unsafe fn from_nonnull(ptr : NonNull<T>) -> Self {
- weak {
- ptr,
- _id : PhantomData
- }
- }
- }
- impl <'a, T> Into<NonNull<T>> for weak<'a, T> {
- fn into(self) -> NonNull<T> {
- self.ptr
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement