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
/*
Copyright 2024 Owain Davies
SPDX-License-Identifier: Apache-2.0 OR MIT
*/
use crate::uints::UnsignedUtilities;
use crate::{Arbi, BitCount, Digit};
use alloc::vec::Vec;
impl Arbi {
/// Maximum capacity for the internal vector of digits.
///
/// [`Vec`] is limited to `isize::MAX` bytes in capacity. A digit has size
/// in bytes `core::mem::size_of::<Digit>()`. The maximum capacity is
/// therefore `isize::MAX / core::mem::size_of::<Digit>()`.
pub const MAX_CAPACITY: usize =
(isize::MAX as usize) / core::mem::size_of::<Digit>();
/// Maximum capacity for the internal vector of digits, in terms of bits.
///
/// This represents the number of bits that can be used to represent the
/// absolute value of the integer when the internal digit vector is at
/// maximum capacity.
///
/// This is `Arbi::MAX_CAPACITY * Digit::BITS`.
pub const MAX_BITS: BitCount =
Self::MAX_CAPACITY as BitCount * Digit::BITS as BitCount;
/// Returns the total number of elements the internal digit vector can hold
/// without reallocating.
///
/// # Examples
/// ```
/// use arbi::{Arbi, Assign};
///
/// let zero = Arbi::zero();
/// assert_eq!(zero.capacity(), 0);
///
/// let mut b = Arbi::with_capacity(10);
/// assert_eq!(b.capacity(), 10);
///
/// b.assign(u64::MAX); // no memory allocation needed
/// assert_eq!(b, u64::MAX);
/// ```
///
/// ## Complexity
/// \\( O(1) \\)
#[inline(always)]
pub fn capacity(&self) -> usize {
self.vec.capacity()
}
/// Return the total number of bits the current capacity can hold to
/// represent the absolute value of this integer.
///
/// # Examples
/// ```
/// use arbi::{Arbi, BitCount, Digit};
///
/// let zero = Arbi::zero();
/// assert_eq!(zero.capacity_bits(), 0);
///
/// let a = Arbi::with_capacity_bits(Digit::BITS as BitCount);
/// assert!(a.capacity_bits() >= Digit::BITS as BitCount);
/// ```
///
/// ## Complexitys
/// \\( O(1) \\)
#[inline(always)]
pub fn capacity_bits(&self) -> BitCount {
self.vec.capacity() as BitCount * Digit::BITS as BitCount
}
/// Construct a new `Arbi` integer with at least the specified capacity, in
/// terms of [`Digit`]s.
///
/// The integer's value will be `0`.
///
/// # Examples
/// ```
/// use arbi::Arbi;
///
/// let a = Arbi::with_capacity(10);
/// assert_eq!(a.capacity(), 10);
/// assert_eq!(a, 0);
/// ```
///
/// Panics if the new capacity exceeds `Arbi::MAX_CAPACITY` digits:
/// ```should_panic
/// use arbi::Arbi;
///
/// let a = Arbi::with_capacity(Arbi::MAX_CAPACITY + 1);
/// ```
///
/// # Panic
/// Panics if the new capacity exceeds `isize::MAX` bytes (or
/// `Arbi::MAX_CAPACITY` digits) or if the allocator reports an allocation
/// failure.
#[inline(always)]
pub fn with_capacity(capacity: usize) -> Self {
Arbi {
vec: Vec::with_capacity(capacity),
neg: false,
}
}
/// Construct a new `Arbi` integer with at least the specified capacity, in
/// terms of bits.
///
/// The integer's value will be `0`.
///
/// # Examples
/// ```
/// use arbi::{Arbi, BitCount, Digit};
///
/// let a = Arbi::with_capacity_bits(Digit::BITS as BitCount - 1);
/// assert_eq!(a.capacity(), 1);
/// assert_eq!(a, 0);
///
/// let a = Arbi::with_capacity_bits(Digit::BITS as BitCount);
/// assert_eq!(a.capacity(), 1);
///
/// let a = Arbi::with_capacity_bits(Digit::BITS as BitCount + 1);
/// assert_eq!(a.capacity(), 2);
/// ```
///
/// Panics if the new capacity in bits exceeds `Arbi::MAX_BITS` bits:
/// ```should_panic
/// use arbi::Arbi;
///
/// // Panics with message: "New capacity exceeds `isize::MAX` bytes".
/// let a = Arbi::with_capacity_bits(Arbi::MAX_BITS + 1);
/// ```
///
/// Note that, in practice, while the theoretical limit for the capacity
/// of a `Vec` in bytes is `isize::MAX`, memory allocation failures
/// typically happen for less.
///
/// # Panic
/// Panics if the new capacity exceeds `isize::MAX` bytes (or
/// `Arbi::MAX_BITS` digits) or if the allocator reports an allocation
/// failure.
#[inline(always)]
pub fn with_capacity_bits(capacity: BitCount) -> Self {
let cap = BitCount::div_ceil_(capacity, Digit::BITS as BitCount);
if cap > Arbi::MAX_CAPACITY as BitCount {
panic!("New capacity exceeds `isize::MAX` bytes");
}
Arbi {
vec: Vec::with_capacity(cap as usize),
neg: false,
}
}
}