1pub mod align;
4pub mod io;
5pub mod iter;
6pub mod path;
7pub mod swizzle;
8pub mod vec;
9
10use std::ops::Range;
11use zerocopy::{FromBytes, Immutable, IntoBytes};
12
13pub fn copy_from_bytes<T>(t: &T) -> T
15where
16 T: IntoBytes + FromBytes + Immutable,
17{
18 FromBytes::read_from_bytes(t.as_bytes()).unwrap()
19}
20
21pub struct StartsOf<'a, T> {
23 pub starts: &'a [u32],
25 pub items: &'a [T],
27}
28
29impl<'a, T> StartsOf<'a, T> {
30 pub fn new(starts: &'a [u32], items: &'a [T]) -> Self {
32 debug_assert!(!starts.is_empty());
33 debug_assert_eq!(starts[0], 0);
34 debug_assert_eq!(*starts.last().unwrap() as usize, items.len());
35 debug_assert!(starts.windows(2).all(|w| w[0] <= w[1]));
36
37 Self { starts, items }
38 }
39}
40
41impl<'a, T> std::ops::Index<usize> for StartsOf<'a, T> {
42 type Output = [T];
43
44 fn index(&self, i: usize) -> &[T] {
45 let start = self.starts[i] as usize;
46 let end = self.starts[i + 1] as usize;
47 &self.items[start..end]
48 }
49}
50
51pub fn is_aligned_4(n: usize) -> bool {
53 (n & 3) == 0
54}
55
56pub fn align_4(n: usize) -> usize {
58 (n + 3) & !3
59}
60
61pub fn iter_similar_ranges<'a, T, F>(items: &'a [T], is_eq: F) -> IterSimilarRanges<'a, T, F> {
63 IterSimilarRanges {
64 items,
65 is_eq,
66 start: 0,
67 }
68}
69
70pub struct IterSimilarRanges<'a, T, F> {
72 items: &'a [T],
73 is_eq: F,
74 start: usize,
75}
76
77impl<'a, T, F> Iterator for IterSimilarRanges<'a, T, F>
78where
79 F: FnMut(&T, &T) -> bool,
80{
81 type Item = Range<usize>;
82
83 fn next(&mut self) -> Option<Self::Item> {
84 if self.items.is_empty() {
85 return None;
86 }
87
88 let first = &self.items[0];
89
90 let mut i = 1;
91 while i < self.items.len() && (self.is_eq)(first, &self.items[i]) {
92 i += 1;
93 }
94
95 let start = self.start;
96 self.start += i;
97 self.items = &self.items[i..];
98
99 Some(start..start + i)
100 }
101}
102
103pub fn iter_similar_slices<'a, T, F>(items: &'a [T], is_eq: F) -> IterSimilarSlices<'a, T, F> {
105 IterSimilarSlices { items, is_eq }
106}
107
108pub struct IterSimilarSlices<'a, T, F> {
110 items: &'a [T],
111 is_eq: F,
112}
113
114impl<'a, T, F> Iterator for IterSimilarSlices<'a, T, F>
115where
116 F: FnMut(&T, &T) -> bool,
117{
118 type Item = &'a [T];
119
120 fn next(&mut self) -> Option<Self::Item> {
121 if self.items.is_empty() {
122 return None;
123 }
124
125 let first = &self.items[0];
126
127 let mut i = 1;
128 while i < self.items.len() && (self.is_eq)(first, &self.items[i]) {
129 i += 1;
130 }
131
132 let (lo, hi) = self.items.split_at(i);
133 self.items = hi;
134 Some(lo)
135 }
136}
137
138pub fn iter_similar_slices_mut<'a, T, F>(
140 items: &'a mut [T],
141 is_eq: F,
142) -> IterSimilarSlicesMut<'a, T, F> {
143 IterSimilarSlicesMut { items, is_eq }
144}
145
146pub struct IterSimilarSlicesMut<'a, T, F> {
148 items: &'a mut [T],
149 is_eq: F,
150}
151
152impl<'a, T, F> Iterator for IterSimilarSlicesMut<'a, T, F>
153where
154 F: FnMut(&T, &T) -> bool,
155{
156 type Item = &'a mut [T];
157
158 fn next(&mut self) -> Option<Self::Item> {
159 if self.items.is_empty() {
160 return None;
161 }
162
163 let items = std::mem::take(&mut self.items);
164 let first = &items[0];
165
166 let mut i = 1;
167 while i < items.len() && (self.is_eq)(first, &items[i]) {
168 i += 1;
169 }
170
171 let (lo, hi) = items.split_at_mut(i);
172 self.items = hi;
173 Some(lo)
174 }
175}