ndarray/
order.rs

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]
34pub enum Order {
35    /// Row major or "C" order
36    RowMajor,
37    /// Column major or "F" order
38    ColumnMajor,
39}
40
41impl 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}