compressed_intvec/fixed/macros.rs
1//! # Macros for [`FixedVec`]
2
3/// Creates a [`FixedVec`] with default parameters.
4///
5/// This macro simplifies the creation of [`FixedVec`] by using default parameters
6/// ([`usize`] for the storage word, [`LE`](dsi_bitstream::prelude::LE) for byte order) inferred
7/// from the element type. It uses [`BitWidth::Minimal`] for space efficiency.
8///
9/// There are three forms of this macro:
10///
11/// - Create a vector from a list of elements:
12/// ```
13/// # use compressed_intvec::fixed_vec;
14/// let vec = fixed_vec![10u32, 20, 30];
15/// # assert_eq!(vec.len(), 3);
16/// ```
17///
18/// - Create a vector from a repeated element:
19/// ```
20/// # use compressed_intvec::fixed_vec;
21/// let vec = fixed_vec![0i16; 100];
22/// # assert_eq!(vec.len(), 100);
23/// ```
24///
25/// - Create an empty vector (the element type must be specified):
26/// ```
27/// # use compressed_intvec::fixed_vec;
28/// # use compressed_intvec::fixed::UFixedVec;
29/// let vec: UFixedVec<u32> = fixed_vec![];
30/// # assert!(vec.is_empty());
31/// ```
32///
33/// # Examples
34///
35/// ```
36/// use compressed_intvec::fixed_vec;
37/// use compressed_intvec::fixed::UFixedVec;
38///
39/// // Create a vector from a list of elements.
40/// let vec = fixed_vec![10u32, 20, 30];
41/// assert_eq!(vec.len(), 3);
42/// assert_eq!(vec.bit_width(), 5); // 30 requires 5 bits
43///
44/// // Create a vector from a repeated element.
45/// let vec_rep = fixed_vec![0i16; 100];
46/// assert_eq!(vec_rep.len(), 100);
47/// assert_eq!(vec_rep.get(50), Some(0));
48///
49/// // Create an empty vector (type annotation is required).
50/// let empty: UFixedVec<u64> = fixed_vec![];
51/// assert!(empty.is_empty());
52/// ```
53#[macro_export]
54macro_rules! fixed_vec {
55 // Empty vector: `fixed_vec![]`
56 // Requires type annotation from the user.
57 () => {
58 $crate::fixed::FixedVec::builder().build(&[]).unwrap()
59 };
60
61 // From list: `fixed_vec![a, b, c]`
62 ($($elem:expr),+ $(,)?) => {
63 // Delegate to a helper function to avoid repeating complex bounds.
64 $crate::fixed::macros::from_slice(&[$($elem),+])
65 };
66
67 // From element and length: `fixed_vec![elem; len]`
68 ($elem:expr; $len:expr) => {
69 // Delegate to a helper function.
70 $crate::fixed::macros::from_repetition($elem, $len)
71 };
72}
73
74/// Creates a [`FixedVec`] of signed integers (forces `i64`).
75///
76/// This macro is similar to [`fixed_vec!`], but automatically casts all
77/// elements to `i64`. This ensures that ZigZag encoding is used for
78/// signed values.
79///
80/// # Examples
81///
82/// ```
83/// use compressed_intvec::sfixed_vec;
84/// let vec = sfixed_vec![-1, 2, -3];
85/// assert_eq!(vec.get(0), Some(-1));
86/// ```
87#[macro_export]
88macro_rules! sfixed_vec {
89 // Empty case
90 () => {
91 $crate::fixed::FixedVec::<i64, usize, dsi_bitstream::prelude::LE>::builder()
92 .build(&[])
93 .unwrap()
94 };
95
96 // From list: `sfixed_vec![a, b, c]`
97 ($($elem:expr),+ $(,)?) => {
98 $crate::fixed::macros::from_slice(&[$($elem as i64),+])
99 };
100
101 // From element and length: `sfixed_vec![elem; len]`
102 ($elem:expr; $len:expr) => {
103 $crate::fixed::macros::from_repetition($elem as i64, $len)
104 };
105}
106
107// --- Macro Helper Functions (Not part of the public API) ---
108
109use crate::fixed::{
110 builder::FixedVecBuilder,
111 traits::{DefaultParams, Storable, Word},
112 BitWidth, FixedVec,
113};
114use dsi_bitstream::prelude::Endianness;
115use num_traits::ToPrimitive;
116
117/// A hidden helper function for the `fixed_vec![...]` macro variant.
118///
119/// This function is not intended for direct use. It is called by the macro
120/// to construct a `FixedVec` from a slice of elements.
121#[doc(hidden)]
122pub fn from_slice<T>(slice: &[T]) -> FixedVec<T, <T as DefaultParams>::W, <T as DefaultParams>::E>
123where
124 T: DefaultParams + Storable<<T as DefaultParams>::W> + ToPrimitive,
125 <T as DefaultParams>::W: Word,
126 <T as DefaultParams>::E: Endianness,
127 FixedVecBuilder<T, <T as DefaultParams>::W, <T as DefaultParams>::E>: Default,
128 // This complex bound is required by the `build` method of the builder.
129 for<'a> dsi_bitstream::impls::BufBitWriter<
130 <T as DefaultParams>::E,
131 dsi_bitstream::impls::MemWordWriterVec<
132 <T as DefaultParams>::W,
133 Vec<<T as DefaultParams>::W>,
134 >,
135 >: dsi_bitstream::prelude::BitWrite<<T as DefaultParams>::E, Error = std::convert::Infallible>,
136{
137 FixedVec::<T, <T as DefaultParams>::W, <T as DefaultParams>::E>::builder()
138 .bit_width(BitWidth::Minimal)
139 .build(slice)
140 .unwrap()
141}
142
143/// A hidden helper function for the `fixed_vec![elem; len]` macro variant.
144///
145/// This function is not intended for direct use. It is called by the macro
146/// to construct a `FixedVec` by repeating an element.
147#[doc(hidden)]
148pub fn from_repetition<T>(
149 elem: T,
150 len: usize,
151) -> FixedVec<T, <T as DefaultParams>::W, <T as DefaultParams>::E>
152where
153 T: DefaultParams + Storable<<T as DefaultParams>::W> + ToPrimitive + Clone,
154 <T as DefaultParams>::W: Word,
155 <T as DefaultParams>::E: Endianness,
156 FixedVecBuilder<T, <T as DefaultParams>::W, <T as DefaultParams>::E>: Default,
157 // This complex bound is required by the `build` method of the builder.
158 for<'a> dsi_bitstream::impls::BufBitWriter<
159 <T as DefaultParams>::E,
160 dsi_bitstream::impls::MemWordWriterVec<
161 <T as DefaultParams>::W,
162 Vec<<T as DefaultParams>::W>,
163 >,
164 >: dsi_bitstream::prelude::BitWrite<<T as DefaultParams>::E, Error = std::convert::Infallible>,
165{
166 let mut v = Vec::new();
167 v.resize(len, elem);
168 FixedVec::<T, <T as DefaultParams>::W, <T as DefaultParams>::E>::builder()
169 .bit_width(BitWidth::Minimal)
170 .build(&v)
171 .unwrap()
172}