rust_3d/
dynamic_precision_index_vec.rs1use crate::{IsIndexContainer, IsIndexContainerIterator};
26
27use std::{u16, u32, u8, usize};
28
29#[derive(Clone, Default)]
32pub struct DynamicPrecisionIndexVec {
34 mode: Mode,
35}
36
37impl DynamicPrecisionIndexVec {
39 pub fn new() -> Self {
41 Self {
42 mode: Mode::U8(Vec::new()),
43 }
44 }
45 pub fn get_u8(&self) -> Option<&Vec<u8>> {
47 match self.mode {
48 Mode::U8(ref vec) => Some(vec),
49 _ => None,
50 }
51 }
52 pub fn get_u8_mut(&mut self) -> Option<&mut Vec<u8>> {
54 match self.mode {
55 Mode::U8(ref mut vec) => Some(vec),
56 _ => None,
57 }
58 }
59 pub fn get_u16(&self) -> Option<&Vec<u16>> {
61 match self.mode {
62 Mode::U16(ref vec) => Some(vec),
63 _ => None,
64 }
65 }
66 pub fn get_u16_mut(&mut self) -> Option<&mut Vec<u16>> {
68 match self.mode {
69 Mode::U16(ref mut vec) => Some(vec),
70 _ => None,
71 }
72 }
73 pub fn get_u32(&self) -> Option<&Vec<u32>> {
75 match self.mode {
76 Mode::U32(ref vec) => Some(vec),
77 _ => None,
78 }
79 }
80 pub fn get_u32_mut(&mut self) -> Option<&mut Vec<u32>> {
82 match self.mode {
83 Mode::U32(ref mut vec) => Some(vec),
84 _ => None,
85 }
86 }
87 pub fn get_usize(&mut self) -> Option<&Vec<usize>> {
89 match self.mode {
90 Mode::Usize(ref vec) => Some(vec),
91 _ => None,
92 }
93 }
94 pub fn get_usize_mut(&mut self) -> Option<&mut Vec<usize>> {
96 match self.mode {
97 Mode::Usize(ref mut vec) => Some(vec),
98 _ => None,
99 }
100 }
101 pub fn get_usize_upgraded(&mut self) -> &Vec<usize> {
103 self.upgrade_to_usize();
104 match self.mode {
105 Mode::Usize(ref vec) => vec,
106 _ => panic!("Logic error in get_usize_upgraded of DynamicPrecisionIndexVec"),
107 }
108 }
109 pub fn get_usize_upgraded_mut(&mut self) -> &mut Vec<usize> {
111 self.upgrade_to_usize();
112 match self.mode {
113 Mode::Usize(ref mut vec) => vec,
114 _ => panic!("Logic error in get_usize_upgraded_mut of DynamicPrecisionIndexVec"),
115 }
116 }
117
118 fn upgrade_to_usize(&mut self) {
119 if let Some(new_mode) = match self.mode {
120 Mode::U8(ref vec) => {
121 let new = vec.iter().map(|x| *x as usize).collect();
122 Some(Mode::Usize(new))
123 }
124 Mode::U16(ref vec) => {
125 let new = vec.iter().map(|x| *x as usize).collect();
126 Some(Mode::Usize(new))
127 }
128 Mode::U32(ref vec) => {
129 let new = vec.iter().map(|x| *x as usize).collect();
130 Some(Mode::Usize(new))
131 }
132 Mode::Usize(_) => None,
133 } {
134 self.mode = new_mode;
135 }
136 }
137
138 fn upgrade_to_u32(&mut self) {
139 if let Some(new_mode) = match self.mode {
140 Mode::U8(ref vec) => {
141 let new = vec.iter().map(|x| *x as u32).collect();
142 Some(Mode::U32(new))
143 }
144 Mode::U16(ref vec) => {
145 let new = vec.iter().map(|x| *x as u32).collect();
146 Some(Mode::U32(new))
147 }
148 Mode::U32(_) => None,
149 Mode::Usize(_) => None,
150 } {
151 self.mode = new_mode;
152 }
153 }
154
155 fn upgrade_to_u16(&mut self) {
156 if let Some(new_mode) = match self.mode {
157 Mode::U8(ref vec) => {
158 let new = vec.iter().map(|x| *x as u16).collect();
159 Some(Mode::U16(new))
160 }
161 Mode::U16(_) => None,
162 Mode::U32(_) => None,
163 Mode::Usize(_) => None,
164 } {
165 self.mode = new_mode;
166 }
167 }
168
169 fn allowed_max(&self) -> usize {
170 match self.mode {
171 Mode::U8(_) => u8::MAX as usize,
172 Mode::U16(_) => u16::MAX as usize,
173 Mode::U32(_) => u32::MAX as usize,
174 Mode::Usize(_) => usize::MAX,
175 }
176 }
177}
178
179impl IsIndexContainer for DynamicPrecisionIndexVec {
182 fn ensure_supported(&mut self, x: usize) {
183 if x <= self.allowed_max() {
184 return;
185 }
186
187 if x > u32::MAX as usize {
188 self.upgrade_to_usize();
189 } else if x > u16::MAX as usize {
190 self.upgrade_to_u32();
191 } else if x > u8::MAX as usize {
192 self.upgrade_to_u16();
193 }
194 }
195
196 fn get(&self, i: usize) -> usize {
197 match self.mode {
198 Mode::U8(ref vec) => vec[i] as usize,
199 Mode::U16(ref vec) => vec[i] as usize,
200 Mode::U32(ref vec) => vec[i] as usize,
201 Mode::Usize(ref vec) => vec[i] as usize,
202 }
203 }
204
205 fn set(&mut self, i: usize, x: usize) {
206 self.ensure_supported(x);
207
208 match self.mode {
209 Mode::U8(ref mut vec) => vec[i] = x as u8,
210 Mode::U16(ref mut vec) => vec[i] = x as u16,
211 Mode::U32(ref mut vec) => vec[i] = x as u32,
212 Mode::Usize(ref mut vec) => vec[i] = x,
213 }
214 }
215
216 fn push(&mut self, x: usize) {
217 self.ensure_supported(x);
218
219 match self.mode {
220 Mode::U8(ref mut vec) => vec.push(x as u8),
221 Mode::U16(ref mut vec) => vec.push(x as u16),
222 Mode::U32(ref mut vec) => vec.push(x as u32),
223 Mode::Usize(ref mut vec) => vec.push(x),
224 }
225 }
226
227 fn len(&self) -> usize {
228 match self.mode {
229 Mode::U8(ref vec) => vec.len(),
230 Mode::U16(ref vec) => vec.len(),
231 Mode::U32(ref vec) => vec.len(),
232 Mode::Usize(ref vec) => vec.len(),
233 }
234 }
235
236 fn reserve(&mut self, n: usize) {
237 match self.mode {
238 Mode::U8(ref mut vec) => vec.reserve(n),
239 Mode::U16(ref mut vec) => vec.reserve(n),
240 Mode::U32(ref mut vec) => vec.reserve(n),
241 Mode::Usize(ref mut vec) => vec.reserve(n),
242 }
243 }
244
245 fn iter(&self) -> IsIndexContainerIterator<Self> {
246 IsIndexContainerIterator::new(self)
247 }
248}
249
250impl From<&Vec<usize>> for DynamicPrecisionIndexVec {
251 fn from(vec: &Vec<usize>) -> Self {
252 let mut result = Self::new();
253 if let Some(max) = vec.iter().max() {
254 result.ensure_supported(max);
255 result.reserve(vec.len());
256 for x in vec.iter() {
257 result.push(x)
258 }
259 }
260
261 result
262 }
263}
264
265impl From<Vec<usize>> for DynamicPrecisionIndexVec {
266 fn from(vec: Vec<usize>) -> Self {
267 Self::from(&vec)
268 }
269}
270
271impl From<&Vec<u32>> for DynamicPrecisionIndexVec {
272 fn from(vec: &Vec<u32>) -> Self {
273 let mut result = Self::new();
274 if let Some(max) = vec.iter().max() {
275 result.ensure_supported(*max as usize);
276 result.reserve(vec.len());
277 for x in vec.iter() {
278 result.push(*x as usize)
279 }
280 }
281
282 result
283 }
284}
285
286impl From<Vec<u32>> for DynamicPrecisionIndexVec {
287 fn from(vec: Vec<u32>) -> Self {
288 Self::from(&vec)
289 }
290}
291
292impl From<&Vec<u16>> for DynamicPrecisionIndexVec {
293 fn from(vec: &Vec<u16>) -> Self {
294 let mut result = Self::new();
295 if let Some(max) = vec.iter().max() {
296 result.ensure_supported(*max as usize);
297 result.reserve(vec.len());
298 for x in vec.iter() {
299 result.push(*x as usize)
300 }
301 }
302
303 result
304 }
305}
306
307impl From<Vec<u16>> for DynamicPrecisionIndexVec {
308 fn from(vec: Vec<u16>) -> Self {
309 Self::from(&vec)
310 }
311}
312
313impl From<&Vec<u8>> for DynamicPrecisionIndexVec {
314 fn from(vec: &Vec<u8>) -> Self {
315 Self::from(vec.clone())
316 }
317}
318
319impl From<Vec<u8>> for DynamicPrecisionIndexVec {
320 fn from(vec: Vec<u8>) -> Self {
321 Self {
322 mode: Mode::U8(vec),
323 }
324 }
325}
326
327#[derive(Clone)]
330enum Mode {
331 U8(Vec<u8>),
332 U16(Vec<u16>),
333 U32(Vec<u32>),
334 Usize(Vec<usize>),
335}
336
337impl Default for Mode {
338 fn default() -> Self {
339 Self::U8(Vec::new())
340 }
341}