malachite_base/num/conversion/string/options/
exhaustive.rs

1// Copyright © 2025 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::bools::exhaustive::exhaustive_bools;
10use crate::num::conversion::string::options::{FromSciStringOptions, SciSizeOptions, ToSciOptions};
11use crate::num::exhaustive::{
12    exhaustive_negative_signeds, primitive_int_increasing_inclusive_range,
13};
14use crate::num::logic::traits::NotAssign;
15use crate::rounding_modes::RoundingMode;
16use crate::rounding_modes::exhaustive::exhaustive_rounding_modes;
17use crate::tuples::exhaustive::{exhaustive_triples, lex_pairs, lex_quadruples_from_single};
18use alloc::boxed::Box;
19
20/// Generates all [`SciSizeOptions`]s.
21///
22/// This struct is created by [`exhaustive_sci_size_options`]; see its documentation for more.
23pub struct ExhaustiveSciSizeOptions {
24    i: u64,
25    even: bool,
26}
27
28impl Iterator for ExhaustiveSciSizeOptions {
29    type Item = SciSizeOptions;
30
31    fn next(&mut self) -> Option<SciSizeOptions> {
32        let out = if self.even {
33            if self.i == 0 {
34                SciSizeOptions::Complete
35            } else {
36                SciSizeOptions::Precision(self.i)
37            }
38        } else {
39            let i = self.i;
40            self.i += 1;
41            SciSizeOptions::Scale(i)
42        };
43        self.even.not_assign();
44        Some(out)
45    }
46}
47
48/// Generates all [`SciSizeOptions`]s.
49///
50/// The output length is $2^{65}$.
51///
52/// # Complexity per iteration
53/// Constant time and additional memory.
54pub const fn exhaustive_sci_size_options() -> ExhaustiveSciSizeOptions {
55    ExhaustiveSciSizeOptions { i: 0, even: true }
56}
57
58/// Generates all [`ToSciOptions`]s.
59///
60/// This struct is created by [`exhaustive_to_sci_options`]; see its documentation for more.
61pub struct ExhaustiveToSciOptions(
62    Box<
63        dyn Iterator<
64            Item = (
65                (u8, SciSizeOptions, i64),
66                (RoundingMode, (bool, bool, bool, bool)),
67            ),
68        >,
69    >,
70);
71
72impl Iterator for ExhaustiveToSciOptions {
73    type Item = ToSciOptions;
74
75    fn next(&mut self) -> Option<ToSciOptions> {
76        let (
77            (base, size_options, neg_exp_threshold),
78            (
79                rounding_mode,
80                (lowercase, e_lowercase, force_exponent_plus_sign, include_trailing_zeros),
81            ),
82        ) = self.0.next()?;
83        Some(ToSciOptions {
84            base,
85            size_options,
86            neg_exp_threshold,
87            rounding_mode,
88            lowercase,
89            e_lowercase,
90            force_exponent_plus_sign,
91            include_trailing_zeros,
92        })
93    }
94}
95
96/// Generates all [`ToSciOptions`]s.
97///
98/// The output length is $2^{133}\times 3 \times 5 \times 7 \approx 1.4335 \times 10^{42}$.
99///
100/// # Complexity per iteration
101/// Constant time and additional memory.
102pub fn exhaustive_to_sci_options() -> ExhaustiveToSciOptions {
103    ExhaustiveToSciOptions(Box::new(lex_pairs(
104        exhaustive_triples(
105            primitive_int_increasing_inclusive_range(2, 36),
106            exhaustive_sci_size_options(),
107            exhaustive_negative_signeds(),
108        ),
109        lex_pairs(
110            exhaustive_rounding_modes(),
111            lex_quadruples_from_single(exhaustive_bools()),
112        ),
113    )))
114}
115
116/// Generates all [`FromSciStringOptions`]s.
117///
118/// This struct is created by [`exhaustive_from_sci_string_options`]; see its documentation for
119/// more.
120pub struct ExhaustiveFromSciStringOptions(Box<dyn Iterator<Item = (u8, RoundingMode)>>);
121
122impl Iterator for ExhaustiveFromSciStringOptions {
123    type Item = FromSciStringOptions;
124
125    fn next(&mut self) -> Option<FromSciStringOptions> {
126        let (base, rounding_mode) = self.0.next()?;
127        Some(FromSciStringOptions {
128            base,
129            rounding_mode,
130        })
131    }
132}
133
134/// Generates all [`FromSciStringOptions`]s.
135///
136/// The output length is 210.
137///
138/// # Complexity per iteration
139/// Constant time and additional memory.
140pub fn exhaustive_from_sci_string_options() -> ExhaustiveFromSciStringOptions {
141    ExhaustiveFromSciStringOptions(Box::new(lex_pairs(
142        primitive_int_increasing_inclusive_range(2, 36),
143        exhaustive_rounding_modes(),
144    )))
145}