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
/*
* SPDX-FileCopyrightText: 2023 Inria
* SPDX-FileCopyrightText: 2023 Sebastiano Vigna
*
* SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
*/
//! Main traits used in the implementation of succinct and compressed data
//! structures.
pub use *;
use ;
use crateBitVec;
use delegatable_trait;
use PrimitiveAtomicUnsigned;
pub use *;
use autoimpl;
pub use *;
pub use *;
use PrimitiveUnsigned;
pub use *;
pub use *;
/// Error returned by [`TryIntoUnaligned::try_into_unaligned`] when the
/// bit width does not satisfy the constraints for unaligned reads.
;
/// A convenient alias for the unaligned variant of a type that implements
/// [`TryIntoUnaligned`].
pub type Unaligned<T> = Unaligned;
/// A trait for types that can be converted into an unaligned variant
/// that uses branchless [unaligned reads].
///
/// The conversion will fail if the bit width for which unaligned reads are
/// required does not satisfy the constraints for the word type used by the
/// structure or its components.
///
/// Compound types (e.g., [`SignedFunc`]) implement this trait by recursively
/// converting their inner components.
///
/// You can obtain an unaligned variant of a structure just by chaining the
/// [`try_into_unaligned`] method at construction time. Since the unaligned
/// variant of a type can be quite complicated, there is an [`Unaligned`]
/// type alias to refer to it more conveniently. For example,
///
/// ```rust
/// # #[cfg(feature = "rayon")]
/// # fn main() -> anyhow::Result<()> {
/// # use dsi_progress_logger::no_logging;
/// # use sux::func::LcpMmphfInt;
/// # use sux::utils::FromSlice;
/// # use sux::traits::{Unaligned, TryIntoUnaligned};
/// let keys: Vec<u64> = vec![10, 20, 30, 40, 50];
/// let unaligned_func: Unaligned<LcpMmphfInt<u64>> =
/// LcpMmphfInt::try_new(FromSlice::new(&keys), keys.len(), no_logging![])?.try_into_unaligned()?;
/// # Ok(())
/// # }
/// # #[cfg(not(feature = "rayon"))]
/// # fn main() {}
/// ```
///
/// Or, equivalently, without chaining:
///
/// ```rust
/// # #[cfg(feature = "rayon")]
/// # fn main() -> anyhow::Result<()> {
/// # use dsi_progress_logger::no_logging;
/// # use sux::func::LcpMmphfInt;
/// # use sux::utils::FromSlice;
/// # use sux::traits::TryIntoUnaligned;
/// # let keys: Vec<u64> = vec![10, 20, 30, 40, 50];
/// let func: LcpMmphfInt<u64> =
/// LcpMmphfInt::try_new(FromSlice::new(&keys), keys.len(), no_logging![])?;
/// let unaligned_func = func.try_into_unaligned()?;
/// # Ok(())
/// # }
/// # #[cfg(not(feature = "rayon"))]
/// # fn main() {}
/// ```
///
/// [unaligned reads]: crate::bits::BitFieldVec::get_unaligned
/// [`SignedFunc`]: crate::func::SignedFunc
/// [`try_into_unaligned`]: Self::try_into_unaligned
/// A trait for primitive types that can be used in [backends].
///
/// This trait is equivalent to [`PrimitiveUnsigned`], but it has a shorter
/// name and provides constants [`ZERO`] and [`ONE`], which avoid a dependency
/// on the [`num-traits`] crate.
///
/// [`num-traits`]: https://crates.io/crates/num-traits
/// [backends]: crate::traits::Backend
/// [`ZERO`]: Self::ZERO
/// [`ONE`]: Self::ONE
// Note: once we can switch to a more recent num-primitive,
// we will be able to use CONST[0] and CONST[1] to define ZERO and ONE
// and we will be able to remove this macro.
impl_word!;
/// The basic trait defining backends.
///
/// Backends are types used as underlying storage by other types. Backends are
/// made of contiguous sequences of words, and the type of such words is given
/// by the [`Backend::Word`] associated type.
///
/// For example, the type `BitVec<Vec<usize>>` represents a bit vector using a
/// vector of `usize` as its backend.
///
/// This trait provides no methods: access to the underlying data is provided by
/// other traits, such as [`AsRef`] or [`AsMut`]. Moreover, the [`Backend::Word`]
/// associated type is usually bound with an appropriate trait such as [`Word`] or
/// [`PrimitiveAtomicUnsigned`].
///
/// For example, the typical read-only word-based backend `B` for bit vectors
/// and vectors of bit fields satisfies the bound
///
/// ```ignore
/// B: Backend<Word: Word> + AsRef<[B::Word]>
/// ```
///
/// whereas an analogous atomic backend satisfies
///
/// ```ignore
/// B: Backend<Word: PrimitiveAtomicUnsigned<Value: Word>> + AsRef<[B::Word]>
/// ```
///
/// Bit-based backends satisfy also the [`BitLength`] trait, which specifies the
/// number of valid bits in the backend. For example, [`BitVec`]'s only
/// parameter is a word-based backend, but [`BitVec`] itself is a bit-based
/// backend, and thus it implements [`BitLength`] and delegates [`Backend`],
/// [`AsRef`] and [`AsMut`] to its word-based backend.
///
/// Note that *traits* manipulating backends such as [`BitVecOps`] do not use
/// this trait, but are rather parametrized by a word type `W`, and extend
/// traits such as [`AsRef<[W]>`](core::convert::AsRef) as needed.
///
/// However, *types* with a backend need this trait to avoid a redundant
/// specification of the word type in isolation and as part of the backend. If
/// we did not have this trait to specify the word type, we would need to write
/// something like `BitVec<u64, Vec<u64>>`, because there is no way to infer `W`
/// from `Vec<W>` when `Vec<W>` is an opaque type parameter, and in an `impl`
/// block a syntax like `impl<W, B: AsRef<[W]>>` will not compile unless the
/// type (or the implemented trait) contains `W`.
///
/// This trait is delegated by every [rank/select structure] to its backend (an
/// inner field) together with [`AsRef`] and [`BitLength`] so that, for
/// example, a rank/select structure can be used as a backend for another
/// structure without any boilerplate.
///
/// We implement this trait for slices, vectors, and arrays; moreover, we
/// delegate it automatically to references, boxed types, and reference-counted
/// wrappers.
///
/// [rank/select structure]: crate::rank_sel
/// [`AsMut`]: core::convert::AsMut
/// [`Backend::Word`]: Self::Word
/// [`BitVec<Vec<usize>>`]: BitVec
/// [`Word`]: crate::traits::Word
/// [`BitLength`]: crate::traits::BitLength
/// [`BitVec`]: BitVec
/// [`BitVecOps`]: crate::traits::BitVecOps
/// [`PrimitiveAtomicUnsigned`]: PrimitiveAtomicUnsigned