1mod errors;
2
3pub use errors::*;
4
5pub fn indices_slice<'a, T>(slice: &'a mut [T], indices: &[usize]) -> Vec<&'a mut T> {
8 let slice_length = slice.len();
9 let indices_length = indices.len();
10 if slice_length == 0 {
11 if indices_length != 0 {
12 panic!("Requested indices but slice is empty.")
13 }
14 return Vec::new();
15 }
16 if indices_length == 0 {
17 return Vec::new();
18 }
19 let mut check: Vec<usize> = indices.to_vec();
20 insertion_sort(&mut check);
21 let indices_len_minus_one = indices_length - 1;
22 let slice_len_minus_one = slice_length - 1;
23 for i in 0..indices_len_minus_one {
24 if check[i] == check[i + 1] {
25 panic!(
26 "Duplicate indices are not allowed. Index `{}` was requested twice.",
27 check[i]
28 );
29 }
30 }
31 if check[indices_len_minus_one] > slice_len_minus_one {
32 panic!(
33 "Index out of bounds. Requested index was `{}` while slice length was `{}`.",
34 check[indices_len_minus_one],
35 slice_len_minus_one + 1
36 );
37 }
38 let mut vector: Vec<std::mem::MaybeUninit<*mut T>> =
39 vec![std::mem::MaybeUninit::uninit(); indices_length];
40 let ptr = slice.as_mut_ptr();
41 unsafe {
42 for (i, index) in indices.iter().enumerate() {
43 vector[i].write(ptr.add(*index));
44 }
45 std::mem::transmute::<_, Vec<&'a mut T>>(vector)
46 }
47}
48
49pub fn indices_slices<'a, T, const N: usize>(
52 slice: &'a mut [T],
53 indices: [&[usize]; N],
54) -> [Vec<&'a mut T>; N] {
55 const {
56 assert!(
57 std::mem::size_of::<[std::mem::MaybeUninit<Vec<*mut T>>; N]>()
58 == std::mem::size_of::<[Vec<*mut T>; N]>()
59 );
60 }
61 if N == 0 {
62 return unsafe { std::mem::zeroed() };
63 }
64 let slice_length = slice.len();
65 let mut all_requested_indices: Vec<usize> = indices.concat();
66 let all_requested_indices_length = all_requested_indices.len();
67 if slice_length == 0 {
68 if all_requested_indices_length != 0 {
69 panic!("Requested indices but slice is empty.")
70 }
71 unsafe {
72 let mut array: [std::mem::MaybeUninit<Vec<*mut T>>; N] =
73 std::mem::MaybeUninit::uninit().assume_init();
74 for i in 0..N {
75 let out_vec = Vec::with_capacity(0);
76 array[i].write(out_vec);
77 }
78 return std::mem::transmute_copy::<
79 [std::mem::MaybeUninit<Vec<*mut T>>; N],
80 [Vec<&'a mut T>; N],
81 >(&array);
82 }
83 }
84 if all_requested_indices_length == 0 {
85 unsafe {
86 let mut array: [std::mem::MaybeUninit<Vec<*mut T>>; N] =
87 std::mem::MaybeUninit::uninit().assume_init();
88 for i in 0..N {
89 let out_vec = Vec::with_capacity(0);
90 array[i].write(out_vec);
91 }
92 return std::mem::transmute_copy::<
93 [std::mem::MaybeUninit<Vec<*mut T>>; N],
94 [Vec<&'a mut T>; N],
95 >(&array);
96 }
97 }
98 insertion_sort(&mut all_requested_indices);
99 let indices_len_minus_one = all_requested_indices_length - 1;
100 let slice_len_minus_one = slice_length - 1;
101 for i in 0..indices_len_minus_one {
102 if all_requested_indices[i] == all_requested_indices[i + 1] {
103 panic!(
104 "Duplicate indices are not allowed. Index `{}` was requested twice.",
105 all_requested_indices[i]
106 );
107 }
108 }
109 if all_requested_indices[indices_len_minus_one] > slice_len_minus_one {
110 panic!(
111 "Index out of bounds. Requested index was `{}` while slice length was `{}`.",
112 all_requested_indices[indices_len_minus_one],
113 slice_len_minus_one + 1
114 );
115 }
116 let ptr = slice.as_mut_ptr();
117 unsafe {
118 let mut array: [std::mem::MaybeUninit<Vec<*mut T>>; N] =
119 std::mem::MaybeUninit::uninit().assume_init();
120 for (i, indice) in indices.iter().enumerate() {
121 let mut out_vec = Vec::with_capacity(indice.len());
122 for index in *indice {
123 out_vec.push(ptr.add(*index));
124 }
125 array[i].write(out_vec);
126 }
127 std::mem::transmute_copy::<[std::mem::MaybeUninit<Vec<*mut T>>; N], [Vec<&'a mut T>; N]>(
128 &array,
129 )
130 }
131}
132
133pub fn indices_array<'a, T, const N: usize>(
138 slice: &'a mut [T],
139 indices: &[usize; N],
140) -> [&'a mut T; N] {
141 const {
142 assert!(
143 std::mem::size_of::<[std::mem::MaybeUninit<*mut T>; N]>()
144 == std::mem::size_of::<[&'a mut T; N]>()
145 );
146 }
147 let slice_length = slice.len();
148 let indices_length = N;
149 if slice_length == 0 {
150 if indices_length != 0 {
151 panic!("Requested indices but slice is empty.")
152 }
153 return unsafe { std::mem::zeroed() };
154 }
155 if indices_length == 0 {
156 return unsafe { std::mem::zeroed() };
157 }
158 let mut check: Vec<usize> = indices.to_vec();
159 insertion_sort(&mut check);
160 let indices_len_minus_one = indices_length - 1;
161 let slice_len_minus_one = slice_length - 1;
162 for i in 0..indices_len_minus_one {
163 if check[i] == check[i + 1] {
164 panic!(
165 "Duplicate indices are not allowed. Index `{}` was requested twice.",
166 check[i]
167 );
168 }
169 }
170 if check[indices_len_minus_one] > slice_len_minus_one {
171 panic!(
172 "Index out of bounds. Requested index was `{}` while slice length was `{}`.",
173 check[indices_len_minus_one],
174 slice_len_minus_one + 1
175 );
176 }
177
178 let ptr = slice.as_mut_ptr();
179 unsafe {
180 let mut array: [std::mem::MaybeUninit<*mut T>; N] =
181 std::mem::MaybeUninit::uninit().assume_init();
182 for (i, index) in indices.iter().enumerate() {
183 array[i].write(ptr.add(*index));
184 }
185 std::mem::transmute_copy::<[std::mem::MaybeUninit<*mut T>; N], [&'a mut T; N]>(&array)
186 }
187}
188
189#[doc(hidden)]
192#[macro_export]
193macro_rules! to_type {
194 ( $t:expr ) => { &'a mut T };
195}
196
197#[macro_export]
200macro_rules! indices {
201 ($slice:expr, $index1:expr) => {{
202 (&mut $slice[$index1],)
203 }};
204
205 ($slice:expr, $index1:expr, $index2:expr) => {{
206 #[inline(always)]
207 fn func<T>(slice: &mut [T], one: usize, two: usize) -> (&mut T, &mut T) {
208 if one == two {
209 panic!("Duplicate indices are not allowed. Index `{}` was requested twice.", one)
210 }
211 let slice_len = slice.len();
212 if one >= slice_len || two >= slice_len {
213 panic!("Index out of bounds.")
214 }
215 let ptr = slice.as_mut_ptr();
216 unsafe {
217 (&mut *ptr.add(one), &mut *ptr.add(two))
218 }
219 }
220 func($slice, $index1, $index2)
221 }};
222
223 ($slice:expr, $index1:expr, $index2:expr, $index3:expr) => {{
224 #[inline(always)]
225 fn func<T>(slice: &mut [T], one: usize, two: usize, three: usize) -> (&mut T, &mut T, &mut T) {
226 if one == two || one == three || two == three {
227 panic!("Duplicate indices are not allowed.")
228 }
229 let slice_len = slice.len();
230 if one >= slice_len || two >= slice_len || three >= slice_len {
231 panic!("Index out of bounds.")
232 }
233 let ptr = slice.as_mut_ptr();
234 unsafe {
235 (&mut *ptr.add(one), &mut *ptr.add(two), &mut *ptr.add(three))
236 }
237 }
238 func($slice, $index1, $index2, $index3)
239 }};
240
241 ($slice:expr, $index1:expr, $index2:expr, $index3:expr, $index4:expr) => {{
242 #[inline(always)]
243 fn func<T>(slice: &mut [T], one: usize, two: usize, three: usize, four: usize) -> (&mut T, &mut T, &mut T, &mut T) {
244 if one == two || one == three || one == four || two == three || two == four || three == four {
245 panic!("Duplicate indices are not allowed.")
246 }
247 let slice_len = slice.len();
248 if one >= slice_len || two >= slice_len || three >= slice_len || four >= slice_len {
249 panic!("Index out of bounds.")
250 }
251 let ptr = slice.as_mut_ptr();
252 unsafe {
253 (&mut *ptr.add(one), &mut *ptr.add(two), &mut *ptr.add(three), &mut *ptr.add(four))
254 }
255 }
256 func($slice, $index1, $index2, $index3, $index4)
257 }};
258
259 ($slice:expr, $( $index:expr ),+) => {{
260 #[inline(always)]
261 fn func<'a, 'b, T>(slice: &'a mut [T], indices: &'b mut [usize]) -> ($($crate::to_type!($index)),+) {
262 if slice.is_empty() {
263 panic!("Requested indices but slice is empty.")
264 }
265 $crate::insertion_sort(indices);
266
267 let indices_len_minus_one = indices.len() - 1;
268 let slice_len_minus_one = slice.len() - 1;
269 for i in 0..indices_len_minus_one {
270 if indices[i] == indices[i + 1] {
271 panic!("Duplicate indices are not allowed. Index `{}` was requested twice.", indices[i])
272 }
273 }
274 if indices[indices_len_minus_one] > slice_len_minus_one {
275 panic!(
276 "Index out of bounds. Requested index was `{}` while slice length was `{}`.",
277 indices[indices_len_minus_one], slice_len_minus_one + 1
278 )
279 }
280
281 let ptr = slice.as_mut_ptr();
282 (
283 $(unsafe { &mut *ptr.add($index) },)*
284 )
285 }
286 let mut indices = [$($index),*];
287 func($slice, &mut indices)
288 }};
289}
290
291#[macro_export]
294macro_rules! try_indices {
295 ($slice:expr, $index1:expr) => {{
296 $slice.get_mut($index1).map(|e| (e,)).ok_or($crate::TryIndicesError::IndexOutOfBounds)
297 }};
298
299 ($slice:expr, $index1:expr, $index2:expr) => {{
300 #[inline(always)]
301 fn func<T>(slice: &mut [T], one: usize, two: usize) -> Result<(&mut T, &mut T), $crate::TryIndicesError> {
302 if one == two {
303 return Err($crate::TryIndicesError::DuplicateIndex);
304 }
305 let slice_len = slice.len();
306 if one >= slice_len || two >= slice_len {
307 return Err($crate::TryIndicesError::IndexOutOfBounds);
308 }
309 let ptr = slice.as_mut_ptr();
310 unsafe {
311 Ok((&mut *ptr.add(one), &mut *ptr.add(two)))
312 }
313 }
314 func($slice, $index1, $index2)
315 }};
316
317 ($slice:expr, $index1:expr, $index2:expr, $index3:expr) => {{
318 #[inline(always)]
319 fn func<T>(slice: &mut [T], one: usize, two: usize, three: usize) -> Result<(&mut T, &mut T, &mut T), $crate::TryIndicesError> {
320 if one == two || one == three || two == three {
321 return Err($crate::TryIndicesError::DuplicateIndex);
322 }
323 let slice_len = slice.len();
324 if one >= slice_len || two >= slice_len || three >= slice_len {
325 return Err($crate::TryIndicesError::IndexOutOfBounds);
326 }
327 let ptr = slice.as_mut_ptr();
328 unsafe {
329 Ok((&mut *ptr.add(one), &mut *ptr.add(two), &mut *ptr.add(three)))
330 }
331 }
332 func($slice, $index1, $index2, $index3)
333 }};
334
335 ($slice:expr, $index1:expr, $index2:expr, $index3:expr, $index4:expr) => {{
336 #[inline(always)]
337 fn func<T>(slice: &mut [T], one: usize, two: usize, three: usize, four: usize) -> Result<(&mut T, &mut T, &mut T, &mut T), $crate::TryIndicesError> {
338 if one == two || one == three || one == four || two == three || two == four || three == four {
339 return Err($crate::TryIndicesError::DuplicateIndex);
340 }
341 let slice_len = slice.len();
342 if one >= slice_len || two >= slice_len || three >= slice_len || four >= slice_len {
343 return Err($crate::TryIndicesError::IndexOutOfBounds);
344 }
345 let ptr = slice.as_mut_ptr();
346 unsafe {
347 Ok((&mut *ptr.add(one), &mut *ptr.add(two), &mut *ptr.add(three), &mut *ptr.add(four)))
348 }
349 }
350 func($slice, $index1, $index2, $index3, $index4)
351 }};
352
353 ($slice:expr, $( $index:expr ),+) => {{
354 #[inline(always)]
355 fn func<'a, 'b, T>(slice: &'a mut [T], indices: &'b mut [usize]) -> Result<($($crate::to_type!($index)),+), $crate::TryIndicesError> {
356 if slice.is_empty() {
357 return Err($crate::TryIndicesError::IndexOutOfBounds);
358 }
359 $crate::insertion_sort(indices);
360
361 let indices_len_minus_one = indices.len() - 1;
362 let slice_len_minus_one = slice.len() - 1;
363 for i in 0..indices_len_minus_one {
364 if indices[i] == indices[i + 1] {
365 return Err($crate::TryIndicesError::DuplicateIndex);
366 }
367 }
368 if indices[indices_len_minus_one] > slice_len_minus_one {
369 return Err($crate::TryIndicesError::IndexOutOfBounds);
370 }
371
372 let ptr = slice.as_mut_ptr();
373 Ok((
374 $(unsafe { &mut *ptr.add($index) },)*
375 ))
376 }
377 let mut indices = [$($index),*];
378 func($slice, &mut indices)
379 }};
380}
381
382#[macro_export]
386macro_rules! indices_ordered {
387 ($slice:expr, $index1:expr) => {{
388 (&mut $slice[$index1],)
389 }};
390
391 ($slice:expr, $( $index:expr ),+) => {{
392 #[inline(always)]
393 fn func<'a, 'b, T>(slice: &'a mut [T], indices: &'b [usize]) -> ($($crate::to_type!($index)),+) {
394 if slice.is_empty() {
395 panic!("Requested indices but slice is empty.");
396 }
397
398 let indices_len_minus_one = indices.len() - 1;
399 let slice_len_minus_one = slice.len() - 1;
400
401 for i in 0..indices_len_minus_one {
402 if indices[i] > slice_len_minus_one {
403 panic!("Index out of bounds. Requested index was `{}` while slice length was `{}`.", indices[i], slice_len_minus_one + 1);
404 }
405 if indices[i] >= indices[i + 1] {
406 panic!("Indices not sorted or duplicate indices detected.");
407 }
408 }
409 if indices[indices_len_minus_one] > slice_len_minus_one {
410 panic!("Index out of bounds. Requested index was `{}` while slice length was `{}`.", indices[indices_len_minus_one], slice_len_minus_one + 1);
411 }
412
413 let ptr = slice.as_mut_ptr();
414 (
415 $(unsafe { &mut *ptr.add($index) },)*
416 )
417 }
418 let indices = [$($index),*];
419 func($slice, &indices)
420 }};
421}
422
423#[macro_export]
427macro_rules! try_indices_ordered {
428 ($slice:expr, $index1:expr) => {{
429 $slice.get_mut($index1).map(|e| (e,)).ok_or($crate::TryIndicesOrderedError::IndexOutOfBounds)
430 }};
431
432 ($slice:expr, $( $index:expr ),+) => {{
433 #[inline(always)]
434 fn func<'a, 'b, T>(slice: &'a mut [T], indices: &'b [usize]) -> Result<($($crate::to_type!($index)),+), $crate::TryIndicesOrderedError> {
435 if slice.is_empty() {
436 return Err($crate::TryIndicesOrderedError::IndexOutOfBounds);
437 }
438
439 let indices_len_minus_one = indices.len() - 1;
440 let slice_len_minus_one = slice.len() - 1;
441
442 for i in 0..indices_len_minus_one {
443 if indices[i] > slice_len_minus_one {
444 return Err($crate::TryIndicesOrderedError::IndexOutOfBounds);
445 }
446 if indices[i] >= indices[i + 1] {
447 return Err($crate::TryIndicesOrderedError::InvalidIndex);
448 }
449 }
450 if indices[indices_len_minus_one] > slice_len_minus_one {
451 return Err($crate::TryIndicesOrderedError::IndexOutOfBounds);
452 }
453
454 let ptr = slice.as_mut_ptr();
455 Ok((
456 $(unsafe { &mut *ptr.add($index) },)*
457 ))
458 }
459 let indices = [$($index),*];
460 func($slice, &indices)
461 }};
462}
463
464#[doc(hidden)]
467pub fn insertion_sort<T: PartialOrd>(s: &mut [T]) {
468 for i in 1..s.len() {
469 let mut j = i;
470 while j > 0 && s[j - 1] > s[j] {
471 s.swap(j - 1, j);
472 j -= 1;
473 }
474 }
475}
476
477#[cfg(test)]
480mod tests {
481 use crate::{
482 indices_array, indices_slice, indices_slices, TryIndicesError, TryIndicesOrderedError,
483 };
484
485 #[test]
486 fn indices_slice_works() {
487 let mut data = [5, 4, 3, 2, 1];
488 let slice = data.as_mut_slice();
489 let [one, two] = indices_slice(slice, &mut [1, 3]).try_into().unwrap();
490 assert_eq!(one, &mut 4);
491 assert_eq!(two, &mut 2);
492 *one = 10;
493 *two = 20;
494 assert_eq!(data, [5, 10, 3, 20, 1]);
495 }
496
497 #[test]
498 fn indices_slice_out_of_order() {
499 let mut data = [5, 4, 3, 2, 1];
500 let slice = data.as_mut_slice();
501 let [one, two] = indices_slice(slice, &mut [3, 1]).try_into().unwrap();
502 assert_eq!(one, &mut 2);
503 assert_eq!(two, &mut 4);
504 *one = 10;
505 *two = 20;
506 assert_eq!(data, [5, 20, 3, 10, 1]);
507 }
508
509 #[test]
510 fn indices_slice_more_than_two_indices() {
511 let mut data = [5, 4, 3, 2, 1];
512 let slice = data.as_mut_slice();
513 let [one, two, three] = indices_slice(slice, &mut [3, 1, 2]).try_into().unwrap();
514 assert_eq!(one, &mut 2);
515 assert_eq!(two, &mut 4);
516 assert_eq!(three, &mut 3);
517 *one = 10;
518 *two = 20;
519 *three = 30;
520 assert_eq!(data, [5, 20, 30, 10, 1]);
521 }
522
523 #[should_panic]
524 #[test]
525 fn indices_slice_duplicate_indices() {
526 let mut data = [5, 4, 3, 2, 1];
527 let slice = data.as_mut_slice();
528 let _result = indices_slice(slice, &mut [3, 3]);
529 }
530
531 #[should_panic]
532 #[test]
533 fn indices_slice_out_of_bounds() {
534 let mut data = [5, 4, 3, 2, 1];
535 let slice = data.as_mut_slice();
536 let _result = indices_slice(slice, &mut [3, 5]);
537 }
538
539 #[should_panic]
540 #[test]
541 fn indices_slice_empty_requested_indices() {
542 let mut data: [i32; 0] = [];
543 let slice = data.as_mut_slice();
544 let _result = indices_slice(slice, &mut [3]);
545 }
546
547 #[test]
548 fn indices_slice_empty_requested_empty() {
549 let mut data: [i32; 0] = [];
550 let slice = data.as_mut_slice();
551 let result = indices_slice(slice, &mut []);
552 assert!(result.is_empty())
553 }
554
555 #[test]
556 fn indices_slice_not_empty_slice_requested_empty() {
557 let mut data: [i32; 1] = [1];
558 let slice = data.as_mut_slice();
559 let result = indices_slice(slice, &mut []);
560 assert!(result.is_empty())
561 }
562
563 #[test]
566 fn indices_array_works() {
567 let mut data = [5, 4, 3, 2, 1];
568 let slice = data.as_mut_slice();
569 let [one, two] = indices_array(slice, &mut [1, 3]);
570 assert_eq!(one, &mut 4);
571 assert_eq!(two, &mut 2);
572 *one = 10;
573 *two = 20;
574 assert_eq!(data, [5, 10, 3, 20, 1]);
575 }
576
577 #[test]
578 fn indices_array_out_of_order() {
579 let mut data = [5, 4, 3, 2, 1];
580 let slice = data.as_mut_slice();
581 let [one, two] = indices_array(slice, &mut [3, 1]);
582 assert_eq!(one, &mut 2);
583 assert_eq!(two, &mut 4);
584 *one = 10;
585 *two = 20;
586 assert_eq!(data, [5, 20, 3, 10, 1]);
587 }
588
589 #[test]
590 fn indices_array_more_than_two_indices() {
591 let mut data = [5, 4, 3, 2, 1];
592 let slice = data.as_mut_slice();
593 let [one, two, three] = indices_array(slice, &mut [3, 1, 2]);
594 assert_eq!(one, &mut 2);
595 assert_eq!(two, &mut 4);
596 assert_eq!(three, &mut 3);
597 *one = 10;
598 *two = 20;
599 *three = 30;
600 assert_eq!(data, [5, 20, 30, 10, 1]);
601 }
602
603 #[should_panic]
604 #[test]
605 fn indices_array_duplicate_indices() {
606 let mut data = [5, 4, 3, 2, 1];
607 let slice = data.as_mut_slice();
608 let [_one, _two] = indices_array(slice, &mut [3, 3]);
609 }
610
611 #[should_panic]
612 #[test]
613 fn indices_array_out_of_bounds() {
614 let mut data = [5, 4, 3, 2, 1];
615 let slice = data.as_mut_slice();
616 let [_one, _two] = indices_array(slice, &mut [3, 5]);
617 }
618
619 #[should_panic]
620 #[test]
621 fn indices_array_empty_requested_indices() {
622 let mut data: [i32; 0] = [];
623 let slice = data.as_mut_slice();
624 let _result = indices_array(slice, &mut [3]);
625 }
626
627 #[test]
628 fn indices_array_empty_requested_empty() {
629 let mut data: [i32; 0] = [];
630 let slice = data.as_mut_slice();
631 let result = indices_array(slice, &mut []);
632 assert!(result.is_empty())
633 }
634
635 #[test]
636 fn indices_array_not_empty_slice_requested_empty() {
637 let mut data: [i32; 1] = [1];
638 let slice = data.as_mut_slice();
639 let result = indices_array(slice, &mut []);
640 assert!(result.is_empty())
641 }
642
643 #[should_panic]
646 #[test]
647 fn indices_empty() {
648 let mut data: [i32; 0] = [];
649 let slice = data.as_mut_slice();
650 let _result = indices!(slice, 3);
651 }
652
653 #[test]
654 fn indices_1() {
655 let mut data = [5, 4, 3, 2, 1];
656 let slice = data.as_mut_slice();
657 let (one,) = indices!(slice, 3);
658 assert_eq!(one, &mut 2);
659 *one = 10;
660 assert_eq!(data, [5, 4, 3, 10, 1]);
661 }
662
663 #[should_panic]
664 #[test]
665 fn indices_1_out_of_bounds() {
666 let mut data = [5, 4, 3, 2, 1];
667 let slice = data.as_mut_slice();
668 let (_one,) = indices!(slice, 5);
669 }
670
671 #[test]
672 fn indices_2() {
673 let mut data = [5, 4, 3, 2, 1];
674 let slice = data.as_mut_slice();
675 let (one, two) = indices!(slice, 1, 3);
676 assert_eq!(one, &mut 4);
677 assert_eq!(two, &mut 2);
678 *one = 10;
679 *two = 20;
680 assert_eq!(data, [5, 10, 3, 20, 1]);
681 }
682
683 #[test]
684 fn indices_2_out_of_order() {
685 let mut data = [5, 4, 3, 2, 1];
686 let slice = data.as_mut_slice();
687 let (one, two) = indices!(slice, 3, 1);
688 assert_eq!(one, &mut 2);
689 assert_eq!(two, &mut 4);
690 *one = 10;
691 *two = 20;
692 assert_eq!(data, [5, 20, 3, 10, 1]);
693 }
694
695 #[should_panic]
696 #[test]
697 fn indices_2_duplicate_indices() {
698 let mut data = [5, 4, 3, 2, 1];
699 let slice = data.as_mut_slice();
700 let (_one, _two) = indices!(slice, 3, 3);
701 }
702
703 #[should_panic]
704 #[test]
705 fn indices_2_out_of_bounds() {
706 let mut data = [5, 4, 3, 2, 1];
707 let slice = data.as_mut_slice();
708 let (_one, _two) = indices!(slice, 3, 5);
709 }
710
711 #[test]
712 fn indices_3() {
713 let mut data = [5, 4, 3, 2, 1];
714 let slice = data.as_mut_slice();
715 let (one, two, three) = indices!(slice, 3, 1, 2);
716 assert_eq!(one, &mut 2);
717 assert_eq!(two, &mut 4);
718 assert_eq!(three, &mut 3);
719 *one = 10;
720 *two = 20;
721 *three = 30;
722 assert_eq!(data, [5, 20, 30, 10, 1]);
723 }
724
725 #[should_panic]
726 #[test]
727 fn indices_3_out_of_bounds() {
728 let mut data = [5, 4, 3, 2, 1];
729 let slice = data.as_mut_slice();
730 let (_one, _two, _three) = indices!(slice, 1, 3, 5);
731 }
732
733 #[should_panic]
734 #[test]
735 fn indices_3_duplicate_indices() {
736 let mut data = [5, 4, 3, 2, 1];
737 let slice = data.as_mut_slice();
738 let (_one, _two, _three) = indices!(slice, 1, 3, 3);
739 }
740
741 #[test]
742 fn indices_4() {
743 let mut data = [5, 4, 3, 2, 1, 6];
744 let slice = data.as_mut_slice();
745 let (one, two, three, four) = indices!(slice, 0, 2, 4, 5);
746 assert_eq!(one, &mut 5);
747 assert_eq!(two, &mut 3);
748 assert_eq!(three, &mut 1);
749 assert_eq!(four, &mut 6);
750 *one = 10;
751 *two = 20;
752 *three = 30;
753 *four = 40;
754 assert_eq!(data, [10, 4, 20, 2, 30, 40]);
755 }
756
757 #[should_panic]
758 #[test]
759 fn indices_4_out_of_bounds() {
760 let mut data = [5, 4, 3, 2, 1];
761 let slice = data.as_mut_slice();
762 let (_one, _two, _three, _four) = indices!(slice, 1, 3, 4, 5);
763 }
764
765 #[should_panic]
766 #[test]
767 fn indices_4_duplicate_indices() {
768 let mut data = [5, 4, 3, 2, 1];
769 let slice = data.as_mut_slice();
770 let (_one, _two, _three, _four) = indices!(slice, 1, 3, 4, 3);
771 }
772
773 #[test]
774 fn indices_5() {
775 let mut data = [5, 4, 3, 2, 1, 6];
776 let slice = data.as_mut_slice();
777 let (one, two, three, four, five) = indices!(slice, 0, 1, 2, 4, 5);
778 assert_eq!(one, &mut 5);
779 assert_eq!(two, &mut 4);
780 assert_eq!(three, &mut 3);
781 assert_eq!(four, &mut 1);
782 assert_eq!(five, &mut 6);
783 *one = 10;
784 *two = 20;
785 *three = 30;
786 *four = 40;
787 *five = 50;
788 assert_eq!(data, [10, 20, 30, 2, 40, 50]);
789 }
790
791 #[should_panic]
792 #[test]
793 fn indices_5_out_of_bounds() {
794 let mut data = [5, 4, 3, 2, 1];
795 let slice = data.as_mut_slice();
796 let (_one, _two, _three, _four, _five) = indices!(slice, 1, 2, 3, 4, 5);
797 }
798
799 #[should_panic]
800 #[test]
801 fn indices_5_duplicate_indices() {
802 let mut data = [5, 4, 3, 2, 1];
803 let slice = data.as_mut_slice();
804 let (_one, _two, _three, _four, _five) = indices!(slice, 1, 2, 3, 4, 3);
805 }
806
807 #[test]
808 fn indices_can_return_mut_from_scope() {
809 let mut data = [0, 1, 2, 3, 4];
810 let (two, four) = indices_scope_helper(&mut data);
811 *two = 200;
812 *four = 400;
813 assert_eq!(data[2], 200);
814 assert_eq!(data[4], 400);
815 }
816
817 fn indices_scope_helper(data: &mut [i32]) -> (&mut i32, &mut i32) {
818 let (two, four) = indices!(data, 2, 4);
819 (two, four)
820 }
821
822 #[test]
825 fn try_indices_empty() {
826 let mut data: [i32; 0] = [];
827 let slice = data.as_mut_slice();
828 let result = try_indices!(slice, 3);
829 assert_eq!(result, Err(TryIndicesError::IndexOutOfBounds))
830 }
831
832 #[test]
833 fn try_indices_1() {
834 let mut data = [5, 4, 3, 2, 1];
835 let slice = data.as_mut_slice();
836 let (one,) = try_indices!(slice, 3).unwrap();
837 assert_eq!(one, &mut 2);
838 *one = 10;
839 assert_eq!(data, [5, 4, 3, 10, 1]);
840 }
841
842 #[test]
843 fn try_indices_1_out_of_bounds() {
844 let mut data = [5, 4, 3, 2, 1];
845 let slice = data.as_mut_slice();
846 let result = try_indices!(slice, 5);
847 assert_eq!(result, Err(TryIndicesError::IndexOutOfBounds))
848 }
849
850 #[test]
851 fn try_indices_2() {
852 let mut data = [5, 4, 3, 2, 1];
853 let slice = data.as_mut_slice();
854 let (one, two) = try_indices!(slice, 1, 3).unwrap();
855 assert_eq!(one, &mut 4);
856 assert_eq!(two, &mut 2);
857 *one = 10;
858 *two = 20;
859 assert_eq!(data, [5, 10, 3, 20, 1]);
860 }
861
862 #[test]
863 fn try_indices_2_out_of_order() {
864 let mut data = [5, 4, 3, 2, 1];
865 let slice = data.as_mut_slice();
866 let (one, two) = try_indices!(slice, 3, 1).unwrap();
867 assert_eq!(one, &mut 2);
868 assert_eq!(two, &mut 4);
869 *one = 10;
870 *two = 20;
871 assert_eq!(data, [5, 20, 3, 10, 1]);
872 }
873
874 #[test]
875 fn try_indices_2_duplicate_indices() {
876 let mut data = [5, 4, 3, 2, 1];
877 let slice = data.as_mut_slice();
878 let result = try_indices!(slice, 3, 3);
879 assert_eq!(result, Err(TryIndicesError::DuplicateIndex))
880 }
881
882 #[test]
883 fn try_indices_2_out_of_bounds() {
884 let mut data = [5, 4, 3, 2, 1];
885 let slice = data.as_mut_slice();
886 let result = try_indices!(slice, 3, 5);
887 assert_eq!(result, Err(TryIndicesError::IndexOutOfBounds))
888 }
889
890 #[test]
891 fn try_indices_3() {
892 let mut data = [5, 4, 3, 2, 1];
893 let slice = data.as_mut_slice();
894 let (one, two, three) = try_indices!(slice, 3, 1, 2).unwrap();
895 assert_eq!(one, &mut 2);
896 assert_eq!(two, &mut 4);
897 assert_eq!(three, &mut 3);
898 *one = 10;
899 *two = 20;
900 *three = 30;
901 assert_eq!(data, [5, 20, 30, 10, 1]);
902 }
903
904 #[test]
905 fn try_indices_3_out_of_bounds() {
906 let mut data = [5, 4, 3, 2, 1];
907 let slice = data.as_mut_slice();
908 let result = try_indices!(slice, 1, 3, 5);
909 assert_eq!(result, Err(TryIndicesError::IndexOutOfBounds))
910 }
911
912 #[test]
913 fn try_indices_3_duplicate_indices() {
914 let mut data = [5, 4, 3, 2, 1];
915 let slice = data.as_mut_slice();
916 let result = try_indices!(slice, 1, 3, 3);
917 assert_eq!(result, Err(TryIndicesError::DuplicateIndex))
918 }
919
920 #[test]
921 fn try_indices_4() {
922 let mut data = [5, 4, 3, 2, 1, 6];
923 let slice = data.as_mut_slice();
924 let (one, two, three, four) = try_indices!(slice, 0, 2, 4, 5).unwrap();
925 assert_eq!(one, &mut 5);
926 assert_eq!(two, &mut 3);
927 assert_eq!(three, &mut 1);
928 assert_eq!(four, &mut 6);
929 *one = 10;
930 *two = 20;
931 *three = 30;
932 *four = 40;
933 assert_eq!(data, [10, 4, 20, 2, 30, 40]);
934 }
935
936 #[test]
937 fn try_indices_4_out_of_bounds() {
938 let mut data = [5, 4, 3, 2, 1];
939 let slice = data.as_mut_slice();
940 let result = try_indices!(slice, 1, 3, 4, 5);
941 assert_eq!(result, Err(TryIndicesError::IndexOutOfBounds))
942 }
943
944 #[test]
945 fn try_indices_4_duplicate_indices() {
946 let mut data = [5, 4, 3, 2, 1];
947 let slice = data.as_mut_slice();
948 let result = try_indices!(slice, 1, 3, 4, 3);
949 assert_eq!(result, Err(TryIndicesError::DuplicateIndex))
950 }
951
952 #[test]
953 fn try_indices_5() {
954 let mut data = [5, 4, 3, 2, 1, 6];
955 let slice = data.as_mut_slice();
956 let (one, two, three, four, five) = try_indices!(slice, 0, 1, 2, 4, 5).unwrap();
957 assert_eq!(one, &mut 5);
958 assert_eq!(two, &mut 4);
959 assert_eq!(three, &mut 3);
960 assert_eq!(four, &mut 1);
961 assert_eq!(five, &mut 6);
962 *one = 10;
963 *two = 20;
964 *three = 30;
965 *four = 40;
966 *five = 50;
967 assert_eq!(data, [10, 20, 30, 2, 40, 50]);
968 }
969
970 #[test]
971 fn try_indices_5_out_of_bounds() {
972 let mut data = [5, 4, 3, 2, 1];
973 let slice = data.as_mut_slice();
974 let result = try_indices!(slice, 1, 2, 3, 4, 5);
975 assert_eq!(result, Err(TryIndicesError::IndexOutOfBounds))
976 }
977
978 #[test]
979 fn try_indices_5_duplicate_indices() {
980 let mut data = [5, 4, 3, 2, 1];
981 let slice = data.as_mut_slice();
982 let result = try_indices!(slice, 1, 2, 3, 4, 3);
983 assert_eq!(result, Err(TryIndicesError::DuplicateIndex))
984 }
985
986 #[test]
987 fn try_indices_can_return_mut_from_scope() {
988 let mut data = [0, 1, 2, 3, 4];
989 let (two, four) = try_indices_scope_helper(&mut data).unwrap();
990 *two = 200;
991 *four = 400;
992 assert_eq!(data[2], 200);
993 assert_eq!(data[4], 400);
994 }
995
996 fn try_indices_scope_helper(data: &mut [i32]) -> Result<(&mut i32, &mut i32), TryIndicesError> {
997 let (two, four) = try_indices!(data, 2, 4)?;
998 Ok((two, four))
999 }
1000
1001 #[test]
1004 fn indices_ordered_works() {
1005 let mut data = [5, 4, 3, 2, 1];
1006 let slice = data.as_mut_slice();
1007 let (one, two) = indices_ordered!(slice, 1, 3);
1008 assert_eq!(one, &mut 4);
1009 assert_eq!(two, &mut 2);
1010 *one = 10;
1011 *two = 20;
1012 assert_eq!(data, [5, 10, 3, 20, 1]);
1013 }
1014
1015 #[test]
1016 fn indices_ordered_more_than_two_indices() {
1017 let mut data = [5, 4, 3, 2, 1];
1018 let slice = data.as_mut_slice();
1019 let (one, two, three) = indices_ordered!(slice, 1, 2, 4);
1020 assert_eq!(one, &mut 4);
1021 assert_eq!(two, &mut 3);
1022 assert_eq!(three, &mut 1);
1023 *one = 10;
1024 *two = 20;
1025 *three = 30;
1026 assert_eq!(data, [5, 10, 20, 2, 30]);
1027 }
1028
1029 #[should_panic]
1030 #[test]
1031 fn indices_ordered_duplicate_indices() {
1032 let mut data = [5, 4, 3, 2, 1];
1033 let slice = data.as_mut_slice();
1034 let (_one, _two) = indices_ordered!(slice, 3, 3);
1035 }
1036
1037 #[should_panic]
1038 #[test]
1039 fn indices_ordered_out_of_order() {
1040 let mut data = [5, 4, 3, 2, 1];
1041 let slice = data.as_mut_slice();
1042 let (_one, _two) = indices_ordered!(slice, 3, 1);
1043 }
1044
1045 #[should_panic]
1046 #[test]
1047 fn indices_ordered_out_of_bounds() {
1048 let mut data = [5, 4, 3, 2, 1];
1049 let slice = data.as_mut_slice();
1050 let (_one, _two) = indices_ordered!(slice, 3, 5);
1051 }
1052
1053 #[should_panic]
1054 #[test]
1055 fn indices_ordered_empty_requested_indices() {
1056 let mut data: [i32; 0] = [];
1057 let slice = data.as_mut_slice();
1058 let _result = indices_ordered!(slice, 3);
1059 }
1060
1061 #[test]
1062 fn indices_ordered_can_return_mut_from_scope() {
1063 let mut data = [0, 1, 2, 3, 4];
1064 let (two, four) = indices_ordered_scope_helper(&mut data);
1065 *two = 200;
1066 *four = 400;
1067 assert_eq!(data[2], 200);
1068 assert_eq!(data[4], 400);
1069 }
1070
1071 fn indices_ordered_scope_helper(data: &mut [i32]) -> (&mut i32, &mut i32) {
1072 let (two, four) = indices_ordered!(data, 2, 4);
1073 (two, four)
1074 }
1075
1076 #[test]
1079 fn try_indices_ordered_works() {
1080 let mut data = [5, 4, 3, 2, 1];
1081 let slice = data.as_mut_slice();
1082 let (one, two) = try_indices_ordered!(slice, 1, 3).unwrap();
1083 assert_eq!(one, &mut 4);
1084 assert_eq!(two, &mut 2);
1085 *one = 10;
1086 *two = 20;
1087 assert_eq!(data, [5, 10, 3, 20, 1]);
1088 }
1089
1090 #[test]
1091 fn try_indices_ordered_more_than_two_indices() {
1092 let mut data = [5, 4, 3, 2, 1];
1093 let slice = data.as_mut_slice();
1094 let (one, two, three) = try_indices_ordered!(slice, 1, 2, 4).unwrap();
1095 assert_eq!(one, &mut 4);
1096 assert_eq!(two, &mut 3);
1097 assert_eq!(three, &mut 1);
1098 *one = 10;
1099 *two = 20;
1100 *three = 30;
1101 assert_eq!(data, [5, 10, 20, 2, 30]);
1102 }
1103
1104 #[test]
1105 fn try_indices_ordered_duplicate_indices() {
1106 let mut data = [5, 4, 3, 2, 1];
1107 let slice = data.as_mut_slice();
1108 let result = try_indices_ordered!(slice, 3, 3);
1109 assert_eq!(result, Err(TryIndicesOrderedError::InvalidIndex));
1110 }
1111
1112 #[test]
1113 fn try_indices_ordered_out_of_order() {
1114 let mut data = [5, 4, 3, 2, 1];
1115 let slice = data.as_mut_slice();
1116 let result = try_indices_ordered!(slice, 3, 1);
1117 assert_eq!(result, Err(TryIndicesOrderedError::InvalidIndex));
1118 }
1119
1120 #[test]
1121 fn try_indices_ordered_out_of_bounds() {
1122 let mut data = [5, 4, 3, 2, 1];
1123 let slice = data.as_mut_slice();
1124 let result = try_indices_ordered!(slice, 3, 5);
1125 assert_eq!(result, Err(TryIndicesOrderedError::IndexOutOfBounds));
1126 }
1127
1128 #[test]
1129 fn try_indices_ordered_empty_requested_indices() {
1130 let mut data: [i32; 0] = [];
1131 let slice = data.as_mut_slice();
1132 let result = try_indices_ordered!(slice, 3);
1133 assert_eq!(result, Err(TryIndicesOrderedError::IndexOutOfBounds))
1134 }
1135
1136 #[test]
1137 fn try_indices_ordered_can_return_mut_from_scope() {
1138 let mut data = [0, 1, 2, 3, 4];
1139 let (two, four) = try_indices_ordered_scope_helper(&mut data).unwrap();
1140 *two = 200;
1141 *four = 400;
1142 assert_eq!(data[2], 200);
1143 assert_eq!(data[4], 400);
1144 }
1145
1146 fn try_indices_ordered_scope_helper(
1147 data: &mut [i32],
1148 ) -> Result<(&mut i32, &mut i32), TryIndicesOrderedError> {
1149 let (two, four) = try_indices_ordered!(data, 2, 4)?;
1150 Ok((two, four))
1151 }
1152
1153 #[test]
1156 fn indices_slices_works() {
1157 let mut data = [5, 4, 3, 2, 1];
1158 let slice = data.as_mut_slice();
1159 let [mut one, mut two] = indices_slices(slice, [&[1, 3], &[4, 2]]);
1160 assert_eq!(one, [&mut 4, &mut 2]);
1161 assert_eq!(two, [&mut 1, &mut 3]);
1162 *one[0] = 10;
1163 *two[0] = 20;
1164 assert_eq!(data, [5, 10, 3, 2, 20]);
1165 }
1166
1167 #[test]
1168 fn indices_slices_more_than_two_indices() {
1169 let mut data = [5, 4, 3, 2, 1];
1170 let slice = data.as_mut_slice();
1171 let [one, two] = indices_slices(slice, [&mut [3, 1, 2], &mut [0]]);
1172 assert_eq!(one[0], &mut 2);
1173 assert_eq!(one[1], &mut 4);
1174 assert_eq!(one[2], &mut 3);
1175 assert_eq!(one.len(), 3);
1176 assert_eq!(two[0], &mut 5);
1177 assert_eq!(two.len(), 1);
1178 }
1179
1180 #[should_panic]
1181 #[test]
1182 fn indices_slices_duplicate_indices() {
1183 let mut data = [5, 4, 3, 2, 1];
1184 let slice = data.as_mut_slice();
1185 let [_one, _two] = indices_slices(slice, [&mut [3, 3], &[1, 2]]);
1186 }
1187
1188 #[should_panic]
1189 #[test]
1190 fn indices_slices_duplicate_indices_different_slice() {
1191 let mut data = [5, 4, 3, 2, 1];
1192 let slice = data.as_mut_slice();
1193 let [_one, _two] = indices_slices(slice, [&mut [3, 1], &mut [2, 3]]);
1194 }
1195
1196 #[should_panic]
1197 #[test]
1198 fn indices_slices_out_of_bounds() {
1199 let mut data = [5, 4, 3, 2, 1];
1200 let slice = data.as_mut_slice();
1201 let [_one, _two] = indices_slices(slice, [&mut [3, 5], &mut [1, 0]]);
1202 }
1203
1204 #[test]
1205 fn indices_slices_data_not_empty_and_indices_requested_has_indices() {
1206 let mut data: [i32; 1] = [1];
1207 let slice = data.as_mut_slice();
1208 let result = indices_slices(slice, [&mut [0]]);
1209 assert_eq!(result.len(), 1);
1210 assert_eq!(*result[0][0], 1)
1211 }
1212
1213 #[should_panic]
1214 #[test]
1215 fn indices_slices_data_empty_and_indices_requested_has_indices() {
1216 let mut data: [i32; 0] = [];
1217 let slice = data.as_mut_slice();
1218 let _result = indices_slices(slice, [&mut [0]]);
1219 }
1220
1221 #[test]
1222 fn indices_slices_data_not_empty_and_indices_requested_has_no_indices() {
1223 let mut data: [i32; 1] = [1];
1224 let slice = data.as_mut_slice();
1225 let result = indices_slices(slice, [&mut []]);
1226 assert_eq!(result.len(), 1);
1227 assert!(result[0].is_empty())
1228 }
1229
1230 #[test]
1231 fn indices_slices_data_empty_and_indices_requested_has_no_indices() {
1232 let mut data: [i32; 0] = [];
1233 let slice = data.as_mut_slice();
1234 let result = indices_slices(slice, [&mut []]);
1235 assert_eq!(result.len(), 1);
1236 assert!(result[0].is_empty())
1237 }
1238
1239 #[test]
1240 fn indices_slices_data_not_empty_and_indices_requested_empty() {
1241 let mut data: [i32; 1] = [1];
1242 let slice = data.as_mut_slice();
1243 let result = indices_slices(slice, []);
1244 assert_eq!(result.len(), 0);
1245 }
1246
1247 #[test]
1248 fn indices_slices_data_empty_and_indices_requested_empty() {
1249 let mut data: [i32; 0] = [];
1250 let slice = data.as_mut_slice();
1251 let result = indices_slices(slice, []);
1252 assert_eq!(result.len(), 0);
1253 }
1254}
1255
1256#[cfg(test)]
1257mod example_tests {
1258 use crate::indices_slices;
1259
1260 #[test]
1261 fn example1() {
1262 struct Person {
1263 first: String,
1264 last: String,
1265 }
1266 let mut data = [
1267 Person {
1268 first: "John".to_string(),
1269 last: "Doe".to_string(),
1270 },
1271 Person {
1272 first: "Jane".to_string(),
1273 last: "Smith".to_string(),
1274 },
1275 Person {
1276 first: "Alice".to_string(),
1277 last: "Johnson".to_string(),
1278 },
1279 Person {
1280 first: "Bob".to_string(),
1281 last: "Brown".to_string(),
1282 },
1283 Person {
1284 first: "Charlie".to_string(),
1285 last: "White".to_string(),
1286 },
1287 ];
1288 fn modify(data_slice: &mut [Person], index: usize) {
1289 let (four, function_provided, three) = indices!(data_slice, 4, index, 3);
1290 four.last = "Black".to_string();
1291 function_provided.first = "Jack".to_string();
1292 three.last = "Jones".to_string();
1293 }
1294 let slice = data.as_mut_slice();
1295 modify(slice, 1);
1296 assert_eq!(data[4].last, "Black");
1297 assert_eq!(data[1].first, "Jack");
1298 assert_eq!(data[3].last, "Jones");
1299 }
1300
1301 #[test]
1302 fn graph_example() {
1303 struct Node {
1304 index: usize,
1305 visited: usize,
1306 edges: Vec<usize>,
1307 message: String,
1308 }
1309
1310 let mut graph = vec![
1311 Node {
1312 index: 0,
1313 visited: usize::MAX,
1314 edges: vec![1, 2],
1315 message: String::new(),
1316 },
1317 Node {
1318 index: 1,
1319 visited: usize::MAX,
1320 edges: vec![0, 2],
1321 message: String::new(),
1322 },
1323 Node {
1324 index: 2,
1325 visited: usize::MAX,
1326 edges: vec![3],
1327 message: String::new(),
1328 },
1329 Node {
1330 index: 4,
1331 visited: usize::MAX,
1332 edges: vec![1],
1333 message: String::new(),
1334 },
1335 ];
1336
1337 fn traverse_graph(graph: &mut [Node], current: usize, start: usize) -> bool {
1338 if current == start {
1339 return true;
1340 }
1341 let edges = graph[current].edges.clone();
1342 let [mut current_node, mut edge_nodes] = indices_slices(graph, [&[current], &edges]);
1343 for edge_node in edge_nodes.iter_mut() {
1344 current_node[0].visited = current;
1345 edge_node.message.push_str(&format!(
1346 "This is Node `{}` Came from Node `{}`.",
1347 edge_node.index, current_node[0].visited
1348 ));
1349 }
1350 for edge in edges {
1351 if traverse_graph(graph, edge, start) {
1352 return true;
1353 }
1354 }
1355 return false;
1356 }
1357 traverse_graph(&mut *graph, 2, 0);
1358 let answers = [
1359 "This is Node `0` Came from Node `1`.",
1360 "This is Node `1` Came from Node `3`.",
1361 "This is Node `2` Came from Node `1`.",
1362 "This is Node `4` Came from Node `2`.",
1363 ];
1364 for (index, node) in graph.iter().enumerate() {
1365 assert_eq!(&node.message, answers[index]);
1366 }
1367 }
1368}