Skip to main content

diskann_quantization/bits/
length.rs

1/*
2 * Copyright (c) Microsoft Corporation.
3 * Licensed under the MIT license.
4 */
5
6pub use sealed::Length;
7
8/// A type for dynamically sized slices.
9#[derive(Debug, Clone, Copy)]
10pub struct Dynamic(pub usize);
11
12/// Allow integers to be converted into `Dynamic`.
13impl From<usize> for Dynamic {
14    fn from(value: usize) -> Dynamic {
15        Dynamic(value)
16    }
17}
18
19/// A type for statically sized slices (slices with a length known at compile-time).
20#[derive(Debug, Clone, Copy)]
21pub struct Static<const N: usize>;
22
23// SAFETY: `value` returns the same value for all copies of `self`.
24unsafe impl Length for Dynamic {
25    #[inline(always)]
26    fn value(self) -> usize {
27        self.0
28    }
29}
30
31// SAFETY: `value` always returns the same value.
32unsafe impl<const N: usize> Length for Static<N> {
33    #[inline(always)]
34    fn value(self) -> usize {
35        N
36    }
37}
38
39mod sealed {
40    /// A trait allowing a type to yield a value.
41    ///
42    /// This allows the lengths of `BitSlice`s to be either static or dynamic.
43    ///
44    /// # Safety
45    ///
46    /// Implementations must ensure that `self.value()` always returns the same value for a
47    /// given instance and that this value is preserved across all copies obtained from `self`.
48    pub unsafe trait Length: Copy {
49        fn value(self) -> usize;
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn test_length() {
59        for i in 0..100 {
60            assert_eq!(Dynamic(i).value(), i);
61        }
62
63        assert_eq!(Static::<0>.value(), 0);
64        assert_eq!(Static::<10>.value(), 10);
65        assert_eq!(Static::<20>.value(), 20);
66        assert_eq!(Static::<37>.value(), 37);
67    }
68}