value_traits_derive/
lib.rs

1/*
2 * SPDX-FileCopyrightText: 2025 Tommaso Fontana
3 * SPDX-FileCopyrightText: 2025 Inria
4 * SPDX-FileCopyrightText: 2025 Sebastiano Vigna
5 *
6 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
7 */
8
9#![warn(missing_docs)]
10#![warn(clippy::missing_errors_doc)]
11#![warn(clippy::missing_panics_doc)]
12
13//! Derive macros for the [`value-traits`](https://docs.rs/value-traits/latest/value_traits/) crate.
14
15use proc_macro::TokenStream;
16use quote::{quote, ToTokens};
17use syn::{
18    parse2, parse_macro_input, punctuated::Punctuated, AngleBracketedGenericArguments, DeriveInput,
19};
20
21/// Helper function returning the list of parameter names without angle brackets.
22fn get_names(ty_generics_token_stream: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
23    if ty_generics_token_stream.is_empty() {
24        proc_macro2::TokenStream::new()
25    } else {
26        let parsed_args: AngleBracketedGenericArguments =
27            parse2(ty_generics_token_stream)
28                .expect("Failed to parse ty_generics into AngleBracketedGenericArguments. This indicates an unexpected structure in the generic parameters.");
29
30        parsed_args.args.into_token_stream()
31    }
32}
33
34/// Helper function to extract additional bounds from attributes
35fn extract_additional_bounds(
36    input: &DeriveInput,
37    attr_name: &str,
38) -> Vec<proc_macro2::TokenStream> {
39    let mut additional_bounds = Vec::new();
40    for attr in &input.attrs {
41        if attr.path().is_ident(attr_name) {
42            attr.parse_nested_meta(|meta| {
43                if meta.path.is_ident("bound") {
44                    let bound: syn::LitStr = meta.value()?.parse()?;
45                    let bound_tokens: proc_macro2::TokenStream =
46                        bound.value().parse().expect("Failed to parse bound");
47                    additional_bounds.push(bound_tokens);
48                }
49                Ok(())
50            })
51            .expect("Failed to parse attribute {attr_name}");
52        }
53    }
54    additional_bounds
55}
56
57/// Helper function to add additional bounds to a where clause
58fn add_bounds_to_where_clause(
59    generics: &mut syn::Generics,
60    additional_bounds: Vec<proc_macro2::TokenStream>,
61) {
62    if !additional_bounds.is_empty() {
63        let where_clause = generics.make_where_clause();
64        for bound in additional_bounds {
65            let predicate: syn::WherePredicate =
66                syn::parse2(bound).expect("Invalid where predicate");
67            where_clause.predicates.push(predicate);
68        }
69    }
70}
71
72fn get_params_without_defaults(
73    generics: &syn::Generics,
74) -> Punctuated<syn::GenericParam, syn::token::Comma> {
75    // Remove default type parameters
76    let mut params = generics.params.clone();
77    params.iter_mut().for_each(|param| match param {
78        syn::GenericParam::Type(ty_param) => {
79            ty_param.default = None;
80        }
81        syn::GenericParam::Const(const_param) => {
82            const_param.default = None;
83        }
84        _ => {}
85    });
86    params
87}
88
89/// A derive macro fully implementing subslices on top of a
90/// [`SliceByValue`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValue.html).
91///
92/// The macro defines a structure `<YOUR TYPE>SubsliceImpl` that keeps track of
93/// a reference to a slice, and of the start and end of the subslice.
94/// `<YOUR TYPE>SubsliceImpl` then implements
95/// [`SliceByValue`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValue.html)
96/// and
97/// [`SliceByValueSubslice`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueSubslice.html).
98///
99/// ## Additional Bounds
100///
101/// Since this macro has no knowledge of the bounds of the generic
102/// parameters in the implementations of
103/// [`SliceByValue`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValue.html),
104/// additional bounds with respect to the type declaration must be specified
105/// using the `#[value_traits_subslices(bound = "<BOUND>")]` attribute. Multiple bounds can
106/// be specified with multiple attributes.
107#[proc_macro_derive(Subslices, attributes(value_traits_subslices))]
108pub fn subslices(input: TokenStream) -> TokenStream {
109    let mut input = parse_macro_input!(input as DeriveInput);
110
111    // Extract and add additional bounds
112    let additional_bounds = extract_additional_bounds(&input, "value_traits_subslices");
113    add_bounds_to_where_clause(&mut input.generics, additional_bounds);
114
115    let input_ident = input.ident;
116    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
117    let params = get_params_without_defaults(&input.generics);
118    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
119
120    let names = get_names(ty_generics_token_stream);
121    let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
122    let mut res = quote! {
123        #[automatically_derived]
124        pub struct #subslice_impl<'__subslice_impl, #params> {
125            slice: &'__subslice_impl #input_ident #ty_generics,
126            range: ::core::ops::Range<usize>,
127        }
128
129        #[automatically_derived]
130        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValue for #subslice_impl<'__subslice_impl, #names> #where_clause {
131            type Value = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
132
133            #[inline]
134            fn len(&self) -> usize {
135                self.range.len()
136            }
137
138            unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
139                self.slice.get_value_unchecked(index + self.range.start)
140            }
141        }
142
143        #[automatically_derived]
144        impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_gat> for #subslice_impl<'__subslice_impl, #names> #where_clause {
145            type Subslice = #subslice_impl<'__subslice_gat, #names>;
146        }
147
148        #[automatically_derived]
149        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_impl> for #input_ident #ty_generics #where_clause  {
150            type Subslice = #subslice_impl<'__subslice_impl, #names>;
151        }
152    };
153
154    for range_type in [
155        quote! { core::ops::Range<usize> },
156        quote! { core::ops::RangeFrom<usize> },
157        quote! { core::ops::RangeToInclusive<usize> },
158        quote! { core::ops::RangeFull },
159        quote! { core::ops::RangeInclusive<usize> },
160        quote! { core::ops::RangeTo<usize> },
161    ] {
162        res.extend(quote! {
163            #[automatically_derived]
164            impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRange<#range_type> for #input_ident #ty_generics #where_clause {
165                unsafe fn get_subslice_unchecked(
166                    &self,
167                    range: #range_type,
168                ) -> ::value_traits::slices::Subslice<'_, Self> {
169                    #subslice_impl {
170                        slice: &self,
171                        range: ::value_traits::slices::ComposeRange::compose(&range, 0..self.len()),
172                    }
173                }
174            }
175            #[automatically_derived]
176            impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<#range_type>
177                for #subslice_impl<'__subslice_impl, #names> #where_clause
178            {
179                unsafe fn get_subslice_unchecked(
180                    &self,
181                    range: #range_type,
182                ) -> ::value_traits::slices::Subslice<'_, Self> {
183                    #subslice_impl {
184                        slice: self.slice,
185                        range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
186                    }
187                }
188            }
189        });
190    }
191
192    res.into()
193}
194
195/// A derive macro fully implementing mutable subslices on top of a
196/// [`SliceByValueMut`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueMut.html)
197/// for which the derive macro [`Subslices`] has been already applied.
198///
199/// The macro defines a structure `<YOUR TYPE>SubsliceImplMut` that keeps track
200/// of a mutable reference to a slice, and of the start and end of the subslice.
201/// `<YOUR TYPE>SubsliceImplMut` then implements
202/// [`SliceByValueMut`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueMut.html),
203/// [`SliceByValueSubslice`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueSubslice.html),
204/// and
205/// [`SliceByValueSubsliceMut`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueSubsliceMut.html).
206///
207/// Note that
208/// [`SliceByValueSubslice`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueSubslice.html)
209/// methods will return the `<YOUR TYPE>SubsliceImpl` structure generated by the
210/// [`Subslices`] macro.
211///
212/// ## Chunks
213///
214/// Presently, [`try_chunks_mut`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueMut.html#method.try_chunks_mut)
215/// is not supported.
216///
217/// ## Additional Bounds
218///
219/// Since this macro has no knowledge of the bounds of the generic parameters in
220/// the implementations of
221/// [`SliceByValue`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValue.html)
222/// and
223/// [`SliceByValueMut`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueMut.html),
224/// additional bounds with respect to the type declaration must be specified
225/// using the `#[value_trait_subslice_mut(bound = "<BOUND>")]` attribute.
226/// Multiple bounds can be specified with multiple attributes.
227#[proc_macro_derive(SubslicesMut, attributes(value_traits_subslices_mut))]
228pub fn subslices_mut(input: TokenStream) -> TokenStream {
229    let mut input = parse_macro_input!(input as DeriveInput);
230
231    // Extract and add additional bounds
232    let additional_bounds = extract_additional_bounds(&input, "value_traits_subslices_mut");
233    add_bounds_to_where_clause(&mut input.generics, additional_bounds);
234
235    let input_ident = input.ident;
236    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
237    let params = get_params_without_defaults(&input.generics);
238    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
239
240    let names = get_names(ty_generics_token_stream);
241    let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
242    let subslice_impl_mut = quote::format_ident!("{}SubsliceImplMut", input_ident);
243    let mut res = quote! {
244        #[automatically_derived]
245        pub struct #subslice_impl_mut<'__subslice_impl, #params> {
246            slice: &'__subslice_impl mut #input_ident #ty_generics,
247            range: ::core::ops::Range<usize>,
248        }
249
250        #[automatically_derived]
251        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValue for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
252            type Value = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
253
254            #[inline]
255            fn len(&self) -> usize {
256                self.range.len()
257            }
258
259            unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
260                self.slice.get_value_unchecked(index + self.range.start)
261            }
262        }
263
264
265        #[automatically_derived]
266        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueMut for #subslice_impl_mut<'__subslice_impl, #names> #where_clause  {
267            unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
268                self.slice.set_value_unchecked(index + self.range.start, value)
269            }
270
271            unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value {
272                self.slice.replace_value_unchecked(index + self.range.start, value)
273            }
274
275            type ChunksMut<'a> = ::core::iter::Empty<&'a mut Self>
276            where
277                Self: 'a;
278
279            type ChunksMutError = ::value_traits::slices::ChunksMutNotSupported;
280
281            fn try_chunks_mut(&mut self, _chunk_size: usize) -> Result<Self::ChunksMut<'_>, Self::ChunksMutError> {
282                // Derived subslice types cannot provide mutable chunks
283                Err(::value_traits::slices::ChunksMutNotSupported)
284            }
285        }
286
287        #[automatically_derived]
288        impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_gat> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
289            type Subslice = #subslice_impl<'__subslice_gat, #names>;
290        }
291
292        #[automatically_derived]
293        impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGatMut<'__subslice_gat> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
294            type SubsliceMut = #subslice_impl_mut<'__subslice_gat, #names>;
295        }
296
297        #[automatically_derived]
298        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceGatMut<'__subslice_impl> for #input_ident #ty_generics #where_clause  {
299            type SubsliceMut = #subslice_impl_mut<'__subslice_impl, #names>;
300        }
301
302    };
303
304    for range_type in [
305        quote! { ::core::ops::Range<usize> },
306        quote! { ::core::ops::RangeFrom<usize> },
307        quote! { ::core::ops::RangeToInclusive<usize> },
308        quote! { ::core::ops::RangeFull },
309        quote! { ::core::ops::RangeInclusive<usize> },
310        quote! { ::core::ops::RangeTo<usize> },
311    ] {
312        // Impl subslice mut traits for the original type
313        res.extend(quote!{
314            #[automatically_derived]
315            impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRangeMut<#range_type> for #input_ident #ty_generics #where_clause {
316                unsafe fn get_subslice_unchecked_mut(
317                    &mut self,
318                    range: #range_type,
319                ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
320                    let len = self.len();
321                    #subslice_impl_mut {
322                        slice: self,
323                        range: ::value_traits::slices::ComposeRange::compose(&range, 0..len),
324                    }
325                }
326            }
327            #[automatically_derived]
328            impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<#range_type>
329                for #subslice_impl_mut<'__subslice_impl, #names> #where_clause
330            {
331                unsafe fn get_subslice_unchecked(
332                    &self,
333                    range: #range_type,
334                ) -> ::value_traits::slices::Subslice<'_, Self> {
335                    #subslice_impl {
336                        slice: &*self.slice,
337                        range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
338                    }
339                }
340            }
341            #[automatically_derived]
342            impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRangeMut<#range_type>
343                for #subslice_impl_mut<'__subslice_impl, #names> #where_clause
344            {
345                unsafe fn get_subslice_unchecked_mut(
346                    &mut self,
347                    range: #range_type,
348                ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
349                    #subslice_impl_mut {
350                        slice: self.slice,
351                        range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
352                    }
353                }
354            }
355        });
356    }
357
358    res.into()
359}
360
361/// A derive macro fully implementing
362/// [`IterateByValue`](https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValue.html)
363/// and
364/// [`IterateByValueFrom`](https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValueFrom.html)
365/// for subslices on top of a the `<YOUR TYPE>SubsliceImpl` structure generated
366/// by the derive macro [`Subslices`].
367///
368/// The macro defines a structure `<YOUR TYPE>Iter` that keeps track of a
369/// mutable reference to a slice and of a current iteration range; the structure
370/// is used to implement
371/// [`IterateByValue`](https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValue.html)
372/// and
373/// [`IterateByValueFrom`](https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValueFrom.html)
374/// on `<YOUR TYPE>SubsliceImpl`.
375///
376/// ## Additional Bounds
377///
378/// Since this macro has no knowledge of the bounds of the generic
379/// parameters in the implementations of
380/// [`SliceByValue`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValue.html),
381/// additional bounds with respect to the type declaration must be specified
382/// using the `#[value_traits_iterators(bound = "<BOUND>")]` attribute. Multiple bounds can
383/// be specified with multiple attributes.
384#[proc_macro_derive(Iterators, attributes(value_traits_iterators))]
385pub fn iterators(input: TokenStream) -> TokenStream {
386    let mut input = parse_macro_input!(input as DeriveInput);
387
388    // Extract and add additional bounds
389    let additional_bounds = extract_additional_bounds(&input, "value_traits_iterators");
390    add_bounds_to_where_clause(&mut input.generics, additional_bounds);
391
392    let input_ident = input.ident;
393    input.generics.make_where_clause();
394    let (_impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
395    let params = get_params_without_defaults(&input.generics);
396    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
397
398    let names = get_names(ty_generics_token_stream);
399    let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
400    let iter = quote::format_ident!("{}Iter", input_ident);
401    quote! {
402        #[automatically_derived]
403        pub struct #iter<'__iter_ref, #params> {
404            subslice: &'__iter_ref #input_ident #ty_generics,
405            range: ::core::ops::Range<usize>,
406        }
407
408        #[automatically_derived]
409        impl<'__iter_ref, #params> #iter<'__iter_ref, #names> #where_clause {
410            pub fn new(subslice: &'__iter_ref #input_ident #ty_generics) -> Self {
411                let len = subslice.len();
412                Self {
413                    subslice,
414                    range: 0..len,
415                }
416            }
417            pub fn new_with_range(subslice: &'__iter_ref #input_ident #ty_generics, range: ::core::ops::Range<usize>) -> Self {
418                Self {
419                    subslice,
420                    range,
421                }
422            }
423        }
424
425        /*#[automatically_derived]
426        impl<#params> ::value_traits::iter::IterateByValue for #input_ident #ty_generics #where_clause {
427            type Item = <Self as ::value_traits::slices::SliceByValue>::Value;
428            type Iter<'__iter_ref>
429                = #iter<'__iter_ref, #names>
430            where
431                Self: '__iter_ref;
432
433            #[inline]
434            fn iter_value(&self) -> Self::Iter<'_> {
435                #iter::new(self)
436            }
437        }
438
439        #[automatically_derived]
440        impl<#params> ::value_traits::iter::IterateByValueFrom for #input_ident #ty_generics #where_clause {
441            type IterFrom<'__iter_ref>
442                = #iter<'__iter_ref, #names>
443            where
444                Self: '__iter_ref;
445
446            #[inline]
447            fn iter_value_from(&self, from: usize) -> Self::IterFrom<'_> {
448                let len = self.len();
449                assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
450                #iter::new_with_range(self, from..len)
451            }
452        }*/
453
454        #[automatically_derived]
455        /// Ideally we would like to also implement [`::core::iter::Iterator::advance_by`], but it is
456        /// nightly, and [`::core::iter::Iterator::skip`], [`::core::iter::Iterator::take`], [`::core::iter::Iterator::step_by`],
457        /// as we can do it more efficiently, but the [`::core::iter::Iterator`] trait definition
458        /// doesn't allow to return an arbitrary type.
459        impl<'__iter_ref, #params> ::core::iter::Iterator for #iter<'__iter_ref, #names> #where_clause {
460            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
461
462            #[inline]
463            fn next(&mut self) -> Option<Self::Item> {
464                if self.range.is_empty() {
465                    return ::core::option::Option::None;
466                }
467                let value = unsafe { self.subslice.get_value_unchecked(self.range.start) };
468                self.range.start += 1;
469                ::core::option::Option::Some(value)
470            }
471
472            /// Since we are indexing into a subslice, we can implement
473            /// [`::core::iter::Iterator::nth`] without needing to consume the first `n` elements.
474            #[inline]
475            fn nth(&mut self, n: usize) -> Option<Self::Item> {
476                if n >= self.range.end {
477                    self.range.start = self.range.end; // consume the ::core::iter::iterator
478                    return ::core::option::Option::None;
479                }
480                let value = unsafe { self.subslice.get_value_unchecked(self.range.start + n) };
481                self.range.start += n + 1;
482                ::core::option::Option::Some(value)
483            }
484
485            #[inline]
486            fn size_hint(&self) -> (usize, Option<usize>) {
487                let len = self.range.len();
488                (len, Some(len))
489            }
490        }
491
492        impl<'__iter_ref, #params> ::core::iter::DoubleEndedIterator for #iter<'__iter_ref, #names> #where_clause {
493            #[inline]
494            fn next_back(&mut self) -> Option<Self::Item> {
495                if self.range.is_empty() {
496                    return ::core::option::Option::None;
497                }
498                self.range.end -= 1;
499                let value = unsafe { self.subslice.get_value_unchecked(self.range.end) };
500                ::core::option::Option::Some(value)
501            }
502        }
503
504        impl<'__iter_ref, #params> ::core::iter::ExactSizeIterator for #iter<'__iter_ref, #names> #where_clause {
505            #[inline]
506            fn len(&self) -> usize {
507                self.range.len()
508            }
509        }
510
511        #[automatically_derived]
512        impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueGat<'__iter_ref> for #subslice_impl<'__subslice_impl, #names> #where_clause {
513            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
514            type Iter = #iter<'__iter_ref, #names>;
515        }
516
517        #[automatically_derived]
518        impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValue for #subslice_impl<'__subslice_impl, #names> #where_clause {
519            #[inline]
520            fn iter_value(&self) -> ::value_traits::iter::Iter<'_, Self> {
521                #iter::new(self.slice)
522            }
523        }
524
525        #[automatically_derived]
526        impl<'__subslice_impl, '__iter_ref,#params> ::value_traits::iter::IterateByValueFromGat<'__iter_ref> for #subslice_impl<'__subslice_impl, #names> #where_clause {
527            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
528            type IterFrom = #iter<'__iter_ref, #names>;
529        }
530
531        #[automatically_derived]
532        impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValueFrom for #subslice_impl<'__subslice_impl, #names> #where_clause {
533            #[inline]
534            fn iter_value_from(&self, from: usize) -> ::value_traits::iter::IterFrom<'_, Self> {
535                let len = self.len();
536                assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
537                let range = ::value_traits::slices::ComposeRange::compose(&(from..), self.range.clone());
538                #iter::new_with_range(self.slice, range)
539            }
540        }
541    }.into()
542}
543
544/// A derive macro that implements
545/// [`IterateByValue`](https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValue.html)
546/// and
547/// [`IterateByValueFrom`](https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValueFrom.html)
548/// for mutable subslices on top of the `<YOUR TYPE>SubsliceImplMut` structure
549/// generated by the derive macro [`SubslicesMut`].
550///
551/// To call this macro, you first need to derive both [`SubslicesMut`] and
552/// [`Iterators`] on the same struct, as this macro uses the `<YOUR TYPE>Iter`
553/// structure defined by [`Iterators`].
554///
555/// ## Additional Bounds
556///
557/// Since this macro has no knowledge of the bounds of the generic parameters in
558/// the implementations of
559/// [`SliceByValue`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValue.html) and
560/// [`SliceByValueMut`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueMut.html),
561/// additional bounds with respect to the type declaration must be specified
562/// using the `#[value_traits_iterators_mut(bound = "<BOUND>")]` attribute.
563/// Multiple bounds can be specified with multiple attributes.
564#[proc_macro_derive(IteratorsMut, attributes(value_traits_iterators_mut))]
565pub fn iterators_mut(input: TokenStream) -> TokenStream {
566    let mut input = parse_macro_input!(input as DeriveInput);
567
568    // Extract and add additional bounds
569    let additional_bounds = extract_additional_bounds(&input, "value_traits_iterators_mut");
570    add_bounds_to_where_clause(&mut input.generics, additional_bounds);
571
572    let input_ident = input.ident;
573    input.generics.make_where_clause();
574    let (_impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
575    let params = get_params_without_defaults(&input.generics);
576    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
577
578    let names = get_names(ty_generics_token_stream);
579    let subslice_impl_mut = quote::format_ident!("{}SubsliceImplMut", input_ident);
580    let iter = quote::format_ident!("{}Iter", input_ident);
581    quote!{
582        #[automatically_derived]
583        impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueGat<'__iter_ref> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
584            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
585            type Iter = #iter<'__iter_ref, #names>;
586        }
587
588        #[automatically_derived]
589        impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValue for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
590            fn iter_value(&self) -> ::value_traits::iter::Iter<'_, Self> {
591                #iter::new(self.slice)
592            }
593        }
594
595        #[automatically_derived]
596        impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueFromGat<'__iter_ref> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
597            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
598            type IterFrom = #iter<'__iter_ref, #names>;
599        }
600
601        #[automatically_derived]
602        impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValueFrom for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
603            fn iter_value_from(&self, from: usize) -> ::value_traits::iter::IterFrom<'_, Self> {
604                let len = self.len();
605                assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
606                let range = ::value_traits::slices::ComposeRange::compose(&(from..), self.range.clone());
607                #iter::new_with_range(self.slice, range)
608            }
609        }
610    }.into()
611}