Skip to main content

malachite_nz/integer_polynomial/conversion/
unsigned_polynomial_from_integer_polynomial.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::integer::Integer;
10use crate::integer_polynomial::IntegerPolynomial;
11use alloc::vec::Vec;
12use malachite_base::num::basic::unsigneds::PrimitiveUnsigned;
13use malachite_base::num::conversion::traits::ConvertibleFrom;
14use malachite_base::polynomial::Polynomial;
15use malachite_base::unsigned_polynomial::UnsignedPolynomial;
16
17/// The error returned when an [`IntegerPolynomial`] has a coefficient that is negative or too large
18/// for the coefficient type of the [`UnsignedPolynomial`] it is being converted to.
19#[derive(Clone, Copy, Debug, Eq, PartialEq)]
20pub struct UnsignedPolynomialFromIntegerPolynomialError;
21
22impl<T: PrimitiveUnsigned + for<'a> TryFrom<&'a Integer>> TryFrom<&IntegerPolynomial>
23    for UnsignedPolynomial<T>
24{
25    type Error = UnsignedPolynomialFromIntegerPolynomialError;
26
27    /// Converts an [`IntegerPolynomial`] to an [`UnsignedPolynomial`], taking the
28    /// [`IntegerPolynomial`] by reference and returning an error if any coefficient is negative or
29    /// too large for `T`.
30    ///
31    /// No coefficient is ever wrapped. A successful conversion keeps the degree.
32    ///
33    /// # Worst-case complexity
34    /// $T(n) = O(n)$
35    ///
36    /// $M(n) = O(n)$
37    ///
38    /// where $T$ is time, $M$ is additional memory, and $n$ is the number of coefficients.
39    ///
40    /// # Examples
41    /// See [here](super::unsigned_polynomial_from_integer_polynomial#try_from).
42    fn try_from(p: &IntegerPolynomial) -> Result<Self, Self::Error> {
43        Ok(Self::from_coefficients_asc(
44            p.coefficients
45                .iter()
46                .map(|c| T::try_from(c).map_err(|_| UnsignedPolynomialFromIntegerPolynomialError))
47                .collect::<Result<Vec<T>, _>>()?,
48        ))
49    }
50}
51
52impl<T: PrimitiveUnsigned + for<'a> TryFrom<&'a Integer>> TryFrom<IntegerPolynomial>
53    for UnsignedPolynomial<T>
54{
55    type Error = UnsignedPolynomialFromIntegerPolynomialError;
56
57    /// Converts an [`IntegerPolynomial`] to an [`UnsignedPolynomial`], taking the
58    /// [`IntegerPolynomial`] by value and returning an error if any coefficient is negative or too
59    /// large for `T`.
60    ///
61    /// Taking the polynomial by value saves nothing, since the coefficients are copied into new
62    /// storage either way; this is here so that a conversion can be written without a borrow.
63    ///
64    /// # Worst-case complexity
65    /// $T(n) = O(n)$
66    ///
67    /// $M(n) = O(n)$
68    ///
69    /// where $T$ is time, $M$ is additional memory, and $n$ is the number of coefficients.
70    ///
71    /// # Examples
72    /// See [here](super::unsigned_polynomial_from_integer_polynomial#try_from).
73    #[inline]
74    fn try_from(p: IntegerPolynomial) -> Result<Self, Self::Error> {
75        Self::try_from(&p)
76    }
77}
78
79impl<T: PrimitiveUnsigned + for<'a> ConvertibleFrom<&'a Integer>>
80    ConvertibleFrom<&IntegerPolynomial> for UnsignedPolynomial<T>
81{
82    /// Determines whether an [`IntegerPolynomial`] can be converted to an [`UnsignedPolynomial`]
83    /// (when every coefficient is non-negative and representable as a `T`). Takes the
84    /// [`IntegerPolynomial`] by reference.
85    ///
86    /// Unlike checking whether [`TryFrom`] succeeds, this allocates nothing.
87    ///
88    /// # Worst-case complexity
89    /// $T(n) = O(n)$
90    ///
91    /// $M(n) = O(1)$
92    ///
93    /// where $T$ is time, $M$ is additional memory, and $n$ is the number of coefficients.
94    ///
95    /// # Examples
96    /// See [here](super::unsigned_polynomial_from_integer_polynomial#convertible_from).
97    #[inline]
98    fn convertible_from(p: &IntegerPolynomial) -> bool {
99        p.coefficients.iter().all(|c| T::convertible_from(c))
100    }
101}