Skip to main content

malachite_base/unsigned_vector/
mod.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::named::Named;
10use crate::num::basic::unsigneds::PrimitiveUnsigned;
11use crate::num::conversion::traits::ExactFrom;
12use crate::num::logic::traits::SignificantBits;
13use crate::vector::Vector;
14use alloc::vec;
15use alloc::vec::Vec;
16use core::fmt::{self, Debug, Formatter};
17use core::ops::Deref;
18
19/// Implementations of [`Index`](core::ops::Index) and [`IndexMut`](core::ops::IndexMut) for
20/// [`UnsignedVector`].
21pub mod access;
22/// Traits for arithmetic on [`UnsignedVector`]s.
23pub mod arithmetic;
24/// Implementations of [`Ord`] and [`PartialOrd`] for [`ShortlexUnsignedVector`] and
25/// [`ShortlexUnsignedVectorRef`], comparing two vectors by dimension and then lexicographically.
26pub mod comparison;
27/// Functions for converting an [`UnsignedVector`] to and from other types.
28pub mod conversion;
29/// Iterators that generate [`UnsignedVector`]s without repetition.
30pub mod exhaustive;
31/// An implementation of [`Extend`], for appending the elements produced by an iterator to an
32/// [`UnsignedVector`].
33pub mod extend;
34/// Traits for logic and bit manipulation on [`UnsignedVector`]s.
35pub mod logic;
36#[cfg(feature = "random")]
37/// Iterators that generate [`UnsignedVector`]s randomly.
38pub mod random;
39/// Implementations of [`SelectCoordinates`](crate::vector::SelectCoordinates) and
40/// [`SelectCoordinatesAssign`](crate::vector::SelectCoordinatesAssign), for selecting coordinates
41/// of an [`UnsignedVector`] by index.
42pub mod select_coordinates;
43
44/// A vector whose elements are primitive unsigned integers.
45///
46/// Its dimension is the number of elements, and the 0-dimensional vector has none. The field is
47/// public, since every [`Vec`] of `T`s is a valid vector: unlike a polynomial, a vector has no
48/// normal form to maintain, and two vectors are equal exactly when their elements are.
49///
50/// An `UnsignedVector` is serialized as the list of its elements.
51///
52/// # Examples
53/// ```
54/// use malachite_base::unsigned_vector::UnsignedVector;
55/// use malachite_base::vector::Vector;
56///
57/// let v = UnsignedVector {
58///     elements: vec![1u32, 2, 3],
59/// };
60/// assert_eq!(v.dimension(), 3);
61/// assert_eq!(v.to_string(), "(1, 2, 3)");
62/// ```
63#[derive(Clone, Eq, Hash, PartialEq)]
64#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
65#[cfg_attr(feature = "serde", serde(transparent))]
66pub struct UnsignedVector<T: PrimitiveUnsigned> {
67    pub elements: Vec<T>,
68}
69
70impl<T: PrimitiveUnsigned> Vector for UnsignedVector<T> {
71    type Element = T;
72    type ElementOutput<'a>
73        = T
74    where
75        Self: 'a;
76
77    /// Converts a slice to an [`UnsignedVector`], cloning the elements.
78    ///
79    /// The vector's dimension is the length of the slice. Every slice is a valid vector, so this
80    /// cannot fail; the empty slice gives the 0-dimensional vector.
81    ///
82    /// # Worst-case complexity
83    /// $T(n) = O(n)$
84    ///
85    /// $M(n) = O(n)$
86    ///
87    /// where $T$ is time, $M$ is additional memory, and $n$ is `xs.len()`.
88    ///
89    /// # Examples
90    /// ```
91    /// use malachite_base::unsigned_vector::UnsignedVector;
92    /// use malachite_base::vector::Vector;
93    ///
94    /// assert_eq!(
95    ///     UnsignedVector::from_elements(&[1u32, 2]).to_string(),
96    ///     "(1, 2)"
97    /// );
98    /// assert_eq!(UnsignedVector::<u32>::from_elements(&[]).to_string(), "()");
99    /// ```
100    #[inline]
101    fn from_elements(xs: &[T]) -> Self {
102        Self {
103            elements: xs.to_vec(),
104        }
105    }
106
107    /// Converts a [`Vec`] to an [`UnsignedVector`], taking ownership of it.
108    ///
109    /// The vector's dimension is the length of the [`Vec`]. Every [`Vec`] is a valid vector, so
110    /// this cannot fail, and nothing is copied or allocated.
111    ///
112    /// # Worst-case complexity
113    /// Constant time and additional memory.
114    ///
115    /// # Examples
116    /// ```
117    /// use malachite_base::unsigned_vector::UnsignedVector;
118    /// use malachite_base::vector::Vector;
119    ///
120    /// assert_eq!(
121    ///     UnsignedVector::from_owned_elements(vec![1u32, 2]).to_string(),
122    ///     "(1, 2)"
123    /// );
124    /// assert_eq!(
125    ///     UnsignedVector::<u32>::from_owned_elements(Vec::new()).to_string(),
126    ///     "()"
127    /// );
128    /// ```
129    #[inline]
130    fn from_owned_elements(xs: Vec<T>) -> Self {
131        Self { elements: xs }
132    }
133
134    /// Returns the zero vector of a given dimension: a vector of `dimension` zeros.
135    ///
136    /// # Worst-case complexity
137    /// $T(n) = O(n)$
138    ///
139    /// $M(n) = O(n)$
140    ///
141    /// where $T$ is time, $M$ is additional memory, and $n$ is `dimension`.
142    ///
143    /// # Panics
144    /// Panics if `dimension` is greater than [`usize::MAX`].
145    ///
146    /// # Examples
147    /// ```
148    /// use malachite_base::unsigned_vector::UnsignedVector;
149    /// use malachite_base::vector::Vector;
150    ///
151    /// assert_eq!(UnsignedVector::<u8>::zero(3).to_string(), "(0, 0, 0)");
152    /// assert_eq!(UnsignedVector::<u8>::zero(0).to_string(), "()");
153    /// ```
154    ///
155    /// This is equivalent to `_nmod_vec_init` from `nmod_vec.h`, FLINT 3.6.0, followed by
156    /// `_nmod_vec_zero`, since `_nmod_vec_init` leaves the elements uninitialized.
157    #[inline]
158    fn zero(dimension: u64) -> Self {
159        Self {
160            elements: vec![T::ZERO; usize::exact_from(dimension)],
161        }
162    }
163
164    /// Returns the standard basis vector $e_i$ of a given dimension: the vector whose element at
165    /// `index` is 1 and whose other elements are 0.
166    ///
167    /// Indices start at 0, as they do for [`Index`](core::ops::Index).
168    ///
169    /// # Worst-case complexity
170    /// $T(n) = O(n)$
171    ///
172    /// $M(n) = O(n)$
173    ///
174    /// where $T$ is time, $M$ is additional memory, and $n$ is `dimension`.
175    ///
176    /// # Panics
177    /// Panics if `index` is greater than or equal to `dimension`, or if `dimension` is greater than
178    /// [`usize::MAX`].
179    ///
180    /// # Examples
181    /// ```
182    /// use malachite_base::unsigned_vector::UnsignedVector;
183    /// use malachite_base::vector::Vector;
184    ///
185    /// assert_eq!(
186    ///     UnsignedVector::<u8>::standard_basis_vector(3, 1).to_string(),
187    ///     "(0, 1, 0)"
188    /// );
189    /// assert_eq!(
190    ///     UnsignedVector::<u8>::standard_basis_vector(1, 0).to_string(),
191    ///     "(1)"
192    /// );
193    /// ```
194    fn standard_basis_vector(dimension: u64, index: u64) -> Self {
195        assert!(
196            index < dimension,
197            "the index {index} is not less than the dimension {dimension}"
198        );
199        let mut v = Self::zero(dimension);
200        v.elements[usize::exact_from(index)] = T::ONE;
201        v
202    }
203
204    /// Appends an element to the end of an [`UnsignedVector`], increasing its dimension by 1.
205    ///
206    /// # Worst-case complexity
207    /// $T(n) = O(n)$
208    ///
209    /// $M(n) = O(n)$
210    ///
211    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`. The capacity
212    /// grows geometrically, so pushing $n$ elements onto an empty vector takes $O(n)$ time in
213    /// total.
214    ///
215    /// # Examples
216    /// ```
217    /// use core::str::FromStr;
218    /// use malachite_base::unsigned_vector::UnsignedVector;
219    /// use malachite_base::vector::Vector;
220    ///
221    /// let mut v = UnsignedVector::<u8>::from_str("(1, 2)").unwrap();
222    /// v.push(3);
223    /// assert_eq!(v.to_string(), "(1, 2, 3)");
224    ///
225    /// let mut v = UnsignedVector::<u8>::zero(0);
226    /// v.push(5);
227    /// assert_eq!(v.to_string(), "(5)");
228    /// ```
229    #[inline]
230    fn push(&mut self, x: T) {
231        self.elements.push(x);
232    }
233
234    /// Sets the dimension of an [`UnsignedVector`], removing elements from the end if the new
235    /// dimension is smaller, and appending zeros if it is larger.
236    ///
237    /// Reducing the dimension keeps the first `dimension` coordinates: it is the projection onto
238    /// them.
239    ///
240    /// # Worst-case complexity
241    /// $T(n) = O(n)$
242    ///
243    /// $M(n) = O(n)$
244    ///
245    /// where $T$ is time, $M$ is additional memory, and $n$ is the larger of `self.dimension()` and
246    /// `dimension`.
247    ///
248    /// # Panics
249    /// Panics if `dimension` is greater than [`usize::MAX`].
250    ///
251    /// # Examples
252    /// ```
253    /// use core::str::FromStr;
254    /// use malachite_base::unsigned_vector::UnsignedVector;
255    /// use malachite_base::vector::Vector;
256    ///
257    /// let mut v = UnsignedVector::<u8>::from_str("(1, 2, 3)").unwrap();
258    /// v.set_dimension(5);
259    /// assert_eq!(v.to_string(), "(1, 2, 3, 0, 0)");
260    /// v.set_dimension(2);
261    /// assert_eq!(v.to_string(), "(1, 2)");
262    /// v.set_dimension(0);
263    /// assert_eq!(v.to_string(), "()");
264    /// ```
265    #[inline]
266    fn set_dimension(&mut self, dimension: u64) {
267        self.elements.resize(usize::exact_from(dimension), T::ZERO);
268    }
269
270    /// Sets every element of an [`UnsignedVector`] to zero, keeping its dimension.
271    ///
272    /// Afterwards the vector equals [`zero`](Vector::zero) of the same dimension.
273    ///
274    /// # Worst-case complexity
275    /// $T(n) = O(n)$
276    ///
277    /// $M(n) = O(1)$
278    ///
279    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
280    ///
281    /// # Examples
282    /// ```
283    /// use core::str::FromStr;
284    /// use malachite_base::unsigned_vector::UnsignedVector;
285    /// use malachite_base::vector::Vector;
286    ///
287    /// let mut v = UnsignedVector::<u8>::from_str("(1, 2, 3)").unwrap();
288    /// v.set_zero();
289    /// assert_eq!(v.to_string(), "(0, 0, 0)");
290    ///
291    /// let mut v = UnsignedVector::<u8>::from_str("()").unwrap();
292    /// v.set_zero();
293    /// assert_eq!(v.to_string(), "()");
294    /// ```
295    ///
296    /// This is equivalent to `_nmod_vec_zero` from `nmod_vec.h`, FLINT 3.6.0.
297    #[inline]
298    fn set_zero(&mut self) {
299        self.elements.fill(T::ZERO);
300    }
301
302    /// Sorts the elements of an [`UnsignedVector`] in ascending order, keeping its dimension.
303    ///
304    /// Equal elements are indistinguishable, so the sort does not need to be stable, and an
305    /// unstable sort is used.
306    ///
307    /// # Worst-case complexity
308    /// $T(n) = O(n \log n)$
309    ///
310    /// $M(n) = O(1)$
311    ///
312    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`, assuming that
313    /// comparing two elements takes constant time; comparing large elements takes time proportional
314    /// to their sizes.
315    ///
316    /// # Examples
317    /// ```
318    /// use core::str::FromStr;
319    /// use malachite_base::unsigned_vector::UnsignedVector;
320    /// use malachite_base::vector::Vector;
321    ///
322    /// let mut v = UnsignedVector::<u8>::from_str("(3, 1, 2, 1)").unwrap();
323    /// v.sort();
324    /// assert_eq!(v.to_string(), "(1, 1, 2, 3)");
325    /// ```
326    #[inline]
327    fn sort(&mut self) {
328        self.elements.sort_unstable();
329    }
330
331    /// Returns an [`UnsignedVector`]'s elements as a [`Vec`], cloning them.
332    ///
333    /// # Worst-case complexity
334    /// $T(n) = O(n)$
335    ///
336    /// $M(n) = O(n)$
337    ///
338    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
339    ///
340    /// # Examples
341    /// ```
342    /// use core::str::FromStr;
343    /// use malachite_base::unsigned_vector::UnsignedVector;
344    /// use malachite_base::vector::Vector;
345    ///
346    /// let v = UnsignedVector::<u32>::from_str("(1, 2, 3)").unwrap();
347    /// assert_eq!(v.to_elements(), [1, 2, 3]);
348    /// assert!(
349    ///     UnsignedVector::<u32>::from_str("()")
350    ///         .unwrap()
351    ///         .to_elements()
352    ///         .is_empty()
353    /// );
354    /// ```
355    #[inline]
356    fn to_elements(&self) -> Vec<T> {
357        self.elements.clone()
358    }
359
360    /// Returns an [`UnsignedVector`]'s elements as a [`Vec`], taking ownership of the
361    /// [`UnsignedVector`].
362    ///
363    /// Nothing is copied or allocated.
364    ///
365    /// # Worst-case complexity
366    /// Constant time and additional memory.
367    ///
368    /// # Examples
369    /// ```
370    /// use core::str::FromStr;
371    /// use malachite_base::unsigned_vector::UnsignedVector;
372    /// use malachite_base::vector::Vector;
373    ///
374    /// let v = UnsignedVector::<u32>::from_str("(1, 2, 3)").unwrap();
375    /// assert_eq!(v.into_elements(), [1, 2, 3]);
376    /// assert!(
377    ///     UnsignedVector::<u32>::from_str("()")
378    ///         .unwrap()
379    ///         .into_elements()
380    ///         .is_empty()
381    /// );
382    /// ```
383    #[inline]
384    fn into_elements(self) -> Vec<T> {
385        self.elements
386    }
387
388    /// Returns a reference to an [`UnsignedVector`]'s elements, as a slice.
389    ///
390    /// # Worst-case complexity
391    /// Constant time and additional memory.
392    ///
393    /// # Examples
394    /// ```
395    /// use core::str::FromStr;
396    /// use malachite_base::unsigned_vector::UnsignedVector;
397    /// use malachite_base::vector::Vector;
398    ///
399    /// let v = UnsignedVector::<u32>::from_str("(1, 2, 3)").unwrap();
400    /// assert_eq!(v.elements_ref(), [1, 2, 3]);
401    /// // A slice of the elements can be taken directly.
402    /// assert_eq!(&v.elements_ref()[1..], [2, 3]);
403    /// assert!(
404    ///     UnsignedVector::<u32>::from_str("()")
405    ///         .unwrap()
406    ///         .elements_ref()
407    ///         .is_empty()
408    /// );
409    /// ```
410    #[inline]
411    fn elements_ref(&self) -> &[T] {
412        &self.elements
413    }
414
415    /// Returns the dimension of an [`UnsignedVector`]: the number of its elements.
416    ///
417    /// # Worst-case complexity
418    /// Constant time and additional memory.
419    ///
420    /// # Examples
421    /// ```
422    /// use malachite_base::unsigned_vector::UnsignedVector;
423    /// use malachite_base::vector::Vector;
424    ///
425    /// assert_eq!(
426    ///     UnsignedVector {
427    ///         elements: vec![4u32, 5]
428    ///     }
429    ///     .dimension(),
430    ///     2
431    /// );
432    /// assert_eq!(
433    ///     UnsignedVector::<u32> {
434    ///         elements: Vec::new()
435    ///     }
436    ///     .dimension(),
437    ///     0
438    /// );
439    /// ```
440    #[inline]
441    fn dimension(&self) -> u64 {
442        u64::exact_from(self.elements.len())
443    }
444
445    /// Returns the pivot of an [`UnsignedVector`]: its first nonzero element.
446    ///
447    /// This is the element that leads the vector when it is a row of a matrix in echelon form. It
448    /// returns a copy of it, or `None` if every element is zero, which includes the 0-dimensional
449    /// vector.
450    ///
451    /// # Worst-case complexity
452    /// $T(n) = O(n)$
453    ///
454    /// $M(n) = O(1)$
455    ///
456    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
457    ///
458    /// # Examples
459    /// ```
460    /// use core::str::FromStr;
461    /// use malachite_base::unsigned_vector::UnsignedVector;
462    /// use malachite_base::vector::Vector;
463    ///
464    /// assert_eq!(
465    ///     UnsignedVector::<u32>::from_str("(0, 0, 3, 0, 5)")
466    ///         .unwrap()
467    ///         .pivot(),
468    ///     Some(3)
469    /// );
470    /// assert_eq!(
471    ///     UnsignedVector::<u32>::from_str("(0, 0)").unwrap().pivot(),
472    ///     None
473    /// );
474    /// assert_eq!(UnsignedVector::<u32>::from_str("()").unwrap().pivot(), None);
475    /// ```
476    #[inline]
477    fn pivot(&self) -> Option<T> {
478        self.elements.iter().find(|&&x| x != T::ZERO).copied()
479    }
480
481    /// Returns the index of the pivot of an [`UnsignedVector`]: the position of its first nonzero
482    /// element.
483    ///
484    /// Indices start at 0, as they do for [`Index`](core::ops::Index). Returns `None` if every
485    /// element is zero, which includes the 0-dimensional vector. When it returns `Some(i)`,
486    /// [`pivot`](Self::pivot) is the element at `i`.
487    ///
488    /// # Worst-case complexity
489    /// $T(n) = O(n)$
490    ///
491    /// $M(n) = O(1)$
492    ///
493    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
494    ///
495    /// # Examples
496    /// ```
497    /// use core::str::FromStr;
498    /// use malachite_base::unsigned_vector::UnsignedVector;
499    /// use malachite_base::vector::Vector;
500    ///
501    /// assert_eq!(
502    ///     UnsignedVector::<u32>::from_str("(0, 0, 3, 0, 5)")
503    ///         .unwrap()
504    ///         .pivot_index(),
505    ///     Some(2)
506    /// );
507    /// assert_eq!(
508    ///     UnsignedVector::<u32>::from_str("(0, 0)")
509    ///         .unwrap()
510    ///         .pivot_index(),
511    ///     None
512    /// );
513    /// assert_eq!(
514    ///     UnsignedVector::<u32>::from_str("()").unwrap().pivot_index(),
515    ///     None
516    /// );
517    /// ```
518    #[inline]
519    fn pivot_index(&self) -> Option<u64> {
520        self.elements
521            .iter()
522            .position(|&x| x != T::ZERO)
523            .map(u64::exact_from)
524    }
525
526    /// Returns the index of the largest element of an [`UnsignedVector`]: the first one, when
527    /// several are tied.
528    ///
529    /// Indices start at 0, as they do for [`Index`](core::ops::Index). Returns `None` for the
530    /// 0-dimensional vector.
531    ///
532    /// # Worst-case complexity
533    /// $T(n) = O(n)$
534    ///
535    /// $M(n) = O(1)$
536    ///
537    /// where $T$ is time, $M$ is additional memory, and $n$ is the total number of bits of the
538    /// elements.
539    ///
540    /// # Examples
541    /// ```
542    /// use core::str::FromStr;
543    /// use malachite_base::unsigned_vector::UnsignedVector;
544    /// use malachite_base::vector::Vector;
545    ///
546    /// assert_eq!(
547    ///     UnsignedVector::<u8>::from_str("(1, 3, 3, 2)")
548    ///         .unwrap()
549    ///         .height_index(),
550    ///     Some(1)
551    /// );
552    /// assert_eq!(
553    ///     UnsignedVector::<u8>::from_str("(5, 5)")
554    ///         .unwrap()
555    ///         .height_index(),
556    ///     Some(0)
557    /// );
558    /// assert_eq!(
559    ///     UnsignedVector::<u8>::from_str("()").unwrap().height_index(),
560    ///     None
561    /// );
562    /// ```
563    #[inline]
564    fn height_index(&self) -> Option<u64> {
565        // `max_by` returns the last of several equal maxima, so iterating in reverse gives the
566        // first.
567        self.elements
568            .iter()
569            .enumerate()
570            .rev()
571            .max_by(|(_, x), (_, y)| x.cmp(y))
572            .map(|(i, _)| u64::exact_from(i))
573    }
574
575    /// Determines whether every element of an [`UnsignedVector`] is zero.
576    ///
577    /// The 0-dimensional vector, which has no elements, counts as zero.
578    ///
579    /// # Worst-case complexity
580    /// $T(n) = O(n)$
581    ///
582    /// $M(n) = O(1)$
583    ///
584    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
585    ///
586    /// # Examples
587    /// ```
588    /// use core::str::FromStr;
589    /// use malachite_base::unsigned_vector::UnsignedVector;
590    /// use malachite_base::vector::Vector;
591    ///
592    /// assert!(UnsignedVector::<u8>::from_str("(0, 0)").unwrap().is_zero());
593    /// assert!(UnsignedVector::<u8>::from_str("()").unwrap().is_zero());
594    /// assert!(
595    ///     !UnsignedVector::<u8>::from_str("(0, 1, 0)")
596    ///         .unwrap()
597    ///         .is_zero()
598    /// );
599    /// ```
600    #[inline]
601    fn is_zero(&self) -> bool {
602        self.elements.iter().all(|&x| x == T::ZERO)
603    }
604
605    /// Determines whether an [`UnsignedVector`] is a standard basis vector, returning the index of
606    /// its 1 if it is.
607    ///
608    /// A standard basis vector has a single element equal to 1 and every other element 0. Returns
609    /// `None` for every other vector, including the zero vectors and the 0-dimensional vector.
610    ///
611    /// # Worst-case complexity
612    /// $T(n) = O(n)$
613    ///
614    /// $M(n) = O(1)$
615    ///
616    /// where $T$ is time, $M$ is additional memory, and $n$ is `self.dimension()`.
617    ///
618    /// # Examples
619    /// ```
620    /// use core::str::FromStr;
621    /// use malachite_base::unsigned_vector::UnsignedVector;
622    /// use malachite_base::vector::Vector;
623    ///
624    /// assert_eq!(
625    ///     UnsignedVector::<u8>::from_str("(0, 1, 0)")
626    ///         .unwrap()
627    ///         .standard_basis_index(),
628    ///     Some(1)
629    /// );
630    /// assert_eq!(
631    ///     UnsignedVector::<u8>::from_str("(0, 2, 0)")
632    ///         .unwrap()
633    ///         .standard_basis_index(),
634    ///     None
635    /// );
636    /// assert_eq!(
637    ///     UnsignedVector::<u8>::from_str("(1, 0, 1)")
638    ///         .unwrap()
639    ///         .standard_basis_index(),
640    ///     None
641    /// );
642    /// assert_eq!(
643    ///     UnsignedVector::<u8>::from_str("(0, 0)")
644    ///         .unwrap()
645    ///         .standard_basis_index(),
646    ///     None
647    /// );
648    /// ```
649    fn standard_basis_index(&self) -> Option<u64> {
650        let index = self.pivot_index()?;
651        let i = usize::exact_from(index);
652        if self.elements[i] == T::ONE && self.elements[i + 1..].iter().all(|&x| x == T::ZERO) {
653            Some(index)
654        } else {
655            None
656        }
657    }
658
659    /// Returns the number of significant bits of the height of an [`UnsignedVector`], together with
660    /// whether any of its elements is negative.
661    ///
662    /// Since no element is negative, the flag is always `false`. The bit count is the bit length of
663    /// the bitwise or of the elements.
664    ///
665    /// # Worst-case complexity
666    /// $T(n) = O(n)$
667    ///
668    /// $M(n) = O(1)$
669    ///
670    /// where $T$ is time, $M$ is additional memory, and $n$ is the number of elements.
671    ///
672    /// # Examples
673    /// ```
674    /// use core::str::FromStr;
675    /// use malachite_base::unsigned_vector::UnsignedVector;
676    /// use malachite_base::vector::Vector;
677    ///
678    /// assert_eq!(
679    ///     UnsignedVector::<u8>::from_str("(1, 5, 2)")
680    ///         .unwrap()
681    ///         .max_bits(),
682    ///     (3, false)
683    /// );
684    /// assert_eq!(
685    ///     UnsignedVector::<u8>::from_str("()").unwrap().max_bits(),
686    ///     (0, false)
687    /// );
688    /// ```
689    ///
690    /// This is equivalent to `_nmod_vec_max_bits` from `nmod_vec/max_bits.c`, FLINT 3.6.0, together
691    /// with the flag.
692    #[inline]
693    fn max_bits(&self) -> (u64, bool) {
694        let mut or = T::ZERO;
695        for &x in &self.elements {
696            or |= x;
697        }
698        (or.significant_bits(), false)
699    }
700
701    /// Returns the number of significant bits of the sum of the absolute values of the elements of
702    /// an [`UnsignedVector`] (its $\ell^1$ norm), together with the number of significant bits of
703    /// its height.
704    ///
705    /// The sum may not fit in a `T`, so the carries out of the top bit are counted; no wider type
706    /// is needed.
707    ///
708    /// # Worst-case complexity
709    /// $T(n) = O(n)$
710    ///
711    /// $M(n) = O(n)$
712    ///
713    /// where $T$ is time, $M$ is additional memory, and $n$ is the number of elements.
714    ///
715    /// # Examples
716    /// ```
717    /// use core::str::FromStr;
718    /// use malachite_base::unsigned_vector::UnsignedVector;
719    /// use malachite_base::vector::Vector;
720    ///
721    /// assert_eq!(
722    ///     UnsignedVector::<u8>::from_str("(255, 255)")
723    ///         .unwrap()
724    ///         .sum_max_bits(),
725    ///     (9, 8)
726    /// );
727    /// assert_eq!(
728    ///     UnsignedVector::<u8>::from_str("()").unwrap().sum_max_bits(),
729    ///     (0, 0)
730    /// );
731    /// ```
732    fn sum_max_bits(&self) -> (u64, u64) {
733        let mut sum = T::ZERO;
734        let mut carries = 0u64;
735        let mut or = T::ZERO;
736        for &x in &self.elements {
737            let overflow;
738            (sum, overflow) = sum.overflowing_add(x);
739            if overflow {
740                carries += 1;
741            }
742            or |= x;
743        }
744        // The sum is `carries` times 2^W plus `sum`.
745        let sum_bits = if carries == 0 {
746            sum.significant_bits()
747        } else {
748            T::WIDTH + carries.significant_bits()
749        };
750        (sum_bits, or.significant_bits())
751    }
752}
753
754macro_rules! impl_named_unsigned_vector {
755    ($t:ident, $name:expr) => {
756        impl Named for UnsignedVector<$t> {
757            /// The name of this type, with its element type spelled out.
758            const NAME: &'static str = $name;
759        }
760    };
761}
762impl_named_unsigned_vector!(u8, "UnsignedVector<u8>");
763impl_named_unsigned_vector!(u16, "UnsignedVector<u16>");
764impl_named_unsigned_vector!(u32, "UnsignedVector<u32>");
765impl_named_unsigned_vector!(u64, "UnsignedVector<u64>");
766impl_named_unsigned_vector!(u128, "UnsignedVector<u128>");
767impl_named_unsigned_vector!(usize, "UnsignedVector<usize>");
768
769/// `ShortlexUnsignedVector` is a wrapper around an [`UnsignedVector`], taking the
770/// [`UnsignedVector`] by value.
771///
772/// [`UnsignedVector`] does not implement [`Ord`], because no order on vectors is canonical: lex,
773/// graded lex, and the others all have their uses, and the order most natural mathematically,
774/// comparing vectors of the same dimension element by element, is only partial. Wrapping an
775/// [`UnsignedVector`] in a `ShortlexUnsignedVector` provides one total order: vectors are compared
776/// first by dimension and then, in case of a tie, lexicographically, by their elements from first
777/// to last. Its equality agrees with [`UnsignedVector`] equality.
778///
779/// Unlike lexicographic order on [`Vec`]s, this order puts every vector of a smaller dimension
780/// before every vector of a larger one, so that $(5) < (0, 0)$. It is a well-order: any nonempty
781/// set of vectors has a least element, the lexicographically least of those of the smallest
782/// dimension present.
783///
784/// `ShortlexUnsignedVector` owns its value. This is useful in many cases, for example if you want
785/// to use [`UnsignedVector`]s as keys in a [`BTreeMap`](alloc::collections::BTreeMap). In other
786/// situations, it is better to use [`ShortlexUnsignedVectorRef`], which only has a reference to its
787/// value.
788// Serialized as its inner `UnsignedVector`, since the wrapper adds no data of its own.
789#[derive(Clone, Eq, Hash, PartialEq)]
790#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
791#[cfg_attr(feature = "serde", serde(transparent))]
792pub struct ShortlexUnsignedVector<T: PrimitiveUnsigned>(pub UnsignedVector<T>);
793
794/// `ShortlexUnsignedVectorRef` is a wrapper around an [`UnsignedVector`], taking the
795/// [`UnsignedVector`] by reference.
796///
797/// See the [`ShortlexUnsignedVector`] documentation for details.
798#[derive(Clone, Eq, Hash, PartialEq)]
799pub struct ShortlexUnsignedVectorRef<'a, T: PrimitiveUnsigned>(pub &'a UnsignedVector<T>);
800
801impl<T: PrimitiveUnsigned> ShortlexUnsignedVector<T> {
802    /// Borrows a [`ShortlexUnsignedVector`] as a [`ShortlexUnsignedVectorRef`].
803    ///
804    /// # Worst-case complexity
805    /// Constant time and additional memory.
806    ///
807    /// # Examples
808    /// ```
809    /// use core::str::FromStr;
810    /// use malachite_base::unsigned_vector::{
811    ///     ShortlexUnsignedVector, ShortlexUnsignedVectorRef, UnsignedVector,
812    /// };
813    ///
814    /// let v = UnsignedVector::<u32>::from_str("(1, 2, 3)").unwrap();
815    /// let x = ShortlexUnsignedVector(v.clone());
816    /// assert_eq!(x.as_ref(), ShortlexUnsignedVectorRef(&v));
817    /// ```
818    pub const fn as_ref(&self) -> ShortlexUnsignedVectorRef<'_, T> {
819        ShortlexUnsignedVectorRef(&self.0)
820    }
821}
822
823impl<T: PrimitiveUnsigned> Deref for ShortlexUnsignedVector<T> {
824    type Target = UnsignedVector<T>;
825
826    /// Allows a [`ShortlexUnsignedVector`] to dereference to an [`UnsignedVector`].
827    ///
828    /// ```
829    /// use core::str::FromStr;
830    /// use malachite_base::unsigned_vector::{ShortlexUnsignedVector, UnsignedVector};
831    ///
832    /// let v = UnsignedVector::<u32>::from_str("(1, 2, 3)").unwrap();
833    /// let x = ShortlexUnsignedVector(v.clone());
834    /// assert_eq!(*x, v);
835    /// ```
836    fn deref(&self) -> &UnsignedVector<T> {
837        &self.0
838    }
839}
840
841impl<T: PrimitiveUnsigned> Deref for ShortlexUnsignedVectorRef<'_, T> {
842    type Target = UnsignedVector<T>;
843
844    /// Allows a [`ShortlexUnsignedVectorRef`] to dereference to an [`UnsignedVector`].
845    ///
846    /// ```
847    /// use core::str::FromStr;
848    /// use malachite_base::unsigned_vector::{ShortlexUnsignedVectorRef, UnsignedVector};
849    ///
850    /// let v = UnsignedVector::<u32>::from_str("(1, 2, 3)").unwrap();
851    /// let x = ShortlexUnsignedVectorRef(&v);
852    /// assert_eq!(*x, v);
853    /// ```
854    fn deref(&self) -> &UnsignedVector<T> {
855        self.0
856    }
857}
858
859impl<T: PrimitiveUnsigned> Debug for ShortlexUnsignedVector<T> {
860    /// Writes a [`ShortlexUnsignedVector`] as `ShortlexUnsignedVector(` followed by the vector and
861    /// `)`.
862    ///
863    /// # Examples
864    /// ```
865    /// use core::str::FromStr;
866    /// use malachite_base::strings::ToDebugString;
867    /// use malachite_base::unsigned_vector::{ShortlexUnsignedVector, UnsignedVector};
868    ///
869    /// let v = UnsignedVector::<u32>::from_str("(1, 2)").unwrap();
870    /// assert_eq!(
871    ///     ShortlexUnsignedVector(v).to_debug_string(),
872    ///     "ShortlexUnsignedVector((1, 2))"
873    /// );
874    /// ```
875    #[inline]
876    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
877        f.debug_tuple("ShortlexUnsignedVector")
878            .field(&self.0)
879            .finish()
880    }
881}
882
883impl<T: PrimitiveUnsigned> Debug for ShortlexUnsignedVectorRef<'_, T> {
884    /// Writes a [`ShortlexUnsignedVectorRef`] as `ShortlexUnsignedVectorRef(` followed by the
885    /// vector and `)`.
886    ///
887    /// # Examples
888    /// ```
889    /// use core::str::FromStr;
890    /// use malachite_base::strings::ToDebugString;
891    /// use malachite_base::unsigned_vector::{ShortlexUnsignedVectorRef, UnsignedVector};
892    ///
893    /// let v = UnsignedVector::<u32>::from_str("(1, 2)").unwrap();
894    /// assert_eq!(
895    ///     ShortlexUnsignedVectorRef(&v).to_debug_string(),
896    ///     "ShortlexUnsignedVectorRef((1, 2))"
897    /// );
898    /// ```
899    #[inline]
900    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
901        f.debug_tuple("ShortlexUnsignedVectorRef")
902            .field(self.0)
903            .finish()
904    }
905}