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/// [`SliceByValueGet`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueGet.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/// [`SliceByValueGet`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueGet.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/// and
105/// [`SliceByValueGet`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueGet.html),
106/// additional bounds with respect to the type declaration must be specified
107/// using the `#[value_traits_subslices(bound = "<BOUND>")]` attribute. Multiple bounds can
108/// be specified with multiple attributes.
109#[proc_macro_derive(Subslices, attributes(value_traits_subslices))]
110pub fn subslices(input: TokenStream) -> TokenStream {
111    let mut input = parse_macro_input!(input as DeriveInput);
112
113    // Extract and add additional bounds
114    let additional_bounds = extract_additional_bounds(&input, "value_traits_subslices");
115    add_bounds_to_where_clause(&mut input.generics, additional_bounds);
116
117    let input_ident = input.ident;
118    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
119    let params = get_params_without_defaults(&input.generics);
120    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
121
122    let names = get_names(ty_generics_token_stream);
123    let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
124    let mut res = quote! {
125        #[automatically_derived]
126        pub struct #subslice_impl<'__subslice_impl, #params> {
127            slice: &'__subslice_impl #input_ident #ty_generics,
128            range: ::core::ops::Range<usize>,
129        }
130
131        #[automatically_derived]
132        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValue for #subslice_impl<'__subslice_impl, #names> #where_clause {
133            type Value = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
134
135            #[inline]
136            fn len(&self) -> usize {
137                self.range.len()
138            }
139        }
140
141        #[automatically_derived]
142        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueGet for #subslice_impl<'__subslice_impl, #names> #where_clause  {
143            unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
144                self.slice.get_value_unchecked(index + self.range.start)
145            }
146        }
147
148        #[automatically_derived]
149        impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_gat> for #subslice_impl<'__subslice_impl, #names> #where_clause {
150            type Subslice = #subslice_impl<'__subslice_gat, #names>;
151        }
152
153        #[automatically_derived]
154        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_impl> for #input_ident #ty_generics #where_clause  {
155            type Subslice = #subslice_impl<'__subslice_impl, #names>;
156        }
157    };
158
159    for range_type in [
160        quote! { core::ops::Range<usize> },
161        quote! { core::ops::RangeFrom<usize> },
162        quote! { core::ops::RangeToInclusive<usize> },
163        quote! { core::ops::RangeFull },
164        quote! { core::ops::RangeInclusive<usize> },
165        quote! { core::ops::RangeTo<usize> },
166    ] {
167        res.extend(quote! {
168            #[automatically_derived]
169            impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRange<#range_type> for #input_ident #ty_generics #where_clause {
170                unsafe fn get_subslice_unchecked(
171                    &self,
172                    range: #range_type,
173                ) -> ::value_traits::slices::Subslice<'_, Self> {
174                    #subslice_impl {
175                        slice: &self,
176                        range: ::value_traits::slices::ComposeRange::compose(&range, 0..self.len()),
177                    }
178                }
179            }
180            #[automatically_derived]
181            impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<#range_type>
182                for #subslice_impl<'__subslice_impl, #names> #where_clause
183            {
184                unsafe fn get_subslice_unchecked(
185                    &self,
186                    range: #range_type,
187                ) -> ::value_traits::slices::Subslice<'_, Self> {
188                    #subslice_impl {
189                        slice: self.slice,
190                        range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
191                    }
192                }
193            }
194        });
195    }
196
197    res.into()
198}
199
200/// A derive macro fully implementing mutable subslices on top of a
201/// [`SliceByValueSet`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueSet.html)/[`SliceByValueRepl`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueRepl.html)
202/// for which the derive macro [`Subslices`] has been already applied.
203///
204/// The macro defines a structure `<YOUR TYPE>SubsliceImplMut` that keeps track
205/// of a mutable reference to a slice, and of the start and end of the subslice.
206/// `<YOUR TYPE>SubsliceImplMut` then implements
207/// [`SliceByValueGet`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueGet.html),
208/// [`SliceByValueSet`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueSet.html),
209/// [`SliceByValueRepl`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueRepl.html),
210/// [`SliceByValueSubslice`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueSubslice.html),
211/// and
212/// [`SliceByValueSubsliceMut`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueSubsliceMut.html).
213///
214/// Note that
215/// [`SliceByValueSubslice`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueSubslice.html)
216/// methods will return the `<YOUR TYPE>SubsliceImpl` structure generated by the
217/// [`Subslices`] macro.
218///
219/// ## Additional Bounds
220///
221/// Since this macro has no knowledge of the bounds of the generic parameters in
222/// the implementations of
223/// [`SliceByValue`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValue.html),
224/// [`SliceByValueSet`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueSet.html),
225/// and
226/// [`SliceByValueRepl`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueRepl.html),
227/// additional bounds with respect to the type declaration must be specified
228/// using the `#[value_trait_subslice_mut(bound = "<BOUND>")]` attribute.
229/// Multiple bounds can be specified with multiple attributes.
230#[proc_macro_derive(SubslicesMut, attributes(value_traits_subslices_mut))]
231pub fn subslices_mut(input: TokenStream) -> TokenStream {
232    let mut input = parse_macro_input!(input as DeriveInput);
233
234    // Extract and add additional bounds
235    let additional_bounds = extract_additional_bounds(&input, "value_traits_subslices_mut");
236    add_bounds_to_where_clause(&mut input.generics, additional_bounds);
237
238    let input_ident = input.ident;
239    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
240    let params = get_params_without_defaults(&input.generics);
241    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
242
243    let names = get_names(ty_generics_token_stream);
244    let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
245    let subslice_impl_mut = quote::format_ident!("{}SubsliceImplMut", input_ident);
246    let mut res = quote! {
247        #[automatically_derived]
248        pub struct #subslice_impl_mut<'__subslice_impl, #params> {
249            slice: &'__subslice_impl mut #input_ident #ty_generics,
250            range: ::core::ops::Range<usize>,
251        }
252
253        #[automatically_derived]
254        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValue for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
255            type Value = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
256
257            #[inline]
258            fn len(&self) -> usize {
259                self.range.len()
260            }
261        }
262
263        #[automatically_derived]
264        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueGet for #subslice_impl_mut<'__subslice_impl, #names> #where_clause  {
265            unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
266                self.slice.get_value_unchecked(index + self.range.start)
267            }
268        }
269
270        #[automatically_derived]
271        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSet for #subslice_impl_mut<'__subslice_impl, #names> #where_clause  {
272            unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
273                self.slice.set_value_unchecked(index + self.range.start, value)
274            }
275        }
276
277        #[automatically_derived]
278        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueRepl for #subslice_impl_mut<'__subslice_impl, #names> #where_clause  {
279            unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value {
280                self.slice.replace_value_unchecked(index + self.range.start, value)
281            }
282        }
283
284        #[automatically_derived]
285        impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_gat> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
286            type Subslice = #subslice_impl<'__subslice_gat, #names>;
287        }
288
289        #[automatically_derived]
290        impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGatMut<'__subslice_gat> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
291            type SubsliceMut = #subslice_impl_mut<'__subslice_gat, #names>;
292        }
293
294        #[automatically_derived]
295        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceGatMut<'__subslice_impl> for #input_ident #ty_generics #where_clause  {
296            type SubsliceMut = #subslice_impl_mut<'__subslice_impl, #names>;
297        }
298
299    };
300
301    for range_type in [
302        quote! { ::core::ops::Range<usize> },
303        quote! { ::core::ops::RangeFrom<usize> },
304        quote! { ::core::ops::RangeToInclusive<usize> },
305        quote! { ::core::ops::RangeFull },
306        quote! { ::core::ops::RangeInclusive<usize> },
307        quote! { ::core::ops::RangeTo<usize> },
308    ] {
309        // Impl subslice mut traits for the original type
310        res.extend(quote!{
311            #[automatically_derived]
312            impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRangeMut<#range_type> for #input_ident #ty_generics #where_clause {
313                unsafe fn get_subslice_unchecked_mut(
314                    &mut self,
315                    range: #range_type,
316                ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
317                    let len = self.len();
318                    #subslice_impl_mut {
319                        slice: self,
320                        range: ::value_traits::slices::ComposeRange::compose(&range, 0..len),
321                    }
322                }
323            }
324            #[automatically_derived]
325            impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<#range_type>
326                for #subslice_impl_mut<'__subslice_impl, #names> #where_clause
327            {
328                unsafe fn get_subslice_unchecked(
329                    &self,
330                    range: #range_type,
331                ) -> ::value_traits::slices::Subslice<'_, Self> {
332                    #subslice_impl {
333                        slice: &*self.slice,
334                        range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
335                    }
336                }
337            }
338            #[automatically_derived]
339            impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRangeMut<#range_type>
340                for #subslice_impl_mut<'__subslice_impl, #names> #where_clause
341            {
342                unsafe fn get_subslice_unchecked_mut(
343                    &mut self,
344                    range: #range_type,
345                ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
346                    #subslice_impl_mut {
347                        slice: self.slice,
348                        range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
349                    }
350                }
351            }
352        });
353    }
354
355    res.into()
356}
357
358/// A derive macro fully implementing
359/// [`IterateByValue`](https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValue.html)
360/// and
361/// [`IterateByValueFrom`](https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValueFrom.html)
362/// for subslices on top of a the `<YOUR TYPE>SubsliceImpl` structure generated
363/// by the derive macro [`Subslices`].
364///
365/// The macro defines a structure `<YOUR TYPE>Iter` that keeps track of a
366/// mutable reference to a slice and of a current iteration range; the structure
367/// is used to implement
368/// [`IterateByValue`](https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValue.html)
369/// and
370/// [`IterateByValueFrom`](https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValueFrom.html)
371/// on `<YOUR TYPE>SubsliceImpl`.
372///
373/// ## Additional Bounds
374///
375/// Since this macro has no knowledge of the bounds of the generic
376/// parameters in the implementations of
377/// [`SliceByValue`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValue.html)
378/// and
379/// [`SliceByValueGet`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueGet.html),
380/// additional bounds with respect to the type declaration must be specified
381/// using the `#[value_traits_iterators(bound = "<BOUND>")]` attribute. Multiple bounds can
382/// be specified with multiple attributes.
383#[proc_macro_derive(Iterators, attributes(value_traits_iterators))]
384pub fn iterators(input: TokenStream) -> TokenStream {
385    let mut input = parse_macro_input!(input as DeriveInput);
386
387    // Extract and add additional bounds
388    let additional_bounds = extract_additional_bounds(&input, "value_traits_iterators");
389    add_bounds_to_where_clause(&mut input.generics, additional_bounds);
390
391    let input_ident = input.ident;
392    input.generics.make_where_clause();
393    let (_impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
394    let params = get_params_without_defaults(&input.generics);
395    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
396
397    let names = get_names(ty_generics_token_stream);
398    let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
399    let iter = quote::format_ident!("{}Iter", input_ident);
400    quote! {
401        #[automatically_derived]
402        pub struct #iter<'__iter_ref, #params> {
403            subslice: &'__iter_ref #input_ident #ty_generics,
404            range: ::core::ops::Range<usize>,
405        }
406
407        #[automatically_derived]
408        impl<'__iter_ref, #params> #iter<'__iter_ref, #names> #where_clause {
409            pub fn new(subslice: &'__iter_ref #input_ident #ty_generics) -> Self {
410                let len = subslice.len();
411                Self {
412                    subslice,
413                    range: 0..len,
414                }
415            }
416            pub fn new_with_range(subslice: &'__iter_ref #input_ident #ty_generics, range: ::core::ops::Range<usize>) -> Self {
417                Self {
418                    subslice,
419                    range,
420                }
421            }
422        }
423
424        /*#[automatically_derived]
425        impl<#params> ::value_traits::iter::IterateByValue for #input_ident #ty_generics #where_clause {
426            type Item = <Self as ::value_traits::slices::SliceByValue>::Value;
427            type Iter<'__iter_ref>
428                = #iter<'__iter_ref, #names>
429            where
430                Self: '__iter_ref;
431
432            #[inline]
433            fn iter_value(&self) -> Self::Iter<'_> {
434                #iter::new(self)
435            }
436        }
437
438        #[automatically_derived]
439        impl<#params> ::value_traits::iter::IterateByValueFrom for #input_ident #ty_generics #where_clause {
440            type IterFrom<'__iter_ref>
441                = #iter<'__iter_ref, #names>
442            where
443                Self: '__iter_ref;
444
445            #[inline]
446            fn iter_value_from(&self, from: usize) -> Self::IterFrom<'_> {
447                let len = self.len();
448                assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
449                #iter::new_with_range(self, from..len)
450            }
451        }*/
452
453        #[automatically_derived]
454        /// Ideally we would like to also implement [`::core::iter::Iterator::advance_by`], but it is
455        /// nightly, and [`::core::iter::Iterator::skip`], [`::core::iter::Iterator::take`], [`::core::iter::Iterator::step_by`],
456        /// as we can do it more efficiently, but the [`::core::iter::Iterator`] trait definition
457        /// doesn't allow to return an arbitrary type.
458        impl<'__iter_ref, #params> ::core::iter::Iterator for #iter<'__iter_ref, #names> #where_clause {
459            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
460
461            #[inline]
462            fn next(&mut self) -> Option<Self::Item> {
463                if self.range.is_empty() {
464                    return ::core::option::Option::None;
465                }
466                let value = unsafe { self.subslice.get_value_unchecked(self.range.start) };
467                self.range.start += 1;
468                ::core::option::Option::Some(value)
469            }
470
471            /// Since we are indexing into a subslice, we can implement
472            /// [`::core::iter::Iterator::nth`] without needing to consume the first `n` elements.
473            #[inline]
474            fn nth(&mut self, n: usize) -> Option<Self::Item> {
475                if n >= self.range.end {
476                    self.range.start = self.range.end; // consume the ::core::iter::iterator
477                    return ::core::option::Option::None;
478                }
479                let value = unsafe { self.subslice.get_value_unchecked(self.range.start + n) };
480                self.range.start += n + 1;
481                ::core::option::Option::Some(value)
482            }
483
484            #[inline]
485            fn size_hint(&self) -> (usize, Option<usize>) {
486                let len = self.range.len();
487                (len, Some(len))
488            }
489        }
490
491        impl<'__iter_ref, #params> ::core::iter::DoubleEndedIterator for #iter<'__iter_ref, #names> #where_clause {
492            #[inline]
493            fn next_back(&mut self) -> Option<Self::Item> {
494                if self.range.is_empty() {
495                    return ::core::option::Option::None;
496                }
497                self.range.end -= 1;
498                let value = unsafe { self.subslice.get_value_unchecked(self.range.end) };
499                ::core::option::Option::Some(value)
500            }
501        }
502
503        impl<'__iter_ref, #params> ::core::iter::ExactSizeIterator for #iter<'__iter_ref, #names> #where_clause {
504            #[inline]
505            fn len(&self) -> usize {
506                self.range.len()
507            }
508        }
509
510        #[automatically_derived]
511        impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueGat<'__iter_ref> for #subslice_impl<'__subslice_impl, #names> #where_clause {
512            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
513            type Iter = #iter<'__iter_ref, #names>;
514        }
515
516        #[automatically_derived]
517        impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValue for #subslice_impl<'__subslice_impl, #names> #where_clause {
518            #[inline]
519            fn iter_value(&self) -> ::value_traits::iter::Iter<'_, Self> {
520                #iter::new(self.slice)
521            }
522        }
523
524        #[automatically_derived]
525        impl<'__subslice_impl, '__iter_ref,#params> ::value_traits::iter::IterateByValueFromGat<'__iter_ref> for #subslice_impl<'__subslice_impl, #names> #where_clause {
526            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
527            type IterFrom = #iter<'__iter_ref, #names>;
528        }
529
530        #[automatically_derived]
531        impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValueFrom for #subslice_impl<'__subslice_impl, #names> #where_clause {
532            #[inline]
533            fn iter_value_from(&self, from: usize) -> ::value_traits::iter::IterFrom<'_, Self> {
534                let len = self.len();
535                assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
536                let range = ::value_traits::slices::ComposeRange::compose(&(from..), self.range.clone());
537                #iter::new_with_range(self.slice, range)
538            }
539        }
540    }.into()
541}
542
543/// A derive macro that implements
544/// [`IterateByValue`](https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValue.html)
545/// and
546/// [`IterateByValueFrom`](https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValueFrom.html)
547/// for mutable subslices on top of the `<YOUR TYPE>SubsliceImplMut` structure
548/// generated by the derive macro [`SubslicesMut`].
549///
550/// To call this macro, you first need to derive both [`SubslicesMut`] and
551/// [`Iterators`] on the same struct, as this macro uses the `<YOUR TYPE>Iter`
552/// structure defined by [`Iterators`].
553///
554/// ## Additional Bounds
555///
556/// Since this macro has no knowledge of the bounds of the generic parameters in
557/// the implementations of
558/// [`SliceByValue`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValue.html),
559/// [`SliceByValueSet`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueSet.html),
560/// and
561/// [`SliceByValueRepl`](https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueRepl.html),
562/// additional bounds with respect to the type declaration must be specified
563/// using the `#[value_traits_iterators_mut(bound = "<BOUND>")]` attribute.
564/// Multiple bounds can be specified with multiple attributes.
565#[proc_macro_derive(IteratorsMut, attributes(value_traits_iterators_mut))]
566pub fn iterators_mut(input: TokenStream) -> TokenStream {
567    let mut input = parse_macro_input!(input as DeriveInput);
568
569    // Extract and add additional bounds
570    let additional_bounds = extract_additional_bounds(&input, "value_traits_iterators_mut");
571    add_bounds_to_where_clause(&mut input.generics, additional_bounds);
572
573    let input_ident = input.ident;
574    input.generics.make_where_clause();
575    let (_impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
576    let params = get_params_without_defaults(&input.generics);
577    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
578
579    let names = get_names(ty_generics_token_stream);
580    let subslice_impl_mut = quote::format_ident!("{}SubsliceImplMut", input_ident);
581    let iter = quote::format_ident!("{}Iter", input_ident);
582    quote!{
583        #[automatically_derived]
584        impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueGat<'__iter_ref> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
585            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
586            type Iter = #iter<'__iter_ref, #names>;
587        }
588
589        #[automatically_derived]
590        impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValue for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
591            fn iter_value(&self) -> ::value_traits::iter::Iter<'_, Self> {
592                #iter::new(self.slice)
593            }
594        }
595
596        #[automatically_derived]
597        impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueFromGat<'__iter_ref> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
598            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
599            type IterFrom = #iter<'__iter_ref, #names>;
600        }
601
602        #[automatically_derived]
603        impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValueFrom for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
604            fn iter_value_from(&self, from: usize) -> ::value_traits::iter::IterFrom<'_, Self> {
605                let len = self.len();
606                assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
607                let range = ::value_traits::slices::ComposeRange::compose(&(from..), self.range.clone());
608                #iter::new_with_range(self.slice, range)
609            }
610        }
611    }.into()
612}