Coder Social home page Coder Social logo

grid's People

Contributors

becheran avatar burntnail avatar chyyran avatar djkato avatar eievui5 avatar einliterflasche avatar henryiii avatar hwjsnc avatar isaaccloos avatar izaakc avatar j-f-liu avatar jmole avatar luca3s avatar mducharm avatar mirsella avatar nickcondron avatar nicoburns avatar pcbowers avatar peterwilli avatar shir0kamii avatar thinred avatar vlad2001mfs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

grid's Issues

Implement Hash for Grid

I want to use a (cloned) Grid as a key in a hashmap. This is currently not possible, because Hash isn't implemented for Grid<T>. I think this should be quite straightforward to add, a simple #[derive(Hash)] might already work.

Allow swapping two elements

A method like swap((row_a, col_a), (row_b, col_b)) would be very useful, since only the underlying vector has ownership of the values and can move them around.

Initialization without Default trait requirements

I cant initialize grid with defined size because struct i use not impl Default
I dont understand bound to Default trait because its possible to create vec and even Vec<Vec> with Vec::with_capacity() function

`Grid::insert_{row, col}()` can create invalid states after panicking

The Grid type has the effective safety invariants that rows.checked_mul(cols) == Some(data.len()) and that rows == 0 if and only if cols == 0. In some panicking paths, Grid::insert_row() can violate these invariants:

  • grid.insert_row(i, row) in release mode, where row.len() == grid.cols and grid.rows == usize::MAX. This sets grid.rows to 0, making the other methods' results inconsistent with one another. This is only possible when size_of::<T>() == 0, and I'm not sure if it can cause any UB by itself.
  • grid.insert_row(i, row), where i <= grid.rows, row.len() == grid.cols, grid.rows < usize::MAX, and grid.rows * grid.cols > usize::MAX - grid.cols: This increments grid.rows without pushing the new row, allowing invalid get_unchecked() calls. Since this is only possible when size_of::<T>() == 0, it causes library UB but not language UB with the current standard library.
  • grid.insert_row(i, row), where i <= grid.rows, row.len() == grid.cols, size_of::<T>() > 0, and (grid.rows + 1) * grid.cols * size_of::<T>() > isize::MAX as usize. This increments grid.rows without pushing the new row, which can cause UB on 32-bit targets:
    /*
    [dependencies]
    grid = "=0.8.1"
    
    cargo run --target i686-unknown-linux-gnu
    */
    
    use grid::Grid;
    use std::panic::{self, AssertUnwindSafe};
    
    fn main() {
        let catch = |f| panic::catch_unwind(AssertUnwindSafe(f)).unwrap_err();
        // 1076 * 1994889 == isize::MAX as usize - 983083
        // 1077 * 1994889 == isize::MAX as usize + 1011806
        let mut grid = Grid::init(1076, 1994889, 0u8);
        catch(|| grid.insert_row(1076, vec![0; 1994889]));
        println!("{}", grid.get(1076, 1994888).unwrap()); // segfault
    }

Support Hash

I think it would be nice to support Hash if the elements support Hash. I was trying to use cached, and couldn't cache on Grid<T> even if T was Hashable. I can try to make a PR.

Clone on GridRowIter/GridColIter ?

Hello !

Would it be possible to implement Clone on theses iterators ? The underlying SkipBy iterator implement it, I'm new to rust but from what I've seen it should be possible ?

The use case is having an iterator at a certain point and cloning it to get two iterator starting at the same place:

let rows = grid.iter_rows().skip(1);
let r1 = rows.clone().take(10);
let r2 = rows.skip(10);

Here we need the clone because take consume the iterator AFAIK.

Thanks !

Overflow in size calculations can allow access to invalid memory

This program produces a segmentation fault:

/*
[dependencies]
grid = "=0.8.0"

cargo run --release
*/

use grid::Grid;

fn main() {
    let grid: Grid<i32> = Grid::new(2, usize::MAX / 2 + 1);
    println!("{}", grid.get(0, 0).unwrap());
}

The documentation on Grid::new() states that it will panic if rows * cols > usize::MAX. However, it currently only panics in debug mode; in release mode, rows * cols will silently overflow without panicking. In this example, rows * cols == 0 due to overflow, so Grid::new() creates a Vec of 0 elements, and we attempt to read from element 0. Since this is an invalid pointer (an empty Vec doesn't point to a real allocation), this results in a segmentation fault.

This issue can be fixed by replacing rows * cols with rows.checked_mul(cols).expect("...") in Grid::new() and Grid::init().

Grid::new(usize, usize) panics undocumented

This doesn't work

use grid::Grid;
fn main() {
    let grid : Grid<u8> = Grid::new(usize::MAX, usize::MAX);
}

while this does

use grid::Grid;
  2 fn main() {
  3     let grid : Grid<u8> = Grid::new(u8::MAX, u8::MAX);
  4 }

Not really sure how the type annotations would look like, but you should probably update the documentation to say that grid lengths can only be sqrt(usize::MAX)

Use RawVec instead of Vec

It should be possible to use the rust RawVec struct instead of Vec. This will save the not needed Len usize member variable

how to read a complete Row ?

Hi,
still learning Rust, so maybe not really a Grid question but how can I read an entire Row and not cell by cell ?
so not grid[x][y], but a way to have grid.get_row(x)
thanks

[Edit:] did what I needed differently by using pop_row().

Support zero-sized grids

A great feature of Vec is that you can create a zero-length Vec with Vec::new(), and this does not allocate. This is great if you if you want to initialise a struct containing a Vec, but you don't yet know what the dimensions of the Vec should be. You can initialise the struct with the placeholder for very low cost.

It would be great if grid supported the same. I think it could make sense to only support both dimensions being zero, or both being non-zero. One being zero while the other is non-zero doesn't make much sense.

Add ability to get slice of row.

I would like to be able to get an entire row as a slice. Since the internal vector saves the rows continuously (at least for one of the allocation options, right?), it would be useful to be able to get such a slice, instead of an iterator with .iter_rows. In my use-case, this iterator wouldn't work, because I need to .rev() the rows, and that only works with a slice as far as I'm aware.

requesing feature: `iter_rows()`, and `iter_cols()`

I'd like to be able to do the following:

grid.iter_rows(|row| row.iter_row().sum()).collect::<Vec<_>>()

same for cols. This could be a great feature when trying to apply functions row or column wise.

I'm new to Rust, but if you have the patience I'd be interested in creating a pr myself.

:)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.