arbi/
assign.rs

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
/*
Copyright 2024 Owain Davies
SPDX-License-Identifier: Apache-2.0 OR MIT
*/

use crate::Arbi;

/// Assign a value of type `T` to an integer.
///
/// One of the main benefits of assigning and reusing an `Arbi` integer is that
/// it can potentially avoid memory allocation if there's already enough
/// capacity. In contrast, `from` methods typically involve memory allocation
/// (when the resulting integer is not zero).
///
/// # Examples
/// ```
/// use arbi::{Arbi, Assign};
///
/// let mut a = Arbi::with_capacity(10);
/// let mut capacity = a.capacity();
///
/// // From integer
/// a.assign(u128::MAX);
/// assert_eq!(a, u128::MAX);
/// assert_eq!(a.capacity(), capacity); // no memory allocation occurred
///
/// // From float
/// a.assign(f64::MAX);
/// assert_eq!(a, f64::MAX);
/// assert!(a.capacity() > capacity); // memory allocation occured because we
///                                   // needed more capacity to represent the
///                                   // value
/// capacity = a.capacity();
///
/// // From string (no need for the Assign trait)
/// if let Err(e) = a.assign_str_radix("123456789", 10) {
///     panic!("Parsing error: {}", e);
/// }
/// assert_eq!(a, 123456789);
/// assert_eq!(a.capacity(), capacity); // no memory allocation occurred
///
/// // From another Arbi integer
/// let b = Arbi::from(987654321);
/// a.assign(&b);
/// assert_eq!(a.capacity(), capacity); // no memory allocation occurred
/// ```
pub trait Assign<T> {
    #[allow(dead_code)]
    fn assign(&mut self, value: T);
}

/// Copies the contents of the argument `Arbi` integer into this `Arbi` integer.
/// If this `Arbi` integer already has enough capacity to represent `value`,
/// then no memory allocation occurs.
impl Assign<&Arbi> for Arbi {
    fn assign(&mut self, value: &Arbi) {
        if self.vec.capacity() < value.size() {
            self.vec.reserve(value.size() - self.vec.capacity());
        }

        self.vec.clear();
        self.vec.extend_from_slice(&value.vec);

        self.neg = value.neg;
    }
}