Pre-RFC: Returning Proxies from Index/IndexMut

I still think Custom DST is the proper backward-compatible solution here rather than GATs, due to the problems pointed out by @CAD97. You place the view information into the metadata part of the DST.

Referring to the linked thread, we can define the output type as this collapsed block.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct ColumnMeta {
   stride: usize,
   len: usize,
}

// "treat `&Column<T>` like `(*const T, ColumnMeta)` ≈ `(*const T, usize, usize)`"
pub dyn type Column<T>(regular: ColumnMeta) = [T];

impl<T> dst::Regular for Column<T> {
    fn reduce_with_metadata(meta: ColumnMeta) -> usize {
        meta.len
    }
}

impl<T> Index<usize> for LazyTransposedMatrix<T> {
    type Output = Column<T>;
    fn index(&self, col_index: usize) -> &Self::Output {
        assert!(col_index < self.width);
        // urgh.
        unsafe {
            &*<*const Row<T>>::from_raw_parts(
                self.base.as_ptr().add(col_index),
                ColumnMeta {
                    stride: self.width,
                    len: self.width * (self.height - 1) + 1,
                },
            )
        }
    }
}

impl<T> Index<usize> for Column<T> {
    type Output = T;
    fn index(&self, row_index: usize) -> &Self::Output {
        let meta = ptr::metadata(self);
        let slice = dst::reduce(self);
        &slice[row_index * meta.stride]
    }
}
1 Like