|
| 1 | + |
| 2 | +/// Array order |
| 3 | +/// |
| 4 | +/// Order refers to indexing order, or how a linear sequence is translated |
| 5 | +/// into a two-dimensional or multi-dimensional array. |
| 6 | +/// |
| 7 | +/// - `RowMajor` means that the index along the row is the most rapidly changing |
| 8 | +/// - `ColumnMajor` means that the index along the column is the most rapidly changing |
| 9 | +/// |
| 10 | +/// Given a sequence like: 1, 2, 3, 4, 5, 6 |
| 11 | +/// |
| 12 | +/// If it is laid it out in a 2 x 3 matrix using row major ordering, it results in: |
| 13 | +/// |
| 14 | +/// ```text |
| 15 | +/// 1 2 3 |
| 16 | +/// 4 5 6 |
| 17 | +/// ``` |
| 18 | +/// |
| 19 | +/// If it is laid using column major ordering, it results in: |
| 20 | +/// |
| 21 | +/// ```text |
| 22 | +/// 1 3 5 |
| 23 | +/// 2 4 6 |
| 24 | +/// ``` |
| 25 | +/// |
| 26 | +/// It can be seen as filling in "rows first" or "columns first". |
| 27 | +/// |
| 28 | +/// `Order` can be used both to refer to logical ordering as well as memory ordering or memory |
| 29 | +/// layout. The orderings have common short names, also seen in other environments, where |
| 30 | +/// row major is called "C" order (after the C programming language) and column major is called "F" |
| 31 | +/// or "Fortran" order. |
| 32 | +#[derive(Copy, Clone, Debug, PartialEq, Eq)] |
| 33 | +#[non_exhaustive] |
| 34 | +pub enum Order { |
| 35 | + /// Row major or "C" order |
| 36 | + RowMajor, |
| 37 | + /// Column major or "F" order |
| 38 | + ColumnMajor, |
| 39 | +} |
| 40 | + |
| 41 | +impl Order { |
| 42 | + /// "C" is an alias for row major ordering |
| 43 | + pub const C: Order = Order::RowMajor; |
| 44 | + |
| 45 | + /// "F" (for Fortran) is an alias for column major ordering |
| 46 | + pub const F: Order = Order::ColumnMajor; |
| 47 | + |
| 48 | + /// Return true if input is Order::RowMajor, false otherwise |
| 49 | + #[inline] |
| 50 | + pub fn is_row_major(self) -> bool { |
| 51 | + match self { |
| 52 | + Order::RowMajor => true, |
| 53 | + Order::ColumnMajor => false, |
| 54 | + } |
| 55 | + } |
| 56 | + |
| 57 | + /// Return true if input is Order::ColumnMajor, false otherwise |
| 58 | + #[inline] |
| 59 | + pub fn is_column_major(self) -> bool { |
| 60 | + !self.is_row_major() |
| 61 | + } |
| 62 | + |
| 63 | + /// Return Order::RowMajor if the input is true, Order::ColumnMajor otherwise |
| 64 | + #[inline] |
| 65 | + pub fn row_major(row_major: bool) -> Order { |
| 66 | + if row_major { Order::RowMajor } else { Order::ColumnMajor } |
| 67 | + } |
| 68 | + |
| 69 | + /// Return Order::ColumnMajor if the input is true, Order::RowMajor otherwise |
| 70 | + #[inline] |
| 71 | + pub fn column_major(column_major: bool) -> Order { |
| 72 | + Self::row_major(!column_major) |
| 73 | + } |
| 74 | + |
| 75 | + /// Return the transpose: row major becomes column major and vice versa. |
| 76 | + #[inline] |
| 77 | + pub fn transpose(self) -> Order { |
| 78 | + match self { |
| 79 | + Order::RowMajor => Order::ColumnMajor, |
| 80 | + Order::ColumnMajor => Order::RowMajor, |
| 81 | + } |
| 82 | + } |
| 83 | +} |
0 commit comments