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}