From 843758b6c83a7bfa376024065de5ffa405747751 Mon Sep 17 00:00:00 2001 From: Andrei Avram <6795248+andreiavrammsd@users.noreply.github.com> Date: Mon, 26 May 2025 19:52:46 +0300 Subject: [PATCH 1/9] Typo --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 8fb70e8..77c827c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,7 +60,7 @@ impl Vec { pub const fn new() -> Self { assert!(CAPACITY > 0, "CAPACITY must be greater than 0"); - // SAFETY: The elements in the array are not accessed before beign initialized. + // SAFETY: The elements in the array are not accessed before being initialized. let data = unsafe { MaybeUninit::<[MaybeUninit; CAPACITY]>::uninit().assume_init() }; Self { data, length: 0 } } From 6c329e3a53eaf697cee7a04e132c71ad47d05ae7 Mon Sep 17 00:00:00 2001 From: Andrei Avram <6795248+andreiavrammsd@users.noreply.github.com> Date: Mon, 26 May 2025 21:26:30 +0300 Subject: [PATCH 2/9] Implement vec! macro --- src/lib.rs | 3 +++ src/macros.rs | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/macros.rs diff --git a/src/lib.rs b/src/lib.rs index 77c827c..2f17700 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,9 @@ #![deny(missing_docs)] #![doc = include_str!("../README.md")] +#[macro_use] +mod macros; + use core::mem::MaybeUninit; use core::{cmp, error, fmt, slice}; diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 0000000..883ac9f --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,56 @@ +/// Creates new vector. +/// +/// # Forms +/// +/// - `vec![T; CAPACITY]`: Creates a new empty `Vec` with maximum `CAPACITY` elements of type `T`. +/// - `vec![x, y, z]`: Creates a `Vec` initialized with the given values. The capacity is inferred from the number of elements. +/// +/// # Examples +/// +/// Create an empty vector with capacity: +/// +/// ```rust +/// let vec = static_vector::vec![i32; 10]; +/// assert!(vec.is_empty()); +/// ``` +/// +/// Create a vector from elements: +/// +/// ```rust +/// let vec = static_vector::vec![1, 2, 3]; +/// assert_eq!(vec.as_slice(), &[1, 2, 3]); +/// ``` +#[macro_export] +macro_rules! vec { + ($type:ty; $capacity:literal) => { + $crate::Vec::<$type, $capacity>::new() + }; + + ($($value:expr),+ $(,)?) => { + { + let mut vec = $crate::Vec::<_, { [$($value),+].len() }>::new(); + // It's safe to call unwrap because we are initializing the vector with a known number of elements + // (which is also the capacity). + vec.extend_from_slice(&[$($value),+]).unwrap(); + vec + } + }; +} + +#[cfg(test)] +mod tests { + #[test] + fn vec_with_type_and_capacity() { + let vec = vec![i32; 10]; + assert_eq!(vec.capacity(), 10); + assert!(vec.is_empty()); + } + + #[test] + fn vec_with_elements() { + let vec = vec![1, 2, 3]; + assert_eq!(vec.capacity(), 3); + assert_eq!(vec.len(), 3); + assert_eq!(vec.as_slice(), &[1, 2, 3]); + } +} From d2e5f3d44baf4b54d13ff5c2b07020af1c3a4ca3 Mon Sep 17 00:00:00 2001 From: Andrei Avram <6795248+andreiavrammsd@users.noreply.github.com> Date: Mon, 26 May 2025 21:34:24 +0300 Subject: [PATCH 3/9] Document panic --- src/macros.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/macros.rs b/src/macros.rs index 883ac9f..65810f4 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -5,6 +5,10 @@ /// - `vec![T; CAPACITY]`: Creates a new empty `Vec` with maximum `CAPACITY` elements of type `T`. /// - `vec![x, y, z]`: Creates a `Vec` initialized with the given values. The capacity is inferred from the number of elements. /// +/// # Panics +/// +/// Panics if `CAPACITY == 0`. Zero-capacity vectors are not supported. +/// /// # Examples /// /// Create an empty vector with capacity: @@ -46,6 +50,12 @@ mod tests { assert!(vec.is_empty()); } + #[test] + #[should_panic(expected = "CAPACITY must be greater than 0")] + fn vec_with_type_and_capacity_zero() { + let _ = vec![i32; 0]; + } + #[test] fn vec_with_elements() { let vec = vec![1, 2, 3]; From 26842d6adce7dbe730fbd6413ef3551ae4cd722a Mon Sep 17 00:00:00 2001 From: Andrei Avram <6795248+andreiavrammsd@users.noreply.github.com> Date: Tue, 27 May 2025 06:40:29 +0300 Subject: [PATCH 4/9] Create vector with capacity and elements --- src/macros.rs | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index 65810f4..dfb0f4c 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -4,10 +4,12 @@ /// /// - `vec![T; CAPACITY]`: Creates a new empty `Vec` with maximum `CAPACITY` elements of type `T`. /// - `vec![x, y, z]`: Creates a `Vec` initialized with the given values. The capacity is inferred from the number of elements. +/// - `vec![CAPACITY; x, y, z]`: Creates a `Vec` with given `CAPACITY`, initialized with the given values. /// /// # Panics /// -/// Panics if `CAPACITY == 0`. Zero-capacity vectors are not supported. +/// - If `CAPACITY == 0`. Zero-capacity vectors are not supported. +/// - If the number of of elements used to initialize the vector is larger than the given `CAPACITY`. /// /// # Examples /// @@ -24,6 +26,12 @@ /// let vec = static_vector::vec![1, 2, 3]; /// assert_eq!(vec.as_slice(), &[1, 2, 3]); /// ``` +/// +/// Create a vector with a specific capacity and elements: +/// ```rust +/// let vec = static_vector::vec![10; 1, 2, 3]; +/// assert_eq!(vec.as_slice(), &[1, 2, 3]); +/// ``` #[macro_export] macro_rules! vec { ($type:ty; $capacity:literal) => { @@ -33,9 +41,24 @@ macro_rules! vec { ($($value:expr),+ $(,)?) => { { let mut vec = $crate::Vec::<_, { [$($value),+].len() }>::new(); - // It's safe to call unwrap because we are initializing the vector with a known number of elements + // It's safe to call expect because we are initializing the vector with a known number of elements // (which is also the capacity). - vec.extend_from_slice(&[$($value),+]).unwrap(); + vec.extend_from_slice(&[$($value),+]).expect("length matches capacity"); + vec + } + }; + + ($capacity:literal; $($value:expr),+ $(,)?) => { + { + assert!( + $capacity >= { [$($value),+].len() }, + "too many elements ({}) for CAPACITY ({})", { [$($value),+].len() }, $capacity + ); + + let mut vec = $crate::Vec::<_, $capacity>::new(); + // It's safe to call expect because we are initializing the vector with a known number of elements + // (which is less than or equal to the capacity). + vec.extend_from_slice(&[$($value),+]).expect("length matches capacity"); vec } }; @@ -63,4 +86,18 @@ mod tests { assert_eq!(vec.len(), 3); assert_eq!(vec.as_slice(), &[1, 2, 3]); } + + #[test] + fn vec_with_capacity_and_elements() { + let vec = vec![10; 1, 2, 3]; + assert_eq!(vec.capacity(), 10); + assert_eq!(vec.len(), 3); + assert_eq!(vec.as_slice(), &[1, 2, 3]); + } + + #[test] + #[should_panic(expected = "too many elements (3) for CAPACITY (2)")] + fn vec_with_more_elements_than_capacity() { + let _ = vec![2; 1, 2, 3]; + } } From 6b6004c422ba95e9284f8010de2accef1555875c Mon Sep 17 00:00:00 2001 From: Andrei Avram <6795248+andreiavrammsd@users.noreply.github.com> Date: Tue, 27 May 2025 07:07:49 +0300 Subject: [PATCH 5/9] Create vector with capacity and length --- src/macros.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index dfb0f4c..6eedf95 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -2,14 +2,16 @@ /// /// # Forms /// -/// - `vec![T; CAPACITY]`: Creates a new empty `Vec` with maximum `CAPACITY` elements of type `T`. +/// - `vec![T; CAPACITY]`: Creates an empty `Vec` with maximum `CAPACITY` elements of type `T`. /// - `vec![x, y, z]`: Creates a `Vec` initialized with the given values. The capacity is inferred from the number of elements. /// - `vec![CAPACITY; x, y, z]`: Creates a `Vec` with given `CAPACITY`, initialized with the given values. +/// - `vec![T; CAPACITY; LENGTH]`: Creates a `Vec` with maximum `CAPACITY` elements of type `T` and initialized with default `LENGTH` elements. /// /// # Panics /// /// - If `CAPACITY == 0`. Zero-capacity vectors are not supported. -/// - If the number of of elements used to initialize the vector is larger than the given `CAPACITY`. +/// - If the number of elements used to initialize the vector is larger than the given `CAPACITY`. +/// - If the given initial `LENGTH` is larger than the given `CAPACITY`. /// /// # Examples /// @@ -32,6 +34,12 @@ /// let vec = static_vector::vec![10; 1, 2, 3]; /// assert_eq!(vec.as_slice(), &[1, 2, 3]); /// ``` +/// +/// Create a vector with a specific type, capacity, length, and default values: +/// ```rust +/// let vec = static_vector::vec![i32; 10; 3]; +/// assert_eq!(vec.as_slice(), &[0, 0, 0]); +/// ``` #[macro_export] macro_rules! vec { ($type:ty; $capacity:literal) => { @@ -58,7 +66,22 @@ macro_rules! vec { let mut vec = $crate::Vec::<_, $capacity>::new(); // It's safe to call expect because we are initializing the vector with a known number of elements // (which is less than or equal to the capacity). - vec.extend_from_slice(&[$($value),+]).expect("length matches capacity"); + vec.extend_from_slice(&[$($value),+]).expect("length is less than or equal to capacity"); + vec + } + }; + + ($type:ty; $capacity:literal; $length:literal) => { + { + assert!( + $capacity >= $length, + "length ({}) is larger than CAPACITY ({})", $length, $capacity + ); + + let mut vec = $crate::Vec::<$type, $capacity>::new(); + // It's safe to call expect because we are initializing the vector with a known number of elements + // (which is less than or equal to the capacity). + vec.set_len($length).expect("length is less than or equal to capacity"); vec } }; @@ -100,4 +123,26 @@ mod tests { fn vec_with_more_elements_than_capacity() { let _ = vec![2; 1, 2, 3]; } + + #[test] + fn vec_with_capacity_and_length() { + let vec = vec![i32; 10; 3]; + assert_eq!(vec.capacity(), 10); + assert_eq!(vec.len(), 3); + assert_eq!(vec.as_slice(), &[0, 0, 0]); + } + + #[test] + fn vec_with_capacity_and_length_when_length_is_equal_to_capacity() { + let vec = vec![i32; 3; 3]; + assert_eq!(vec.capacity(), 3); + assert_eq!(vec.len(), 3); + assert_eq!(vec.as_slice(), &[0, 0, 0]); + } + + #[test] + #[should_panic(expected = "length (30) is larger than CAPACITY (10)")] + fn vec_with_capacity_and_length_when_length_is_greater_than_capacity() { + let _ = vec![i32; 10; 30]; + } } From bfa28e5cd6a10328381f15dfe42dea67bf1924b4 Mon Sep 17 00:00:00 2001 From: Andrei Avram <6795248+andreiavrammsd@users.noreply.github.com> Date: Tue, 27 May 2025 08:43:57 +0300 Subject: [PATCH 6/9] Implicit panics --- src/macros.rs | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index 6eedf95..82a298a 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -49,8 +49,6 @@ macro_rules! vec { ($($value:expr),+ $(,)?) => { { let mut vec = $crate::Vec::<_, { [$($value),+].len() }>::new(); - // It's safe to call expect because we are initializing the vector with a known number of elements - // (which is also the capacity). vec.extend_from_slice(&[$($value),+]).expect("length matches capacity"); vec } @@ -58,14 +56,7 @@ macro_rules! vec { ($capacity:literal; $($value:expr),+ $(,)?) => { { - assert!( - $capacity >= { [$($value),+].len() }, - "too many elements ({}) for CAPACITY ({})", { [$($value),+].len() }, $capacity - ); - let mut vec = $crate::Vec::<_, $capacity>::new(); - // It's safe to call expect because we are initializing the vector with a known number of elements - // (which is less than or equal to the capacity). vec.extend_from_slice(&[$($value),+]).expect("length is less than or equal to capacity"); vec } @@ -73,14 +64,7 @@ macro_rules! vec { ($type:ty; $capacity:literal; $length:literal) => { { - assert!( - $capacity >= $length, - "length ({}) is larger than CAPACITY ({})", $length, $capacity - ); - let mut vec = $crate::Vec::<$type, $capacity>::new(); - // It's safe to call expect because we are initializing the vector with a known number of elements - // (which is less than or equal to the capacity). vec.set_len($length).expect("length is less than or equal to capacity"); vec } @@ -119,7 +103,7 @@ mod tests { } #[test] - #[should_panic(expected = "too many elements (3) for CAPACITY (2)")] + #[should_panic(expected = "length is less than or equal to capacity: CapacityError")] fn vec_with_more_elements_than_capacity() { let _ = vec![2; 1, 2, 3]; } @@ -141,7 +125,7 @@ mod tests { } #[test] - #[should_panic(expected = "length (30) is larger than CAPACITY (10)")] + #[should_panic(expected = "length is less than or equal to capacity: CapacityError")] fn vec_with_capacity_and_length_when_length_is_greater_than_capacity() { let _ = vec![i32; 10; 30]; } From 021cfa3eb0db5b646e312e0479b2aa55c26e15e9 Mon Sep 17 00:00:00 2001 From: Andrei Avram <6795248+andreiavrammsd@users.noreply.github.com> Date: Tue, 27 May 2025 08:48:25 +0300 Subject: [PATCH 7/9] Detailed macro summary --- src/macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/macros.rs b/src/macros.rs index 82a298a..4b187ee 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,4 +1,4 @@ -/// Creates new vector. +/// Creates a new `static_vector::Vec`, optionally empty, with specific elements, or default-initialized. /// /// # Forms /// From a1978c7e85661df6571a224d6019d52a1df05676 Mon Sep 17 00:00:00 2001 From: Andrei Avram <6795248+andreiavrammsd@users.noreply.github.com> Date: Tue, 27 May 2025 09:05:50 +0300 Subject: [PATCH 8/9] Enhance doc --- src/macros.rs | 55 +++++++++++++++++++++------------------------------ 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index 4b187ee..02a6c13 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,46 +1,37 @@ -/// Creates a new `static_vector::Vec`, optionally empty, with specific elements, or default-initialized. -/// -/// # Forms +#[macro_export] +/// A macro for creating a static vector (`Vec`) with various initialization patterns. /// -/// - `vec![T; CAPACITY]`: Creates an empty `Vec` with maximum `CAPACITY` elements of type `T`. -/// - `vec![x, y, z]`: Creates a `Vec` initialized with the given values. The capacity is inferred from the number of elements. -/// - `vec![CAPACITY; x, y, z]`: Creates a `Vec` with given `CAPACITY`, initialized with the given values. -/// - `vec![T; CAPACITY; LENGTH]`: Creates a `Vec` with maximum `CAPACITY` elements of type `T` and initialized with default `LENGTH` elements. +/// # Usage /// -/// # Panics +/// - `vec![Type; CAPACITY]` +/// - Creates an empty static vector of the specified type and capacity. +/// - Example: `vec![u32; 8]` /// -/// - If `CAPACITY == 0`. Zero-capacity vectors are not supported. -/// - If the number of elements used to initialize the vector is larger than the given `CAPACITY`. -/// - If the given initial `LENGTH` is larger than the given `CAPACITY`. +/// - `vec![value1, value2, ..., valueN]` +/// - Creates a static vector with the given values, inferring the type and capacity from the values. +/// - Example: `vec![1, 2, 3]` /// -/// # Examples +/// - `vec![CAPACITY; value1, value2, ..., valueN]` +/// - Creates a static vector with the specified capacity and initializes it with the given values. +/// - Example: `vec![8; 1, 2, 3]` /// -/// Create an empty vector with capacity: -/// -/// ```rust -/// let vec = static_vector::vec![i32; 10]; -/// assert!(vec.is_empty()); -/// ``` +/// - `vec![Type; CAPACITY; Length]` +/// - Creates a static vector of the specified type and capacity, and sets its length to `Length`. +/// - Example: `vec![u32; 8; 4]` /// -/// Create a vector from elements: +/// # Panics /// -/// ```rust -/// let vec = static_vector::vec![1, 2, 3]; -/// assert_eq!(vec.as_slice(), &[1, 2, 3]); -/// ``` +/// Panics if the specified capacity is zero, or the number of provided values exceeds the capacity, or the requested length is greater than the capacity. /// -/// Create a vector with a specific capacity and elements: -/// ```rust -/// let vec = static_vector::vec![10; 1, 2, 3]; -/// assert_eq!(vec.as_slice(), &[1, 2, 3]); -/// ``` +/// # Examples /// -/// Create a vector with a specific type, capacity, length, and default values: /// ```rust -/// let vec = static_vector::vec![i32; 10; 3]; -/// assert_eq!(vec.as_slice(), &[0, 0, 0]); +/// use static_vector::vec; +/// let vec = vec![u8; 4]; // Empty vector with capacity 4 +/// let vec = vec![1, 2, 3]; // Vector with 3 elements +/// let vec = vec![4; 1, 2]; // Vector with capacity 4, initialized with 2 elements +/// let vec = vec![u16; 8; 5]; // Vector with capacity 8, length set to 5, initialized with zeros /// ``` -#[macro_export] macro_rules! vec { ($type:ty; $capacity:literal) => { $crate::Vec::<$type, $capacity>::new() From cfc0748034e6d94be87dab9389268b44cb34211e Mon Sep 17 00:00:00 2001 From: Andrei Avram <6795248+andreiavrammsd@users.noreply.github.com> Date: Tue, 27 May 2025 09:10:39 +0300 Subject: [PATCH 9/9] Add more scenarios --- src/macros.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index 02a6c13..6b2af3b 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -77,6 +77,14 @@ mod tests { let _ = vec![i32; 0]; } + #[test] + fn vec_with_one_element() { + let vec = vec![999]; + assert_eq!(vec.capacity(), 1); + assert_eq!(vec.len(), 1); + assert_eq!(vec.as_slice(), &[999]); + } + #[test] fn vec_with_elements() { let vec = vec![1, 2, 3]; @@ -108,7 +116,15 @@ mod tests { } #[test] - fn vec_with_capacity_and_length_when_length_is_equal_to_capacity() { + fn vec_with_capacity_and_length_zero() { + let vec = vec![i32; 10; 0]; + assert_eq!(vec.capacity(), 10); + assert!(vec.is_empty()); + assert_eq!(vec.as_slice(), &[]); + } + + #[test] + fn vec_with_capacity_and_length_equal_to_capacity() { let vec = vec![i32; 3; 3]; assert_eq!(vec.capacity(), 3); assert_eq!(vec.len(), 3); @@ -117,7 +133,7 @@ mod tests { #[test] #[should_panic(expected = "length is less than or equal to capacity: CapacityError")] - fn vec_with_capacity_and_length_when_length_is_greater_than_capacity() { + fn vec_with_capacity_and_length_greater_than_capacity() { let _ = vec![i32; 10; 30]; } }