• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vigna / dsi-bitstream-rs / 22237719643

20 Feb 2026 07:16PM UTC coverage: 54.824% (-0.5%) from 55.302%
22237719643

push

github

vigna
Cosmetic changes

2108 of 3845 relevant lines covered (54.82%)

3125840.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.19
/src/codes/params.rs
1
/*
2
 * SPDX-FileCopyrightText: 2023 Tommaso Fontana
3
 * SPDX-FileCopyrightText: 2023 Inria
4
 * SPDX-FileCopyrightText: 2023 Sebastiano Vigna
5
 *
6
 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
7
 */
8

9
//! Mechanisms for selecting parameters.
10
//!
11
//! Traits and structures in this file are of no interest for the standard
12
//! user. Their purpose is to provide a systematic way, and in particular
13
//! a default way, to select parameters for parameterized traits
14
//! such as [`GammaReadParam`] and [`GammaWriteParam`].
15
//!
16
//! The traits and structure in this module work closely with the
17
//! bitstream readers and writers in [`impls`](crate::impls), which have an
18
//! additional type parameter `RP`/`WP` that must
19
//! implement marker traits [`ReadParams`] or [`WriteParams`], respectively.
20
//! The type is then used as a selector type to provide blanket implementations
21
//! of parameterless traits in [`codes`](crate::codes) such as [`GammaRead`],
22
//! [`GammaWrite`], [`DeltaRead`], [`DeltaWrite`], and so on.
23
//!
24
//! This module provides default selector types [`DefaultReadParams`] and [`DefaultWriteParams`]
25
//! which are also the default value for the parameter `RP`/`WP` in the bitstream
26
//! readers and writers in [`crate::impls`]. Type-selected blanket implementations
27
//! of all parameterless traits in [`crate::codes`] are provided for the bitstream
28
//! readers and writers in [`impls`](crate::impls). Thus, if you not specify a value for the
29
//! parameter `RP`/`WP`, you will obtain automatically
30
//! the blanket implementations for parameterless traits contained in this module.
31
//!
32
//! However, you can also create new selector types implementing [`ReadParams`]/[`WriteParams`] and
33
//! write blanket implementations for the bitstream readers and writers in [`crate::impls`]
34
//! where `RP`/`WP` is set to your selector types. Then, by specifying your type as value of the
35
//! parameter `RP`/`WP` when creating such readers and writers you will use
36
//! automatically your blanket implementations instead of the ones provided by this module.
37
//!
38
//! Note that the default implementations provided by this module are targeted at
39
//! `u32` read words and `u64` write words. If you use different word sizes,
40
//! you may want to write your own selector types.
41
//!
42
//! # Table peek-bits checks
43
//!
44
//! The `read_*_param` methods in each code module (e.g.,
45
//! [`GammaReadParam::read_gamma_param`]) verify at compile time, via `const {
46
//! }` blocks using [`BitRead::PEEK_BITS`], that the reader's peek word is large
47
//! enough for the table when the corresponding `USE_TABLE` const parameter is
48
//! `true`. These checks are short-circuited when the table is not used, so they
49
//! are only triggered for the tables actually selected.
50

51
use crate::codes::*;
52
use crate::impls::*;
53
use crate::traits::*;
54
use common_traits::*;
55
use core::error::Error;
56
#[cfg(feature = "mem_dbg")]
57
use mem_dbg::{MemDbg, MemSize};
58

59
/// Marker trait for read-parameters selector types.
60
///
61
/// Note that in principle marker traits are not necessary to use
62
/// selector types, but they are useful to avoid that the user specifies
63
/// a nonsensical type, and to document the meaning of type parameters.
64
pub trait ReadParams {}
65

66
/// A selector type for read parameters providing reasonable defaults.
67
///
68
/// If you want to optimize these choices for your architecture, we suggest to
69
/// run the benchmarks in the `benchmarks` directory and write your
70
/// own implementation.
71
#[derive(Debug, Clone)]
72
#[cfg_attr(feature = "mem_dbg", derive(MemDbg, MemSize))]
73
#[cfg_attr(feature = "mem_dbg", mem_size_flat)]
74
pub struct DefaultReadParams;
75
impl ReadParams for DefaultReadParams {}
76

