Skip to content

Instantly share code, notes, and snippets.

@qryxip
Last active March 9, 2021 01:40
Show Gist options
  • Save qryxip/9649210c2322dbdc4a3a937326fe6290 to your computer and use it in GitHub Desktop.
Save qryxip/9649210c2322dbdc4a3a937326fe6290 to your computer and use it in GitHub Desktop.
use std::{
cell::Cell,
num::Wrapping,
ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Sub},
};
fn main() {
// 1D
let mut arr = vec![Wrapping(1); 2];
let cells = d1(&mut arr);
cells[0].add_assign(cells[1].get());
assert_eq!(Wrapping(2), arr[0]);
// 2D
let mut arr = vec![vec![Wrapping(1); 2]; 2];
let cells = d2(&mut arr);
cells[0][0].add_assign(cells[1][1].get());
assert_eq!(Wrapping(2), arr[0][0]);
// 3D
let mut arr = vec![vec![vec![Wrapping(1); 2]; 2]; 2];
let cells = d3(&mut arr);
cells[0][0][0].add_assign(cells[1][1][1].get());
assert_eq!(Wrapping(2), arr[0][0][0]);
// 4D
let mut arr = vec![vec![vec![vec![Wrapping(1); 2]; 2]; 2]; 2];
let cells = d4(&mut arr);
cells[0][0][0][0].add_assign(cells[1][1][1][1].get());
assert_eq!(Wrapping(2), arr[0][0][0][0]);
// 5D
let mut arr = vec![vec![vec![vec![vec![Wrapping(1); 2]; 2]; 2]; 2]; 2];
let cells = d5(&mut arr);
cells[0][0][0][0][0].add_assign(cells[1][1][1][1][1].get());
assert_eq!(Wrapping(2), arr[0][0][0][0][0]);
}
pub fn d1<T: Copy>(array: &mut [T]) -> &[Cell<T>] {
Cell::from_mut(array).as_slice_of_cells()
}
pub fn d2<R: AsMut<[T]>, T: Copy>(array: &mut [R]) -> Vec<&[Cell<T>]> {
array.iter_mut().map(|r| d1(r.as_mut())).collect()
}
pub fn d3<'a, R1: AsMut<[R2]>, R2: 'a + AsMut<[T]>, T: Copy>(
array: &'a mut [R1],
) -> Vec<Vec<&'a [Cell<T>]>> {
array.iter_mut().map(|r| d2(r.as_mut())).collect()
}
pub fn d4<'a, R1: AsMut<[R2]>, R2: 'a + AsMut<[R3]>, R3: 'a + AsMut<[T]>, T: Copy>(
array: &'a mut [R1],
) -> Vec<Vec<Vec<&'a [Cell<T>]>>> {
array.iter_mut().map(|r| d3(r.as_mut())).collect()
}
#[allow(clippy::type_complexity)]
pub fn d5<
'a,
R1: AsMut<[R2]>,
R2: 'a + AsMut<[R3]>,
R3: 'a + AsMut<[R4]>,
R4: 'a + AsMut<[T]>,
T: Copy,
>(
array: &'a mut [R1],
) -> Vec<Vec<Vec<Vec<&'a [Cell<T>]>>>> {
array.iter_mut().map(|r| d4(r.as_mut())).collect()
}
macro_rules! cell_ext(($($method:ident, $trait:ident, { $op:tt };)*) => {
pub trait CellExt {
type Item;
$(
fn $method<R>(&self, rhs: R)
where
Self::Item: $trait<R, Output = Self::Item>;
)*
}
impl<L: Copy> CellExt for Cell<L> {
type Item = L;
$(
fn $method<R>(&self, rhs: R)
where
L: $trait<R, Output = L>
{
self.set(self.get() $op rhs);
}
)*
}
});
cell_ext! {
add_assign, Add, { + };
sub_assign, Sub, { - };
mul_assign, Mul, { * };
div_assign, Div, { / };
rem_assign, Rem, { % };
bitor_assign, BitOr, { | };
bitand_assign, BitAnd, { & };
bitxor_assign, BitXor, { ^ };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment