1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
//! This crate contains many utilities that are used by the
//! [`malachite-nz`](https://docs.rs/malachite-nz/latest/malachite_nz/) and
//! [`malachite-q`]((https://docs.rs/malachite-q/latest/malachite_q/)) crates. These utilities
//! include
//! - Traits that wrap functions from the standard library, like
//!   [`CheckedAdd`](num::arithmetic::traits::CheckedAdd).
//! - Traits that give extra functionality to primitive types, like
//!   [`Gcd`](num::arithmetic::traits::Gcd), [`FloorSqrt`](num::arithmetic::traits::FloorSqrt), and
//!   [`BitAccess`](num::logic::traits::BitAccess).
//! - Iterator-producing functions that let you generate values for testing. Here's an example of
//!   an iterator that produces all pairs of [`u32`]s:
//!   ```
//!   use malachite_base::num::exhaustive::exhaustive_unsigneds;
//!   use malachite_base::tuples::exhaustive::exhaustive_pairs_from_single;
//!
//!   let mut pairs = exhaustive_pairs_from_single(exhaustive_unsigneds::<u32>());
//!   assert_eq!(
//!       pairs.take(20).collect::<Vec<_>>(),
//!       &[
//!           (0, 0), (0, 1), (1, 0), (1, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 0), (2, 1),
//!           (3, 0), (3, 1), (2, 2), (2, 3), (3, 2), (3, 3), (0, 4), (0, 5), (1, 4), (1, 5)
//!       ]
//!   );
//!   ```
//! - The [`RoundingMode`](rounding_modes::RoundingMode) enum, which allows you to specify the
//!   rounding behavior of various functions.
//! - The [`NiceFloat`](num::float::NiceFloat) wrapper, which provides alternative implementations
//!   of [`Eq`], [`Ord`], and [`Display`](std::fmt::Display) for floating-point values which are in
//!   some ways nicer than the defaults.
//!
//! # Demos and benchmarks
//! This crate comes with a `bin` target that can be used for running demos and benchmarks.
//! - Almost all of the public functions in this crate have an associated demo. Running a demo
//!   shows you a function's behavior on a large number of inputs. For example, to demo the
//!   [`mod_pow`](num::arithmetic::traits::ModPow::mod_pow) function on [`u32`]s, you can use the
//!   following command:
//!   ```text
//!   cargo run --features bin_build --release -- -l 10000 -m exhaustive -d demo_mod_pow_u32
//!   ```
//!   This command uses the `exhaustive` mode, which generates every possible input, generally
//!   starting with the simplest input and progressing to more complex ones. Another mode is
//!   `random`. The `-l` flag specifies how many inputs should be generated.
//! - You can use a similar command to run benchmarks. The following command benchmarks various
//!   GCD algorithms for [`u64`]s:
//!   ```text
//!   cargo run --features bin_build --release -- -l 1000000 -m random -b \
//!       benchmark_gcd_algorithms_u64 -o gcd-bench.gp
//!   ```
//!   This creates a file called gcd-bench.gp. You can use gnuplot to create an SVG from it like
//!   so:
//!   ```text
//!   gnuplot -e "set terminal svg; l \"gcd-bench.gp\"" > gcd-bench.svg
//!   ```
//!
//! The list of available demos and benchmarks is not documented anywhere; you must find them by
//! browsing through
//! [`bin_util/demo_and_bench`](https://github.com/mhogrefe/malachite/tree/master/malachite-base/src/bin_util/demo_and_bench).
//!
//! # Features
//! - `test_build`: A large proportion of the code in this crate is only used for testing. For a
//!   typical user, building this code would result in an unnecessarily long compilation time and
//!   an unnecessarily large binary. Much of it is also used for testing
//!   [`malachite-nz`](https://docs.rs/malachite-nz/latest/malachite_nz/) and
//!   [`malachite-q`](https://docs.rs/malachite-q/latest/malachite_q/), so it can't just be
//!   confined to the `tests` directory. My solution is to only build this code when the
//!   `test_build` feature is enabled. If you want to run unit tests, you must enable `test_build`.
//!   However, doctests don't require it, since they only test the public interface.
//! - `bin_build`: This feature is used to build the code for demos and benchmarks, which also
//!   takes a long time to build. Enabling this feature also enables `test_build`.

#![warn(
    clippy::cast_lossless,
    clippy::explicit_into_iter_loop,
    clippy::explicit_iter_loop,
    clippy::filter_map_next,
    clippy::large_digit_groups,
    clippy::manual_filter_map,
    clippy::manual_find_map,
    clippy::map_flatten,
    clippy::map_unwrap_or,
    clippy::match_same_arms,
    clippy::missing_const_for_fn,
    clippy::mut_mut,
    clippy::needless_borrow,
    clippy::needless_continue,
    clippy::needless_pass_by_value,
    clippy::print_stdout,
    clippy::redundant_closure_for_method_calls,
    clippy::single_match_else,
    clippy::trait_duplication_in_bounds,
    clippy::type_repetition_in_bounds,
    clippy::unused_self
)]
#![allow(
    clippy::cognitive_complexity,
    clippy::float_cmp,
    clippy::many_single_char_names,
    clippy::too_many_arguments,
    clippy::type_complexity,
    clippy::upper_case_acronyms,
    unstable_name_collisions
)]

extern crate itertools;
extern crate rand;
extern crate rand_chacha;
extern crate sha3;

#[cfg(any(feature = "bin_build", feature = "test_build"))]
extern crate clap;
#[cfg(any(feature = "bin_build", feature = "test_build"))]
extern crate gnuplot;
#[cfg(any(feature = "bin_build", feature = "test_build"))]
extern crate time;
#[cfg(feature = "bin_build")]
extern crate walkdir;

// TODO links for malachite-nz and malachite-q

/// The [`Named`](named::Named) trait, for getting a type's name.
#[macro_use]
pub mod named;

#[doc(hidden)]
#[macro_use]
pub mod macros;

/// Functions for working with [`bool`]s.
#[macro_use]
pub mod bools;
/// Functions for working with [`char`]s.
#[macro_use]
pub mod chars;
/// Macros and traits related to comparing values.
pub mod comparison;
/// Functions and adaptors for iterators.
pub mod iterators;
/// [`Never`](nevers::Never), a type that cannot be instantiated.
pub mod nevers;
/// Functions for working with primitive integers and floats.
#[macro_use]
pub mod num;
/// Functions for working with [`Ordering`](std::cmp::Ordering)s.
pub mod options;
/// Functions for working with [`Option`]s.
pub mod orderings;
/// Functions for generating random values.
pub mod random;
/// [`RationalSequence`](rational_sequences::RationalSequence), a type representing a sequence that
/// is finite or eventually repeating, just like the digits of a rational number.
pub mod rational_sequences;
/// [`RoundingMode`](rounding_modes::RoundingMode), an enum used to specify rounding behavior.
pub mod rounding_modes;
/// Functions for working with [`HashSet`](std::collections::HashSet)s and
/// [`BTreeSet`](std::collections::BTreeSet)s.
pub mod sets;
/// Functions for working with slices.
#[macro_use]
pub mod slices;
/// Functions for working with [`String`]s.
pub mod strings;
/// Functions for working with tuples.
pub mod tuples;
/// Unions (sum types). These are essentially generic enums.
///
/// # unwrap
/// ```
/// use malachite_base::unions::UnionFromStrError;
/// use malachite_base::union_struct;
/// use std::fmt::{self, Display, Formatter};
/// use std::str::FromStr;
///
/// union_struct!(
///     (pub(crate)),
///     Union3,
///     Union3<T, T, T>,
///     [A, A, 'A', a],
///     [B, B, 'B', b],
///     [C, C, 'C', c]
/// );
///
/// let mut u: Union3<char, char, char>;
///
/// u = Union3::A('a');
/// assert_eq!(u.unwrap(), 'a');
///
/// u = Union3::B('b');
/// assert_eq!(u.unwrap(), 'b');
///
/// u = Union3::C('c');
/// assert_eq!(u.unwrap(), 'c');
/// ```
///
/// # fmt
/// ```
/// use malachite_base::unions::UnionFromStrError;
/// use malachite_base::union_struct;
/// use std::fmt::{self, Display, Formatter};
/// use std::str::FromStr;
///
/// union_struct!(
///     (pub(crate)),
///     Union3,
///     Union3<T, T, T>,
///     [A, A, 'A', a],
///     [B, B, 'B', b],
///     [C, C, 'C', c]
/// );
///
/// let mut u: Union3<char, u32, bool>;
///
/// u = Union3::A('a');
/// assert_eq!(u.to_string(), "A(a)");
///
/// u = Union3::B(5);
/// assert_eq!(u.to_string(), "B(5)");
///
/// u = Union3::C(false);
/// assert_eq!(u.to_string(), "C(false)");
/// ```
///
/// # from_str
/// ```
/// use malachite_base::unions::UnionFromStrError;
/// use malachite_base::union_struct;
/// use std::fmt::{self, Display, Formatter};
/// use std::str::FromStr;
///
/// union_struct!(
///     (pub(crate)),
///     Union3,
///     Union3<T, T, T>,
///     [A, A, 'A', a],
///     [B, B, 'B', b],
///     [C, C, 'C', c]
/// );
///
/// let u3: Union3<bool, u32, char> = Union3::from_str("B(5)").unwrap();
/// assert_eq!(u3, Union3::B(5));
///
/// let result: Result<Union3<char, u32, bool>, _> = Union3::from_str("xyz");
/// assert_eq!(result, Err(UnionFromStrError::Generic("xyz".to_string())));
///
/// let result: Result<Union3<char, u32, bool>, _> = Union3::from_str("A(ab)");
/// if let Err(UnionFromStrError::Specific(Union3::A(_e))) = result {
/// } else {
///     panic!("wrong error variant")
/// }
/// ```
pub mod unions;
/// Functions for working with [`Vec`]s.
pub mod vecs;

#[cfg(feature = "test_build")]
pub mod test_util;