77
macro_rules! impl_default_read_codes {
78
    ($($endianess:ident),*) => {$(
79
        impl<WR: WordRead> GammaRead<$endianess>
80
            for BufBitReader<$endianess, WR, DefaultReadParams>
81
        where
82
            WR:: Word: DoubleType + UpcastableInto<u64>,
83
            <WR::Word as DoubleType>::DoubleType: CastableInto<u64>,
84
        {
85
            #[inline(always)]
86
            fn read_gamma(&mut self) -> Result<u64, Self::Error> {
28,049,409✔
87
                // From our tests on all architectures ɣ codes are faster
88
                // without tables
89
                self.read_gamma_param::<false>()
56,098,818✔
90
            }
91
        }
92

93
        impl<WR: WordRead> DeltaRead<$endianess>
94
            for BufBitReader<$endianess, WR, DefaultReadParams>
95
        where
96
            WR:: Word: DoubleType + UpcastableInto<u64>,
97
            <WR::Word as DoubleType>::DoubleType: CastableInto<u64>,
98
        {
99
            #[inline(always)]
100
            fn read_delta(&mut self) -> Result<u64, Self::Error> {
28,004,457✔
101
                self.read_delta_param::<false, true>()
56,008,914✔
102
            }
103
        }
104

105
        impl<WR: WordRead> OmegaRead<$endianess>
106
            for BufBitReader<$endianess, WR, DefaultReadParams>
107
        where
108
            WR:: Word: DoubleType + UpcastableInto<u64>,
109
            <WR::Word as DoubleType>::DoubleType: CastableInto<u64>,
110
        {
111
            #[inline(always)]
112
            fn read_omega(&mut self) -> Result<u64, Self::Error> {
6,274✔
113
                self.read_omega_param::<true>()
12,548✔
114
            }
115
        }
116

117
        impl<WR: WordRead> ZetaRead<$endianess>
118
            for BufBitReader<$endianess, WR, DefaultReadParams>
119
        where
120
            WR:: Word: DoubleType + UpcastableInto<u64>,
121
            <WR::Word as DoubleType>::DoubleType: CastableInto<u64>,
122
        {
123
            #[inline(always)]
124
            fn read_zeta(&mut self, k: usize) -> Result<u64, Self::Error> {
34,849✔
125
                self.read_zeta_param(k)
104,547✔
126
            }
127

128
            #[inline(always)]
129
            fn read_zeta3(&mut self) -> Result<u64, Self::Error> {
4,357✔
130
                self.read_zeta3_param::<true>()
8,714✔
131
            }
132
        }
133

134
        impl<WR: WordRead> PiRead<$endianess>
135
            for BufBitReader<$endianess, WR, DefaultReadParams>
136
        where
137
            WR:: Word: DoubleType + UpcastableInto<u64>,
138
            <WR::Word as DoubleType>::DoubleType: CastableInto<u64>,
139
        {
140
            #[inline(always)]
141
            fn read_pi(&mut self, k: usize) -> Result<u64, Self::Error> {
40,293✔
142
                self.read_pi_param(k)
120,879✔
143
            }
144

145
            #[inline(always)]
146
            fn read_pi2(&mut self) -> Result<u64, Self::Error> {
6,534✔
147
                self.read_pi2_param::<false>()
13,068✔
148
            }
149
        }
150

151
        impl<E: Error + Send + Sync + 'static, WR: WordRead<Error = E, Word = u64> + WordSeek<Error = E>> GammaRead<$endianess>
152
            for BitReader<$endianess, WR, DefaultReadParams>
153
        where
154
            WR:: Word: DoubleType + UpcastableInto<u64>,
155
            <WR::Word as DoubleType>::DoubleType: CastableInto<u64>,
156
        {
157
            #[inline(always)]
158
            fn read_gamma(&mut self) -> Result<u64, Self::Error> {
1,256✔
159
                // From our tests, the ARM architecture is faster
160
                // without tables for ɣ codes.
161
                self.read_gamma_param::<false>()
2,512✔
162
            }
163
        }
164

165
        impl<E: Error + Send + Sync + 'static, WR: WordRead<Error = E, Word = u64> + WordSeek<Error = E>> DeltaRead<$endianess>
166
            for BitReader<$endianess, WR, DefaultReadParams>
167
        where
168
            WR:: Word: DoubleType + UpcastableInto<u64>,
169
            <WR::Word as DoubleType>::DoubleType: CastableInto<u64>,
170
        {
171
            #[inline(always)]
172
            fn read_delta(&mut self) -> Result<u64, Self::Error> {
×
173
                self.read_delta_param::<false, true>()
×
174
            }
175
        }
176

177
        impl<E: Error + Send + Sync + 'static, WR: WordRead<Error = E, Word = u64> + WordSeek<Error = E>> OmegaRead<$endianess>
178
            for BitReader<$endianess, WR, DefaultReadParams>
179
        where
180
            WR:: Word: DoubleType + UpcastableInto<u64>,
181
            <WR::Word as DoubleType>::DoubleType: CastableInto<u64>,
182
        {
183
            #[inline(always)]
184
            fn read_omega(&mut self) -> Result<u64, Self::Error> {
1,918✔
185
                self.read_omega_param::<true>()
3,836✔
186
            }
187
        }
188

189
        impl<E: Error + Send + Sync + 'static, WR: WordRead<Error = E, Word = u64> + WordSeek<Error = E>> ZetaRead<$endianess>
190
            for BitReader<$endianess, WR, DefaultReadParams>
191
        where
192
            WR:: Word: DoubleType + UpcastableInto<u64>,
193
            <WR::Word as DoubleType>::DoubleType: CastableInto<u64>,
194
        {
195
            #[inline(always)]
196
            fn read_zeta(&mut self, k: usize) -> Result<u64, Self::Error> {
×
197
                self.read_zeta_param(k)
×
198
            }
199

200
            #[inline(always)]
201
            fn read_zeta3(&mut self) -> Result<u64, Self::Error> {
×
202
                self.read_zeta3_param::<true>()
×
203
            }
204
        }
205

206
        impl<E: Error + Send + Sync + 'static, WR: WordRead<Error = E, Word = u64> + WordSeek<Error = E>> PiRead<$endianess>
207
            for BitReader<$endianess, WR, DefaultReadParams>
208
        where
209
            WR:: Word: DoubleType + UpcastableInto<u64>,
210
            <WR::Word as DoubleType>::DoubleType: CastableInto<u64>,
211
        {
212
            #[inline(always)]
213
            fn read_pi(&mut self, k: usize) -> Result<u64, Self::Error> {
×
214
                self.read_pi_param(k)
×
215
            }
216

217
            #[inline(always)]
218
            fn read_pi2(&mut self) -> Result<u64, Self::Error> {
×
219
                self.read_pi2_param::<false>()
×
220
            }
221
        }
222
    )*};
223
}
224

