From ea98969d350109487a42a01f0e5ef08afa4b01ac Mon Sep 17 00:00:00 2001 From: Mica White Date: Tue, 12 May 2026 15:51:06 -0400 Subject: ArrayTuple and ArrayTupleOrEmpty --- src/lib.rs | 82 ++++++++++++++++++++++----------------------- varihappy-macros/src/lib.rs | 23 ++++++++++--- 2 files changed, 60 insertions(+), 45 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6d93428..b7b58ba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,11 @@ use varihappy_macros::{ - repeat, tuple_expr_reverse, tuple_new, tuple_reverse, tuple_trait_def, type_to_field_access, + repeat, tuple_expr_reverse, tuple_len, tuple_new, tuple_reverse, tuple_trait_def, + type_to_field_access, }; pub trait Tuple { + const LEN: usize; + type AsRef<'a>: Tuple where Self: 'a; @@ -26,6 +29,15 @@ pub trait Tuple1: Tuple { fn into_rest(self) -> Self::Rest; } +pub trait ArrayTupleOrEmpty: Tuple {} + +pub trait ArrayTuple: Tuple { + type Item; +} + +impl ArrayTupleOrEmpty for () {} +impl> ArrayTupleOrEmpty for T {} + impl Tuple for () { type AsRef<'a> = () @@ -38,49 +50,13 @@ impl Tuple for () { type Reversed = (); + const LEN: usize = 0; + fn as_ref(&self) -> Self::AsRef<'_> {} fn as_mut(&mut self) -> Self::AsMut<'_> {} fn rev(self) -> Self::Reversed {} } -impl Tuple for (A,) { - type AsRef<'a> - = (&'a A,) - where - Self: 'a; - type AsMut<'a> - = (&'a mut A,) - where - Self: 'a; - type Reversed = (A,); - - fn as_ref(&self) -> Self::AsRef<'_> { - (&self.0,) - } - - fn as_mut(&mut self) -> Self::AsMut<'_> { - (&mut self.0,) - } - - fn rev(self) -> Self::Reversed { - (self.0,) - } -} - -impl Tuple1 for (A,) { - type Item0 = A; - type Rest = (); - - fn into_0(self) -> Self::Item0 { - self.0 - } - fn split_into(self) -> (Self::Item0, Self::Rest) { - (self.0, ()) - } - - fn into_rest(self) -> Self::Rest {} -} - macro_rules! tuple_apply { (($($letter: ident,)*), $other: ident) => { $other!(($($letter,)*)) @@ -119,6 +95,7 @@ macro_rules! tuple_expr_mut { macro_rules! tuple_expr_rest { ($this: ident, (A, $($letter: ident,)*)) => { + #[allow(unused_variables, clippy::unused_unit)] { let this = $this; ($(type_to_field_access!($letter),)*) @@ -138,6 +115,8 @@ macro_rules! tuple_expr_split { macro_rules! impl_tuple_inner { (($($letter: ident,)*)) => { impl<$($letter),*> Tuple for ($($letter,)*) { + const LEN: usize = tuple_len!(($($letter,)*)); + type AsRef<'a> = ($(&'a $letter,)*) where Self: 'a; type AsMut<'a> = ($(&'a mut $letter,)*) where Self: 'a; type Reversed = tuple_apply!(($($letter,)*), tuple_reverse); @@ -213,5 +192,26 @@ macro_rules! tuple_trait { }; } -repeat!(64, impl_tuple); -repeat!(64, tuple_trait); +macro_rules! t { + ($_t:tt) => { + T + }; +} + +macro_rules! impl_array_tuple_inner { + (($($letter: ident,)*)) => { + impl ArrayTuple for ($(t!($letter),)*) { + type Item = T; + } + }; +} + +macro_rules! impl_array_tuple { + ($number: literal) => { + tuple_new! { $number, impl_array_tuple_inner } + }; +} + +repeat!(1..64, impl_tuple); +repeat!(2..64, tuple_trait); +repeat!(1..64, impl_array_tuple); diff --git a/varihappy-macros/src/lib.rs b/varihappy-macros/src/lib.rs index 3931899..3b1cc29 100644 --- a/varihappy-macros/src/lib.rs +++ b/varihappy-macros/src/lib.rs @@ -1,11 +1,11 @@ extern crate proc_macro; use proc_macro::TokenStream; -use proc_macro2::{Ident, Literal, Span}; +use proc_macro2::{Ident, Literal}; use quote::{format_ident, quote}; -use syn::LitInt; use unsynn::{ Comma, CommaDelimitedVec, Cons, Either, GroupContaining, IParse, LiteralInteger, TokenIter, + unsynn, }; fn number_to_type(mut number: u128) -> String { @@ -169,11 +169,19 @@ pub fn type_to_field_access(input: TokenStream) -> TokenStream { #[proc_macro] pub fn repeat(input: TokenStream) -> TokenStream { + unsynn! { + struct RangeLiteral { + start: LiteralInteger, + dotdot: unsynn::DotDot, + end: LiteralInteger, + } + } + let input: proc_macro2::TokenStream = input.into(); let mut token_iter = TokenIter::new(input); - let ast: Cons = token_iter.parse().unwrap(); + let ast: Cons = token_iter.parse().unwrap(); - let numbers = (2..=ast.first.value()).map(Literal::u128_unsuffixed); + let numbers = (ast.first.start.value()..ast.first.end.value()).map(Literal::u128_unsuffixed); let macro_name = ast.third; quote! { #(#macro_name!(#numbers);)* }.into() } @@ -197,3 +205,10 @@ pub fn tuple_trait_def(input: TokenStream) -> TokenStream { quote! { #ident! { trait #trait_name for #other_trait { type #item_type; fn #item_fn; }} } .into() } + +#[proc_macro] +pub fn tuple_len(input: TokenStream) -> TokenStream { + let tuple = syn::parse_macro_input!(input as syn::TypeTuple); + let len = Literal::usize_unsuffixed(tuple.elems.len()); + quote! { #len }.into() +} -- cgit v1.2.3