Sun, 27 Apr 2025 20:29:43 -0500
Fix build with stable rust.
For optimisations, build.rs now automatically sets a nightly cfg flag,
so problems with the nightly feature are avoided. It is still used for
required for additional nightly-only features.
Cargo.lock | file | annotate | diff | comparison | revisions | |
Cargo.toml | file | annotate | diff | comparison | revisions | |
build.rs | file | annotate | diff | comparison | revisions | |
src/bisection_tree/refine.rs | file | annotate | diff | comparison | revisions | |
src/direct_product.rs | file | annotate | diff | comparison | revisions | |
src/lib.rs | file | annotate | diff | comparison | revisions | |
src/linsolve.rs | file | annotate | diff | comparison | revisions | |
src/maputil.rs | file | annotate | diff | comparison | revisions | |
src/metaprogramming.rs | file | annotate | diff | comparison | revisions |
--- a/Cargo.lock Tue Apr 08 13:30:12 2025 -0500 +++ b/Cargo.lock Sun Apr 27 20:29:43 2025 -0500 @@ -4,7 +4,7 @@ [[package]] name = "alg_tools" -version = "0.3.1" +version = "0.3.2" dependencies = [ "anyhow", "colored", @@ -16,6 +16,7 @@ "num-traits", "numeric_literals", "rayon", + "rustc_version", "serde", "serde_json", "simba", @@ -324,6 +325,15 @@ ] [[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] name = "ryu" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -339,6 +349,12 @@ ] [[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] name = "serde" version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index"
--- a/Cargo.toml Tue Apr 08 13:30:12 2025 -0500 +++ b/Cargo.toml Sun Apr 27 20:29:43 2025 -0500 @@ -1,6 +1,6 @@ [package] name = "alg_tools" -version = "0.3.1" +version = "0.3.2" edition = "2021" rust-version = "1.85" authors = ["Tuomo Valkonen <tuomov@iki.fi>"] @@ -40,6 +40,11 @@ debug = true [features] -default = ["nightly"] +default = [] use_custom_thread_pool = [] -nightly = [] # enable for higher-performance implementations of some things +# The nightly feature enables some additional features. +# Nightly-based optimisations are decided automatically by build.rs. +nightly = [] + +[build-dependencies] +rustc_version = "0.4"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/build.rs Sun Apr 27 20:29:43 2025 -0500 @@ -0,0 +1,10 @@ +use rustc_version::{version_meta, Channel}; + +fn main() { + // Tell rust that nightly flag exists + println!("cargo::rustc-check-cfg=cfg(nightly)"); + if version_meta().unwrap().channel == Channel::Nightly { + // … and set it for nightly. + println!("cargo:rustc-cfg=nightly"); + } +}
--- a/src/bisection_tree/refine.rs Tue Apr 08 13:30:12 2025 -0500 +++ b/src/bisection_tree/refine.rs Sun Apr 27 20:29:43 2025 -0500 @@ -364,10 +364,10 @@ let mut container = container_arc.lock().unwrap(); // Safe: we just created arg_b and have a mutable exclusive // reference to self containing it. - #[cfg(feature = "nightly")] + #[cfg(nightly)] unsafe { Arc::get_mut_unchecked(arc_b) } .stage_refine(domain, &mut *container); - #[cfg(not(feature = "nightly"))] + #[cfg(not(nightly))] Arc::get_mut(arc_b).unwrap() .stage_refine(domain, &mut *container);
--- a/src/direct_product.rs Tue Apr 08 13:30:12 2025 -0500 +++ b/src/direct_product.rs Sun Apr 27 20:29:43 2025 -0500 @@ -5,33 +5,38 @@ operations on references. */ -use core::ops::{Mul,MulAssign,Div,DivAssign,Add,AddAssign,Sub,SubAssign,Neg}; -use std::clone::Clone; -use serde::{Serialize, Deserialize}; -use crate::types::{Num, Float}; -use crate::{maybe_lifetime, maybe_ref}; use crate::euclidean::Euclidean; -use crate::instance::{Instance, InstanceMut, Decomposition, DecompositionMut, MyCow}; -use crate::mapping::Space; +use crate::instance::{Decomposition, DecompositionMut, Instance, InstanceMut, MyCow}; use crate::linops::AXPY; use crate::loc::Loc; -use crate::norms::{Norm, PairNorm, NormExponent, Normed, HasDual, L2}; +use crate::mapping::Space; +use crate::norms::{HasDual, Norm, NormExponent, Normed, PairNorm, L2}; +use crate::types::{Float, Num}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use serde::{Deserialize, Serialize}; +use std::clone::Clone; -#[derive(Debug,Clone,Copy,PartialEq,Eq,Serialize,Deserialize)] -pub struct Pair<A, B> (pub A, pub B); +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub struct Pair<A, B>(pub A, pub B); -impl<A, B> Pair<A,B> { - pub fn new(a : A, b : B) -> Pair<A,B> { Pair(a, b) } +impl<A, B> Pair<A, B> { + pub fn new(a: A, b: B) -> Pair<A, B> { + Pair(a, b) + } } -impl<A, B> From<(A,B)> for Pair<A,B> { +impl<A, B> From<(A, B)> for Pair<A, B> { #[inline] - fn from((a, b) : (A, B)) -> Pair<A,B> { Pair(a, b) } + fn from((a, b): (A, B)) -> Pair<A, B> { + Pair(a, b) + } } -impl<A, B> From<Pair<A,B>> for (A,B) { +impl<A, B> From<Pair<A, B>> for (A, B) { #[inline] - fn from(Pair(a, b) : Pair<A, B>) -> (A,B) { (a, b) } + fn from(Pair(a, b): Pair<A, B>) -> (A, B) { + (a, b) + } } macro_rules! impl_binop { @@ -152,16 +157,18 @@ macro_rules! impl_scalar_assignop { (($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => { - impl<'r> $trait<$field> - for Pair<$a, $b> - where $a: $trait<$field>, $b: $trait<$field> { + impl<'r> $trait<$field> for Pair<$a, $b> + where + $a: $trait<$field>, + $b: $trait<$field>, + { #[inline] - fn $fn(&mut self, a : $field) -> () { + fn $fn(&mut self, a: $field) -> () { self.0.$fn(a); self.1.$fn(a); } } - } + }; } macro_rules! impl_unaryop { @@ -241,24 +248,28 @@ impl<A, B, F> Euclidean<F> for Pair<A, B> where - A : Euclidean<F>, - B : Euclidean<F>, - F : Float, - PairOutput<F, A, B> : Euclidean<F>, - Self : Sized - + Mul<F, Output=PairOutput<F, A, B>> + MulAssign<F> - + Div<F, Output=PairOutput<F, A, B>> + DivAssign<F> - + Add<Self, Output=PairOutput<F, A, B>> - + Sub<Self, Output=PairOutput<F, A, B>> - + for<'b> Add<&'b Self, Output=PairOutput<F, A, B>> - + for<'b> Sub<&'b Self, Output=PairOutput<F, A, B>> - + AddAssign<Self> + for<'b> AddAssign<&'b Self> - + SubAssign<Self> + for<'b> SubAssign<&'b Self> - + Neg<Output=PairOutput<F, A, B>> + A: Euclidean<F>, + B: Euclidean<F>, + F: Float, + PairOutput<F, A, B>: Euclidean<F>, + Self: Sized + + Mul<F, Output = PairOutput<F, A, B>> + + MulAssign<F> + + Div<F, Output = PairOutput<F, A, B>> + + DivAssign<F> + + Add<Self, Output = PairOutput<F, A, B>> + + Sub<Self, Output = PairOutput<F, A, B>> + + for<'b> Add<&'b Self, Output = PairOutput<F, A, B>> + + for<'b> Sub<&'b Self, Output = PairOutput<F, A, B>> + + AddAssign<Self> + + for<'b> AddAssign<&'b Self> + + SubAssign<Self> + + for<'b> SubAssign<&'b Self> + + Neg<Output = PairOutput<F, A, B>>, { type Output = PairOutput<F, A, B>; - fn dot<I : Instance<Self>>(&self, other : I) -> F { + fn dot<I: Instance<Self>>(&self, other: I) -> F { let Pair(u, v) = other.decompose(); self.0.dot(u) + self.1.dot(v) } @@ -267,7 +278,7 @@ self.0.norm2_squared() + self.1.norm2_squared() } - fn dist2_squared<I : Instance<Self>>(&self, other : I) -> F { + fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F { let Pair(u, v) = other.decompose(); self.0.dist2_squared(u) + self.1.dist2_squared(v) } @@ -275,31 +286,30 @@ impl<F, A, B, U, V> AXPY<F, Pair<U, V>> for Pair<A, B> where - U : Space, - V : Space, - A : AXPY<F, U>, - B : AXPY<F, V>, - F : Num, - Self : MulAssign<F>, - Pair<A, B> : MulAssign<F>, - Pair<A::Owned, B::Owned> : AXPY<F, Pair<U, V>>, + U: Space, + V: Space, + A: AXPY<F, U>, + B: AXPY<F, V>, + F: Num, + Self: MulAssign<F>, + Pair<A, B>: MulAssign<F>, + Pair<A::Owned, B::Owned>: AXPY<F, Pair<U, V>>, { - type Owned = Pair<A::Owned, B::Owned>; - fn axpy<I : Instance<Pair<U,V>>>(&mut self, α : F, x : I, β : F) { + fn axpy<I: Instance<Pair<U, V>>>(&mut self, α: F, x: I, β: F) { let Pair(u, v) = x.decompose(); self.0.axpy(α, u, β); self.1.axpy(α, v, β); } - fn copy_from<I : Instance<Pair<U,V>>>(&mut self, x : I) { + fn copy_from<I: Instance<Pair<U, V>>>(&mut self, x: I) { let Pair(u, v) = x.decompose(); self.0.copy_from(u); self.1.copy_from(v); } - fn scale_from<I : Instance<Pair<U,V>>>(&mut self, α : F, x : I) { + fn scale_from<I: Instance<Pair<U, V>>>(&mut self, α: F, x: I) { let Pair(u, v) = x.decompose(); self.0.scale_from(α, u); self.1.scale_from(α, v); @@ -321,52 +331,64 @@ #[derive(Copy, Clone, Debug)] pub struct PairDecomposition<D, Q>(D, Q); -impl<A : Space, B : Space> Space for Pair<A, B> { +impl<A: Space, B: Space> Space for Pair<A, B> { type Decomp = PairDecomposition<A::Decomp, B::Decomp>; } -impl<A, B, D, Q> Decomposition<Pair<A, B>> for PairDecomposition<D,Q> +impl<A, B, D, Q> Decomposition<Pair<A, B>> for PairDecomposition<D, Q> where - A : Space, - B : Space, - D : Decomposition<A>, - Q : Decomposition<B>, + A: Space, + B: Space, + D: Decomposition<A>, + Q: Decomposition<B>, { - type Decomposition<'b> = Pair<D::Decomposition<'b>, Q::Decomposition<'b>> where Pair<A, B> : 'b; - type Reference<'b> = Pair<D::Reference<'b>, Q::Reference<'b>> where Pair<A, B> : 'b; + type Decomposition<'b> + = Pair<D::Decomposition<'b>, Q::Decomposition<'b>> + where + Pair<A, B>: 'b; + type Reference<'b> + = Pair<D::Reference<'b>, Q::Reference<'b>> + where + Pair<A, B>: 'b; #[inline] - fn lift<'b>(Pair(u, v) : Self::Reference<'b>) -> Self::Decomposition<'b> { + fn lift<'b>(Pair(u, v): Self::Reference<'b>) -> Self::Decomposition<'b> { Pair(D::lift(u), Q::lift(v)) } } impl<A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for Pair<U, V> where - A : Space, - B : Space, - D : Decomposition<A>, - Q : Decomposition<B>, - U : Instance<A, D>, - V : Instance<B, Q>, + A: Space, + B: Space, + D: Decomposition<A>, + Q: Decomposition<B>, + U: Instance<A, D>, + V: Instance<B, Q>, { #[inline] - fn decompose<'b>(self) - -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b> - where Self : 'b, Pair<A, B> : 'b + fn decompose<'b>( + self, + ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b> + where + Self: 'b, + Pair<A, B>: 'b, { Pair(self.0.decompose(), self.1.decompose()) } #[inline] - fn ref_instance(&self) - -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_> - { + fn ref_instance( + &self, + ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_> { Pair(self.0.ref_instance(), self.1.ref_instance()) } #[inline] - fn cow<'b>(self) -> MyCow<'b, Pair<A, B>> where Self : 'b{ + fn cow<'b>(self) -> MyCow<'b, Pair<A, B>> + where + Self: 'b, + { MyCow::Owned(Pair(self.0.own(), self.1.own())) } @@ -376,35 +398,43 @@ } } - impl<'a, A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for &'a Pair<U, V> where - A : Space, - B : Space, - D : Decomposition<A>, - Q : Decomposition<B>, - U : Instance<A, D>, - V : Instance<B, Q>, - &'a U : Instance<A, D>, - &'a V : Instance<B, Q>, + A: Space, + B: Space, + D: Decomposition<A>, + Q: Decomposition<B>, + U: Instance<A, D>, + V: Instance<B, Q>, + &'a U: Instance<A, D>, + &'a V: Instance<B, Q>, { #[inline] - fn decompose<'b>(self) - -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b> - where Self : 'b, Pair<A, B> : 'b + fn decompose<'b>( + self, + ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b> + where + Self: 'b, + Pair<A, B>: 'b, { - Pair(D::lift(self.0.ref_instance()), Q::lift(self.1.ref_instance())) + Pair( + D::lift(self.0.ref_instance()), + Q::lift(self.1.ref_instance()), + ) } #[inline] - fn ref_instance(&self) - -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_> - { + fn ref_instance( + &self, + ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_> { Pair(self.0.ref_instance(), self.1.ref_instance()) } #[inline] - fn cow<'b>(self) -> MyCow<'b, Pair<A, B>> where Self : 'b { + fn cow<'b>(self) -> MyCow<'b, Pair<A, B>> + where + Self: 'b, + { MyCow::Owned(self.own()) } @@ -413,75 +443,74 @@ let Pair(ref u, ref v) = self; Pair(u.own(), v.own()) } - } -impl<A, B, D, Q> DecompositionMut<Pair<A, B>> for PairDecomposition<D,Q> +impl<A, B, D, Q> DecompositionMut<Pair<A, B>> for PairDecomposition<D, Q> where - A : Space, - B : Space, - D : DecompositionMut<A>, - Q : DecompositionMut<B>, + A: Space, + B: Space, + D: DecompositionMut<A>, + Q: DecompositionMut<B>, { - type ReferenceMut<'b> = Pair<D::ReferenceMut<'b>, Q::ReferenceMut<'b>> where Pair<A, B> : 'b; + type ReferenceMut<'b> + = Pair<D::ReferenceMut<'b>, Q::ReferenceMut<'b>> + where + Pair<A, B>: 'b; } impl<A, B, U, V, D, Q> InstanceMut<Pair<A, B>, PairDecomposition<D, Q>> for Pair<U, V> where - A : Space, - B : Space, - D : DecompositionMut<A>, - Q : DecompositionMut<B>, - U : InstanceMut<A, D>, - V : InstanceMut<B, Q>, + A: Space, + B: Space, + D: DecompositionMut<A>, + Q: DecompositionMut<B>, + U: InstanceMut<A, D>, + V: InstanceMut<B, Q>, { #[inline] - fn ref_instance_mut(&mut self) - -> <PairDecomposition<D, Q> as DecompositionMut<Pair<A, B>>>::ReferenceMut<'_> - { + fn ref_instance_mut( + &mut self, + ) -> <PairDecomposition<D, Q> as DecompositionMut<Pair<A, B>>>::ReferenceMut<'_> { Pair(self.0.ref_instance_mut(), self.1.ref_instance_mut()) } } impl<'a, A, B, U, V, D, Q> InstanceMut<Pair<A, B>, PairDecomposition<D, Q>> for &'a mut Pair<U, V> where - A : Space, - B : Space, - D : DecompositionMut<A>, - Q : DecompositionMut<B>, - U : InstanceMut<A, D>, - V : InstanceMut<B, Q>, + A: Space, + B: Space, + D: DecompositionMut<A>, + Q: DecompositionMut<B>, + U: InstanceMut<A, D>, + V: InstanceMut<B, Q>, { #[inline] - fn ref_instance_mut(&mut self) - -> <PairDecomposition<D, Q> as DecompositionMut<Pair<A, B>>>::ReferenceMut<'_> - { + fn ref_instance_mut( + &mut self, + ) -> <PairDecomposition<D, Q> as DecompositionMut<Pair<A, B>>>::ReferenceMut<'_> { Pair(self.0.ref_instance_mut(), self.1.ref_instance_mut()) } } - -impl<F, A, B, ExpA, ExpB, ExpJ> Norm<F, PairNorm<ExpA, ExpB, ExpJ>> -for Pair<A,B> +impl<F, A, B, ExpA, ExpB, ExpJ> Norm<F, PairNorm<ExpA, ExpB, ExpJ>> for Pair<A, B> where - F : Num, - ExpA : NormExponent, - ExpB : NormExponent, - ExpJ : NormExponent, - A : Norm<F, ExpA>, - B : Norm<F, ExpB>, - Loc<F, 2> : Norm<F, ExpJ>, + F: Num, + ExpA: NormExponent, + ExpB: NormExponent, + ExpJ: NormExponent, + A: Norm<F, ExpA>, + B: Norm<F, ExpB>, + Loc<F, 2>: Norm<F, ExpJ>, { - fn norm(&self, PairNorm(expa, expb, expj) : PairNorm<ExpA, ExpB, ExpJ>) -> F { + fn norm(&self, PairNorm(expa, expb, expj): PairNorm<ExpA, ExpB, ExpJ>) -> F { Loc([self.0.norm(expa), self.1.norm(expb)]).norm(expj) } } - -impl<F : Float, A, B> Normed<F> for Pair<A,B> +impl<F: Float, A, B> Normed<F> for Pair<A, B> where - A : Normed<F>, - B : Normed<F>, + A: Normed<F>, + B: Normed<F>, { type NormExp = PairNorm<A::NormExp, B::NormExp, L2>; @@ -496,11 +525,10 @@ } } -impl<F : Float, A, B> HasDual<F> for Pair<A,B> +impl<F: Float, A, B> HasDual<F> for Pair<A, B> where - A : HasDual<F>, - B : HasDual<F>, - + A: HasDual<F>, + B: HasDual<F>, { type DualSpace = Pair<A::DualSpace, B::DualSpace>; }
--- a/src/lib.rs Tue Apr 08 13:30:12 2025 -0500 +++ b/src/lib.rs Sun Apr 27 20:29:43 2025 -0500 @@ -1,48 +1,54 @@ +// Version of lib.rs for stable builds. + // The main documentation is in the README. #![doc = include_str!("../README.md")] - // We use unicode. We would like to use much more of it than Rust allows. // Live with it. Embrace it. #![allow(uncommon_codepoints)] #![allow(mixed_script_confusables)] #![allow(confusable_idents)] - -#![cfg_attr(feature = "nightly", - feature(maybe_uninit_array_assume_init,maybe_uninit_slice), - feature(float_minimum_maximum), - feature(get_mut_unchecked), - feature(cow_is_borrowed), +// Extra setup for builds with the nightly compiler +#![cfg_attr( + nightly, + feature( + maybe_uninit_array_assume_init, + maybe_uninit_slice, + float_minimum_maximum, + get_mut_unchecked, + cow_is_borrowed + ) )] -pub mod types; -pub mod instance; +#[macro_use] +pub(crate) mod metaprogramming; pub mod collection; -pub mod nanleast; pub mod error; +pub mod euclidean; +pub mod instance; +pub mod maputil; +pub mod nanleast; +pub mod norms; pub mod parallelism; -pub mod maputil; pub mod tuple; -pub mod euclidean; -pub mod norms; +pub mod types; #[macro_use] pub mod loc; +pub mod bisection_tree; +pub mod coefficients; +pub mod convex; +pub mod direct_product; +pub mod discrete_gradient; +pub mod fe_model; pub mod iter; -pub mod linops; pub mod iterate; -pub mod tabledump; -pub mod logger; +pub mod lingrid; +pub mod linops; pub mod linsolve; -pub mod lingrid; -pub mod sets; +pub mod logger; pub mod mapping; -pub mod coefficients; -pub mod fe_model; -pub mod bisection_tree; pub mod nalgebra_support; -pub(crate) mod metaprogramming; -pub mod direct_product; -pub mod convex; -pub mod discrete_gradient; pub mod operator_arithmetic; +pub mod sets; +pub mod tabledump; pub use types::*;
--- a/src/linsolve.rs Tue Apr 08 13:30:12 2025 -0500 +++ b/src/linsolve.rs Sun Apr 27 20:29:43 2025 -0500 @@ -3,7 +3,7 @@ */ use crate::types::Float; -#[cfg(feature = "nightly")] +#[cfg(nightly)] use std::mem::MaybeUninit; /// Gaussian elimination for $AX=B$, where $A$ and $B$ are both stored in `ab`, @@ -50,7 +50,7 @@ // If the "nightly" feature is enabled, we will use an uninitialised array for a // little bit of efficiency. // This use of MaybeUninit assumes F : Copy. Otherwise undefined behaviour may occur. - #[cfg(feature = "nightly")] + #[cfg(nightly)] { let mut x: [[MaybeUninit<F>; K]; M] = [[const { MaybeUninit::uninit() }; K]; M]; //unsafe { std::mem::MaybeUninit::uninit().assume_init() }; @@ -69,7 +69,7 @@ (&x as *const _ as *const [[F; K]; M]).read() } } - #[cfg(not(feature = "nightly"))] + #[cfg(not(nightly))] { let mut x: [[F; K]; M] = [[F::ZERO; K]; M]; for i in (0..M).rev() {
--- a/src/maputil.rs Tue Apr 08 13:30:12 2025 -0500 +++ b/src/maputil.rs Sun Apr 27 20:29:43 2025 -0500 @@ -3,7 +3,7 @@ */ use itertools::izip; -#[cfg(feature = "nightly")] +#[cfg(nightly)] use std::mem::MaybeUninit; /// Trait for a fixed-length container type. @@ -352,7 +352,7 @@ /// /// If `iter.next()` panicks, all items already yielded by the iterator are /// dropped. -#[cfg(feature = "nightly")] +#[cfg(nightly)] #[inline] pub(crate) fn collect_into_array_unchecked<T, I: Iterator<Item = T>, const N: usize>( mut iter: I, @@ -413,7 +413,7 @@ unreachable!("Something went wrong with iterator length") } -#[cfg(not(feature = "nightly"))] +#[cfg(not(nightly))] #[inline] pub(crate) fn collect_into_array_unchecked<T, I: Iterator<Item = T>, const N: usize>( iter: I,
--- a/src/metaprogramming.rs Tue Apr 08 13:30:12 2025 -0500 +++ b/src/metaprogramming.rs Sun Apr 27 20:29:43 2025 -0500 @@ -9,21 +9,30 @@ /// maybe_ref!(ref, V) // ➡ &V /// maybe_ref!(noref, V) // ➡ V /// ``` -#[macro_export] macro_rules! maybe_ref { - (ref, $x:expr) => { &$x }; - (noref, $x:expr) => { $x }; - (ref, $x:ty) => { &$x }; - (noref, $x:ty) => { $x }; + (ref, $x:expr) => { + &$x + }; + (noref, $x:expr) => { + $x + }; + (ref, $x:ty) => { + &$x + }; + (noref, $x:ty) => { + $x + }; } /// Choose `a` if first argument is the literal `ref`, otherwise `b`. -#[macro_export] -macro_rules! ifref { - (noref, $a:expr, $b:expr) => { $b }; - (ref, $a:expr, $b:expr) => { $a }; -} - +// macro_rules! ifref { +// (noref, $a:expr, $b:expr) => { +// $b +// }; +// (ref, $a:expr, $b:expr) => { +// $a +// }; +// } /// Annotate `x` with a lifetime if the first parameter /// Typically to be used from another macro. @@ -32,10 +41,14 @@ /// maybe_ref!(ref, &'a V) // ➡ &'a V /// maybe_ref!(noref, &'a V) // ➡ V /// ``` -#[macro_export] macro_rules! maybe_lifetime { - (ref, $x:ty) => { $x }; - (noref, &$lt:lifetime $x:ty) => { $x }; - (noref, &$x:ty) => { $x }; + (ref, $x:ty) => { + $x + }; + (noref, &$lt:lifetime $x:ty) => { + $x + }; + (noref, &$x:ty) => { + $x + }; } -