malachite_base/unsigned_vector/select_coordinates.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::num::basic::unsigneds::PrimitiveUnsigned;
10use crate::unsigned_vector::UnsignedVector;
11use crate::vector::{
12 SelectCoordinates, SelectCoordinatesAssign, select_elements, select_elements_in_place,
13};
14
15impl<T: PrimitiveUnsigned> SelectCoordinates for UnsignedVector<T> {
16 type Output = Self;
17
18 /// Selects coordinates of an [`UnsignedVector`] by index, taking the vector by value.
19 ///
20 /// Element $j$ of the result is element `indices[j]` of the original, so the result's dimension
21 /// is the number of indices. The indices may repeat and may appear in any order.
22 ///
23 /// Elements are moved rather than cloned wherever possible: when the indices are strictly
24 /// increasing, nothing is cloned or allocated, and otherwise an element is cloned only once for
25 /// each extra time it is selected.
26 ///
27 /// # Worst-case complexity
28 /// $T(n) = O(n)$
29 ///
30 /// $M(n) = O(n)$
31 ///
32 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()` plus
33 /// `indices.len()`.
34 ///
35 /// # Panics
36 /// Panics if any index is greater than or equal to `self.dimension()`.
37 ///
38 /// # Examples
39 /// ```
40 /// use core::str::FromStr;
41 /// use malachite_base::unsigned_vector::UnsignedVector;
42 /// use malachite_base::vector::SelectCoordinates;
43 ///
44 /// let v = UnsignedVector::<u8>::from_str("(10, 20, 30)").unwrap();
45 /// assert_eq!(
46 /// v.clone().select_coordinates(&[2, 0]).to_string(),
47 /// "(30, 10)"
48 /// );
49 /// assert_eq!(
50 /// v.clone().select_coordinates(&[1, 1, 1]).to_string(),
51 /// "(20, 20, 20)"
52 /// );
53 /// assert_eq!(v.select_coordinates(&[0, 2]).to_string(), "(10, 30)");
54 /// ```
55 #[inline]
56 fn select_coordinates(mut self, indices: &[u64]) -> Self {
57 self.select_coordinates_assign(indices);
58 self
59 }
60}
61
62impl<T: PrimitiveUnsigned> SelectCoordinates for &UnsignedVector<T> {
63 type Output = UnsignedVector<T>;
64
65 /// Selects coordinates of an [`UnsignedVector`] by index, taking the vector by reference.
66 ///
67 /// Element $j$ of the result is element `indices[j]` of the original, so the result's dimension
68 /// is the number of indices. The indices may repeat and may appear in any order.
69 ///
70 /// The selected elements are cloned.
71 ///
72 /// # Worst-case complexity
73 /// $T(n) = O(n)$
74 ///
75 /// $M(n) = O(n)$
76 ///
77 /// where $T$ is time, $M$ is additional memory, and $n$ is `indices.len()`.
78 ///
79 /// # Panics
80 /// Panics if any index is greater than or equal to `self.dimension()`.
81 ///
82 /// # Examples
83 /// ```
84 /// use core::str::FromStr;
85 /// use malachite_base::unsigned_vector::UnsignedVector;
86 /// use malachite_base::vector::SelectCoordinates;
87 ///
88 /// let v = UnsignedVector::<u8>::from_str("(10, 20, 30)").unwrap();
89 /// assert_eq!((&v).select_coordinates(&[2, 0]).to_string(), "(30, 10)");
90 /// assert_eq!(
91 /// (&v).select_coordinates(&[1, 1, 1]).to_string(),
92 /// "(20, 20, 20)"
93 /// );
94 /// assert_eq!((&v).select_coordinates(&[]).to_string(), "()");
95 /// ```
96 #[inline]
97 fn select_coordinates(self, indices: &[u64]) -> UnsignedVector<T> {
98 UnsignedVector {
99 elements: select_elements(&self.elements, indices),
100 }
101 }
102}
103
104impl<T: PrimitiveUnsigned> SelectCoordinatesAssign for UnsignedVector<T> {
105 /// Selects coordinates of an [`UnsignedVector`] by index, in place.
106 ///
107 /// Afterwards, element $j$ of the vector is what element `indices[j]` was before, so its
108 /// dimension is the number of indices. The indices may repeat and may appear in any order.
109 ///
110 /// Elements are moved rather than cloned wherever possible: when the indices are strictly
111 /// increasing, nothing is cloned or allocated, and otherwise an element is cloned only once for
112 /// each extra time it is selected.
113 ///
114 /// # Worst-case complexity
115 /// $T(n) = O(n)$
116 ///
117 /// $M(n) = O(n)$
118 ///
119 /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()` plus
120 /// `indices.len()`.
121 ///
122 /// # Panics
123 /// Panics if any index is greater than or equal to `self.dimension()`.
124 ///
125 /// # Examples
126 /// ```
127 /// use core::str::FromStr;
128 /// use malachite_base::unsigned_vector::UnsignedVector;
129 /// use malachite_base::vector::SelectCoordinatesAssign;
130 ///
131 /// let mut v = UnsignedVector::<u8>::from_str("(10, 20, 30)").unwrap();
132 /// v.select_coordinates_assign(&[2, 0]);
133 /// assert_eq!(v.to_string(), "(30, 10)");
134 /// v.select_coordinates_assign(&[1, 1]);
135 /// assert_eq!(v.to_string(), "(10, 10)");
136 /// ```
137 #[inline]
138 fn select_coordinates_assign(&mut self, indices: &[u64]) {
139 select_elements_in_place(&mut self.elements, indices);
140 }
141}