Skip to main content

rlst_proc_macro/
lib.rs

1//! Proc Macros for the rlst library
2#![cfg_attr(feature = "strict", deny(warnings))]
3#![warn(missing_docs)]
4
5use proc_macro::TokenStream;
6
7mod dense;
8mod tracing;
9
10/// Allocate a dynamic column-major RLST array.
11///
12/// Syntax is `rlst_dynamic_array!(ItemType, shape_expression)`. An optional alignment expression
13/// follows `|`, as in `rlst_dynamic_array!(f64, [2, 3] | 64)`. The number of dimensions is
14/// inferred from the shape array; elements are initialized with `Default`.
15///
16/// A shape known to have rank zero, such as `[]` or a variable of type `[usize; 0]`,
17/// creates a `ZeroDimArray<ItemType>` containing one scalar. Use `scalar()`,
18/// `scalar_mut()`, and `into_scalar()` to access it; indexed access is unavailable.
19/// Positive ranks produce the existing heap-backed `DynArray` type.
20///
21/// Dispatch takes place where the macro expands. Inside a function generic over
22/// the rank, the result remains `DynArray<ItemType, NDIM>` and rank zero is rejected
23/// at runtime. Generic reduction code can construct a scalar result explicitly
24/// with `ZeroDimArray::from_scalar(value)`.
25///
26/// For the unaligned form, determine the shape rank through the shape expression
27/// or an explicit expected result type. If neither constrains the rank during
28/// dispatch, it is inferred as zero; subsequent uses cannot change that choice.
29/// For example, annotate `let shape: [usize; 2] = Default::default()` rather than
30/// relying on a later use of the resulting array to infer the shape rank.
31/// `DynArray::from_shape` retains the original inference behavior for positive ranks.
32///
33/// # Panics
34///
35/// Panics if an alignment is requested for rank zero, or if an unresolved generic
36/// rank is instantiated with zero.
37#[proc_macro]
38pub fn rlst_dynamic_array(items: TokenStream) -> TokenStream {
39    dense::rlst_dynamic_array_impl(items)
40}
41
42/// Create a stack-backed column-major RLST array.
43///
44/// Syntax is `rlst_static_array!(ItemType, [literal_dimension, ...])`. Dimensions must be integer
45/// literals because their product determines the backing Rust array type at compile time.
46#[proc_macro]
47pub fn rlst_static_array(items: TokenStream) -> TokenStream {
48    dense::rlst_static_array_impl(items)
49}
50
51/// Expand to the type of a stack-backed RLST array.
52///
53/// Syntax is `rlst_static_type!(ItemType, literal_dimension, ...)`, without brackets around the
54/// dimensions. At least one dimension is required.
55#[proc_macro]
56pub fn rlst_static_type(items: TokenStream) -> TokenStream {
57    dense::rlst_static_type_impl(items)
58}
59
60/// Instrument a function with entry, exit, and elapsed-time log messages.
61///
62/// The attribute takes no arguments. Its expansion calls `rlst::rlst_print!`, which emits log
63/// records when RLST's `enable_tracing` feature is enabled and otherwise compiles to a no-op.
64#[proc_macro_attribute]
65pub fn measure_duration(attr: TokenStream, item: TokenStream) -> TokenStream {
66    tracing::measure_duration_impl(attr, item)
67}