225
impl_default_read_codes! {LittleEndian, BigEndian}
226

227
/// Marker trait for write-parameters selector types.
228
///
229
/// Note that in principle marker traits are not necessary to use
230
/// selector types, but they are useful to avoid that the user specifies
231
/// a nonsensical type, and to document the meaning of type parameters.
232
pub trait WriteParams {}
233

234
/// A selector type for write parameters providing reasonable defaults.
235
///
236
/// If you want to optimize these choices for your architecture, we suggest to
237
/// run the benchmarks in the `benchmarks` directory and write your
238
/// own implementation.
239
#[derive(Debug, Clone)]
240
#[cfg_attr(feature = "mem_dbg", derive(MemDbg, MemSize))]
241
#[cfg_attr(feature = "mem_dbg", mem_size_flat)]
242
pub struct DefaultWriteParams;
243
impl WriteParams for DefaultWriteParams {}
244

245
macro_rules! impl_default_write_codes {
246
    ($($endianess:ident),*) => {$(
247
        impl<WR: WordWrite> GammaWrite<$endianess>
248
            for BufBitWriter<$endianess, WR, DefaultWriteParams>
249
            where u64: CastableInto<WR::Word>,
250
        {
251
            #[inline(always)]
252
            fn write_gamma(&mut self, value: u64) -> Result<usize, Self::Error> {
20,053,786✔
253
                self.write_gamma_param::<true>(value)
60,161,358✔
254
            }
255
        }
256

257
        impl<WR: WordWrite, DC: WriteParams> DeltaWrite<$endianess>
258
            for BufBitWriter<$endianess, WR, DC>
259
            where u64: CastableInto<WR::Word>,
260
        {
261
            #[inline(always)]
262
            fn write_delta(&mut self, value: u64) -> Result<usize, Self::Error> {
20,004,494✔
263
                self.write_delta_param::<true, true>(value)
60,013,482✔
264
            }
265
        }
266

267
        impl<WR: WordWrite, WP: WriteParams> OmegaWrite<$endianess>
268
            for BufBitWriter<$endianess, WR, WP>
269
            where u64: CastableInto<WR::Word>,
270
        {
271
            #[inline(always)]
272
            fn write_omega(&mut self, value: u64) -> Result<usize, Self::Error> {
6,298✔
273
                self.write_omega_param::<true>(value)
18,894✔
274
            }
275
        }
276

277
        impl<WR: WordWrite, DC: WriteParams> ZetaWrite<$endianess>
278
            for BufBitWriter<$endianess, WR, DC>
279
            where u64: CastableInto<WR::Word>,
280
        {
281
            #[inline(always)]
282
            fn write_zeta(&mut self, value: u64, k: usize) -> Result<usize, Self::Error> {
30,815✔
283
                self.write_zeta_param(value, k)
123,260✔
284
            }
285

286
            #[inline(always)]
287
            fn write_zeta3(&mut self, value: u64) -> Result<usize, Self::Error> {
4,379✔
288
                self.write_zeta3_param::<true>(value)
13,137✔
289
            }
290
        }
291

292
        impl<WR: WordWrite, DC: WriteParams> PiWrite<$endianess>
293
            for BufBitWriter<$endianess, WR, DC>
294
            where u64: CastableInto<WR::Word>,
295
        {
296
            #[inline(always)]
297
            fn write_pi(&mut self, value: u64, k: usize) -> Result<usize, Self::Error> {
40,610✔
298
                self.write_pi_param(value, k)
162,440✔
299
            }
300

301
            #[inline(always)]
302
            fn write_pi2(&mut self, value: u64) -> Result<usize, Self::Error> {
6,534✔
303
                self.write_pi2_param::<true>(value)
19,602✔
304
            }
305
        }
306

307
    )*};
308
}
309

310
impl_default_write_codes! {LittleEndian, BigEndian}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc