Skip to main content

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}