Hone logo
Hone
Problems

Const Generic Arrays: A Type-Safe Fixed-Size Collection

Const generics in Rust allow you to define generic parameters that are evaluated at compile time, offering powerful ways to create more flexible and efficient code. This challenge focuses on leveraging const generics to implement a type-safe, fixed-size array-like data structure.

Problem Description

Your task is to implement a generic struct called ConstArray<T, const N: usize>. This struct should behave like a fixed-size array of elements of type T, where the size N is determined at compile time.

Key Requirements:

  1. Struct Definition: Define the ConstArray<T, const N: usize> struct. It should internally hold a standard Rust array [T; N] to store its elements.
  2. Creation: Implement a constructor function (e.g., new) that takes an array [T; N] as input and returns a ConstArray.
  3. Element Access: Implement an index method (or overload the [] operator using traits) that allows read-only access to elements by their index. This access should be bounds-checked at runtime.
  4. Mutation: Implement a index_mut method (or overload the [] operator for mutable access) that allows read-write access to elements by their index. This access should also be bounds-checked at runtime.
  5. Length: Implement a len method that returns the size N of the array.
  6. Iterator (Optional but Recommended): Implement an iterator that allows you to iterate over the elements of the ConstArray immutably.

Expected Behavior:

  • The size N of the ConstArray must be a constant value known at compile time.
  • Accessing elements within the valid bounds (0 to N-1) should succeed.
  • Accessing elements outside these bounds should panic.

Edge Cases:

  • Arrays of size 0.
  • Arrays with different element types T.

Examples

Example 1: Basic Usage

let mut my_array: ConstArray<i32, 5> = ConstArray::new([10, 20, 30, 40, 50]);

// Read-only access
assert_eq!(my_array[0], 10);
assert_eq!(my_array[2], 30);

// Mutable access
my_array[1] = 25;
assert_eq!(my_array[1], 25);

// Length
assert_eq!(my_array.len(), 5);

Explanation: A ConstArray of 5 i32s is created. Elements are accessed and modified using their indices. The len() method correctly returns 5.

Example 2: Different Types and Size

let string_array: ConstArray<&str, 3> = ConstArray::new(["hello", "world", "rust"]);

assert_eq!(string_array[0], "hello");
assert_eq!(string_array.len(), 3);

Explanation: Demonstrates that ConstArray can hold different types and that its size is determined by the const generic parameter.

Example 3: Edge Case - Zero Size Array

let empty_array: ConstArray<u8, 0> = ConstArray::new([]);
assert_eq!(empty_array.len(), 0);
// Accessing any index on an empty array should panic
// let _ = empty_array[0]; // This line would panic

Explanation: An empty ConstArray is created. Its length is 0. Attempting to access any index on it would result in a panic, as expected for out-of-bounds access.

Constraints

  • The const generic parameter N must be a usize.
  • The element type T can be any type that implements Clone and Copy for simplicity in the provided examples, but the core implementation should ideally work with any T. For basic index access and mutation, Clone and Copy are not strictly required for the array's internal storage itself, but might be for the constructor if it takes a slice or similar. The problem focuses on the structure and genericity, so assume T: Sized is sufficient for the struct definition.
  • Runtime performance for element access and mutation should be comparable to standard Rust arrays.

Notes

  • You will need to implement std::ops::Index and std::ops::IndexMut traits for the [] operator syntax.
  • For the optional iterator, consider implementing IntoIterator for both mutable and immutable iteration.
  • The new function could also be a direct struct instantiation ConstArray { data: [...] } if preferred, but a new function is often clearer.
  • Consider how to handle initialization for arrays where T does not implement Default or Copy. For this challenge, assume T is Copy or a simple initializer like an array literal is provided to new.
Loading editor...
rust