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, `LittleEndian` 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// --- Macro Helper Functions (Not part of the public API) ---
75
76use crate::fixed::{
77 builder::FixedVecBuilder,
78 traits::{DefaultParams, Storable, Word},
79 BitWidth, FixedVec,
80};
81use dsi_bitstream::prelude::Endianness;
82use num_traits::ToPrimitive;
83
84/// A hidden helper function for the `fixed_vec![...]` macro variant.
85///
86/// This function is not intended for direct use. It is called by the macro
87/// to construct a `FixedVec` from a slice of elements.
88#[doc(hidden)]
89pub fn from_slice<T>(slice: &[T]) -> FixedVec<T, <T as DefaultParams>::W, <T as DefaultParams>::E>
90where
91 T: DefaultParams + Storable<<T as DefaultParams>::W> + ToPrimitive,
92 <T as DefaultParams>::W: Word,
93 <T as DefaultParams>::E: Endianness,
94 FixedVecBuilder<T, <T as DefaultParams>::W, <T as DefaultParams>::E>: Default,
95 // This complex bound is required by the `build` method of the builder.
96 for<'a> dsi_bitstream::impls::BufBitWriter<
97 <T as DefaultParams>::E,
98 dsi_bitstream::impls::MemWordWriterVec<
99 <T as DefaultParams>::W,
100 Vec<<T as DefaultParams>::W>,
101 >,
102 >: dsi_bitstream::prelude::BitWrite<<T as DefaultParams>::E, Error = std::convert::Infallible>,
103{
104 FixedVec::<T, <T as DefaultParams>::W, <T as DefaultParams>::E>::builder()
105 .bit_width(BitWidth::Minimal)
106 .build(slice)
107 .unwrap()
108}
109
110/// A hidden helper function for the `fixed_vec![elem; len]` macro variant.
111///
112/// This function is not intended for direct use. It is called by the macro
113/// to construct a `FixedVec` by repeating an element.
114#[doc(hidden)]
115pub fn from_repetition<T>(
116 elem: T,
117 len: usize,
118) -> FixedVec<T, <T as DefaultParams>::W, <T as DefaultParams>::E>
119where
120 T: DefaultParams + Storable<<T as DefaultParams>::W> + ToPrimitive + Clone,
121 <T as DefaultParams>::W: Word,
122 <T as DefaultParams>::E: Endianness,
123 FixedVecBuilder<T, <T as DefaultParams>::W, <T as DefaultParams>::E>: Default,
124 // This complex bound is required by the `build` method of the builder.
125 for<'a> dsi_bitstream::impls::BufBitWriter<
126 <T as DefaultParams>::E,
127 dsi_bitstream::impls::MemWordWriterVec<
128 <T as DefaultParams>::W,
129 Vec<<T as DefaultParams>::W>,
130 >,
131 >: dsi_bitstream::prelude::BitWrite<<T as DefaultParams>::E, Error = std::convert::Infallible>,
132{
133 let mut v = Vec::new();
134 v.resize(len, elem);
135 FixedVec::<T, <T as DefaultParams>::W, <T as DefaultParams>::E>::builder()
136 .bit_width(BitWidth::Minimal)
137 .build(&v)
138 .unwrap()
139}