arrayfire/core/dim4.rs
1use std::fmt;
2use std::ops::{Index, IndexMut};
3
4#[cfg(feature = "afserde")]
5use serde::{Deserialize, Serialize};
6
7/// Dim4 is used to store [Array](./struct.Array.html) dimensions
8#[derive(Copy, Clone, PartialEq, Debug)]
9#[cfg_attr(feature = "afserde", derive(Serialize, Deserialize))]
10pub struct Dim4 {
11 dims: [u64; 4],
12}
13
14/// Default trait for Dim4 returns an Array of dimensions [1, 1, 1, 1]
15impl Default for Dim4 {
16 fn default() -> Self {
17 Self { dims: [1, 1, 1, 1] }
18 }
19}
20
21/// Enables index operation for Dim4
22///
23/// # Examples
24///
25/// ```rust
26/// use arrayfire::Dim4;
27///
28/// let dims = Dim4::new(&[4, 4, 2, 1]);
29/// println!("0th Dimension length is {}", dims[0]); // -> 4
30/// println!("1th Dimension length is {}", dims[1]); // -> 4
31/// println!("2th Dimension length is {}", dims[2]); // -> 2
32/// println!("3th Dimension length is {}", dims[3]); // -> 1
33/// ```
34impl Index<usize> for Dim4 {
35 type Output = u64;
36
37 fn index(&self, _index: usize) -> &u64 {
38 &self.dims[_index]
39 }
40}
41
42/// Enables index operation for Dim4 to modify dimensions
43///
44/// # Examples
45///
46/// ```rust
47/// use arrayfire::Dim4;
48///
49/// let mut dims = Dim4::new(&[4, 4, 2, 1]);
50/// dims[2] = 4;
51/// println!("Dimensions: {}", dims); // note that third dimension changed to 4
52/// ```
53impl IndexMut<usize> for Dim4 {
54 fn index_mut(&mut self, _index: usize) -> &mut Self::Output {
55 &mut self.dims[_index]
56 }
57}
58
59/// Enables use of Dim4 objects for printing it to display
60///
61/// # Examples
62///
63/// ```rust
64/// use arrayfire::Dim4;
65///
66/// let dims = Dim4::new(&[4, 4, 2, 1]);
67/// println!("0th Dimension length is {}", dims[0]); // -> 4
68/// ```
69impl fmt::Display for Dim4 {
70 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71 write!(
72 f,
73 "[{} {} {} {}]",
74 self.dims[0], self.dims[1], self.dims[2], self.dims[3]
75 )
76 }
77}
78
79impl Dim4 {
80 /// Create Dim4 object
81 ///
82 /// # Examples
83 ///
84 /// ```rust
85 /// use arrayfire::Dim4;
86 /// let dims = Dim4::new(&[4, 4, 2, 1]);
87 /// ```
88 pub fn new(dims: &[u64; 4]) -> Self {
89 Self {
90 dims: [dims[0], dims[1], dims[2], dims[3]],
91 }
92 }
93
94 /// Get the number of elements represented by Dim4 object
95 pub fn elements(&self) -> u64 {
96 self.dims[0] * self.dims[1] * self.dims[2] * self.dims[3]
97 }
98
99 /// Get the number of dimensions of Dim4
100 pub fn ndims(&self) -> usize {
101 let nelems = self.elements();
102 match nelems {
103 0 => 0,
104 1 => 1,
105 _ => {
106 if self.dims[3] != 1 {
107 4
108 } else if self.dims[2] != 1 {
109 3
110 } else if self.dims[1] != 1 {
111 2
112 } else {
113 1
114 }
115 }
116 }
117 }
118
119 /// Get the dimensions as a slice of 4 values
120 pub fn get(&self) -> &[u64; 4] {
121 &self.dims
122 }
123}
124
125#[cfg(test)]
126mod tests {
127 #[cfg(feature = "afserde")]
128 mod serde_tests {
129 use super::super::Dim4;
130 use crate::dim4;
131
132 #[test]
133 fn dim4_serde() {
134 let dims = dim4!(4, 4);
135 let serd = match serde_json::to_string(&dims) {
136 Ok(serialized_str) => serialized_str,
137 Err(e) => e.to_string(),
138 };
139 assert_eq!(serd, "{\"dims\":[4,4,1,1]}");
140
141 let deserd: Dim4 = serde_json::from_str(&serd).unwrap();
142 assert_eq!(deserd, dims);
143 }
144 }
145}