Skip to main content

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`] crate.
14//!
15//! [`value-traits`]: https://docs.rs/value-traits/latest/value_traits/
16
17use proc_macro::TokenStream;
18use quote::{ToTokens, quote};
19use syn::{
20    AngleBracketedGenericArguments, DeriveInput, parse_macro_input, parse2, punctuated::Punctuated,
21};
22
23/// Helper function returning the list of parameter names without angle brackets.
24fn get_names(ty_generics_token_stream: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
25    if ty_generics_token_stream.is_empty() {
26        proc_macro2::TokenStream::new()
27    } else {
28        let parsed_args: AngleBracketedGenericArguments =
29            parse2(ty_generics_token_stream)
30                .expect("Failed to parse ty_generics into AngleBracketedGenericArguments. This indicates an unexpected structure in the generic parameters.");
31
32        parsed_args.args.into_token_stream()
33    }
34}
35
36/// Helper function to extract additional bounds from attributes
37fn extract_additional_bounds(
38    input: &DeriveInput,
39    attr_name: &str,
40) -> Vec<proc_macro2::TokenStream> {
41    let mut additional_bounds = Vec::new();
42    for attr in &input.attrs {
43        if attr.path().is_ident(attr_name) {
44            attr.parse_nested_meta(|meta| {
45                if meta.path.is_ident("bound") {
46                    let bound: syn::LitStr = meta.value()?.parse()?;
47                    let bound_tokens: proc_macro2::TokenStream =
48                        bound.value().parse().expect("Failed to parse bound");
49                    additional_bounds.push(bound_tokens);
50                }
51                Ok(())
52            })
53            .unwrap_or_else(|e| panic!("Failed to parse attribute {attr_name}: {e}"));
54        }
55    }
56    additional_bounds
57}
58
59/// Helper function to add additional bounds to a where clause
60fn add_bounds_to_where_clause(
61    generics: &mut syn::Generics,
62    additional_bounds: Vec<proc_macro2::TokenStream>,
63) {
64    if !additional_bounds.is_empty() {
65        let where_clause = generics.make_where_clause();
66        for bound in additional_bounds {
67            let predicate: syn::WherePredicate =
68                syn::parse2(bound).expect("Invalid where predicate");
69            where_clause.predicates.push(predicate);
70        }
71    }
72}
73
74fn get_params_without_defaults(
75    generics: &syn::Generics,
76) -> Punctuated<syn::GenericParam, syn::token::Comma> {
77    // Remove default type parameters
78    let mut params = generics.params.clone();
79    params.iter_mut().for_each(|param| match param {
80        syn::GenericParam::Type(ty_param) => {
81            ty_param.default = None;
82        }
83        syn::GenericParam::Const(const_param) => {
84            const_param.default = None;
85        }
86        _ => {}
87    });
88    params
89}
90
91/// A derive macro fully implementing subslices on top of a [`SliceByValue`].
92///
93/// The macro defines a structure `<YOUR TYPE>SubsliceImpl` that keeps track of
94/// a reference to a slice, and of the start and end of the subslice.
95/// `<YOUR TYPE>SubsliceImpl` then implements [`SliceByValue`] and
96/// [`SliceByValueSubslice`].
97///
98/// The generated structure has the same visibility as the type the macro is
99/// applied to.
100///
101/// ## Additional Bounds
102///
103/// Since this macro has no knowledge of the bounds of the generic
104/// parameters in the implementations of [`SliceByValue`],
105/// additional bounds with respect to the type declaration must be specified
106/// using the `#[value_traits_subslices(bound = "<BOUND>")]` attribute. Multiple bounds can
107/// be specified with multiple attributes.
108///
109/// [`SliceByValue`]: https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValue.html
110/// [`SliceByValueSubslice`]: https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueSubslice.html
111#[proc_macro_derive(Subslices, attributes(value_traits_subslices))]
112pub fn subslices(input: TokenStream) -> TokenStream {
113    let mut input = parse_macro_input!(input as DeriveInput);
114
115    // Extract and add additional bounds
116    let additional_bounds = extract_additional_bounds(&input, "value_traits_subslices");
117    add_bounds_to_where_clause(&mut input.generics, additional_bounds);
118
119    let visibility = input.vis;
120    let input_ident = input.ident;
121    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
122    let params = get_params_without_defaults(&input.generics);
123    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
124
125    let names = get_names(ty_generics_token_stream);
126    let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
127    let mut res = quote! {
128        #[automatically_derived]
129        #[doc = concat!("Read-only subslice of [`", stringify!(#input_ident), "`] generated by the `Subslices` derive macro.")]
130        #visibility struct #subslice_impl<'__subslice_impl, #params> {
131            slice: &'__subslice_impl #input_ident #ty_generics,
132            range: ::core::ops::Range<usize>,
133        }
134
135        #[automatically_derived]
136        impl<'__subslice_impl, #params> ::core::clone::Clone for #subslice_impl<'__subslice_impl, #names> #where_clause {
137            fn clone(&self) -> Self {
138                Self {
139                    slice: self.slice,
140                    range: ::core::clone::Clone::clone(&self.range),
141                }
142            }
143        }
144
145        #[automatically_derived]
146        impl<'__subslice_impl, #params> ::core::fmt::Debug for #subslice_impl<'__subslice_impl, #names> #where_clause {
147            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
148                f.debug_struct(stringify!(#subslice_impl))
149                    .field("range", &self.range)
150                    .finish_non_exhaustive()
151            }
152        }
153
154        #[automatically_derived]
155        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValue for #subslice_impl<'__subslice_impl, #names> #where_clause {
156            type Value = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
157
158            #[inline]
159            fn len(&self) -> usize {
160                self.range.len()
161            }
162
163            unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
164                // SAFETY: the invariant of this structure guarantees that
165                // `range` is within the bounds of `slice`; the caller
166                // guarantees that `index` is within the bounds of `range`.
167                unsafe {
168                    ::value_traits::slices::SliceByValue::get_value_unchecked(
169                        self.slice,
170                        index + self.range.start,
171                    )
172                }
173            }
174        }
175
176        #[automatically_derived]
177        impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_gat> for #subslice_impl<'__subslice_impl, #names> #where_clause {
178            type Subslice = #subslice_impl<'__subslice_gat, #names>;
179        }
180
181        #[automatically_derived]
182        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_impl> for #input_ident #ty_generics #where_clause  {
183            type Subslice = #subslice_impl<'__subslice_impl, #names>;
184        }
185    };
186
187    for range_type in [
188        quote! { ::core::ops::Range<usize> },
189        quote! { ::core::ops::RangeFrom<usize> },
190        quote! { ::core::ops::RangeToInclusive<usize> },
191        quote! { ::core::ops::RangeFull },
192        quote! { ::core::ops::RangeInclusive<usize> },
193        quote! { ::core::ops::RangeTo<usize> },
194    ] {
195        res.extend(quote! {
196            #[automatically_derived]
197            impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRange<#range_type> for #input_ident #ty_generics #where_clause {
198                unsafe fn get_subslice_unchecked(
199                    &self,
200                    range: #range_type,
201                ) -> ::value_traits::slices::Subslice<'_, Self> {
202                    #subslice_impl {
203                        slice: self,
204                        range: ::value_traits::slices::ComposeRange::compose(
205                            &range,
206                            0..::value_traits::slices::SliceByValue::len(self),
207                        ),
208                    }
209                }
210            }
211            #[automatically_derived]
212            impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<#range_type>
213                for #subslice_impl<'__subslice_impl, #names> #where_clause
214            {
215                unsafe fn get_subslice_unchecked(
216                    &self,
217                    range: #range_type,
218                ) -> ::value_traits::slices::Subslice<'_, Self> {
219                    #subslice_impl {
220                        slice: self.slice,
221                        range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
222                    }
223                }
224            }
225        });
226    }
227
228    res.into()
229}
230
231/// A derive macro fully implementing mutable subslices on top of a
232/// [`SliceByValueMut`] for which the derive macro [`Subslices`] has been
233/// already applied.
234///
235/// The macro defines a structure `<YOUR TYPE>SubsliceImplMut` that keeps track
236/// of a mutable reference to a slice, and of the start and end of the subslice.
237/// `<YOUR TYPE>SubsliceImplMut` then implements [`SliceByValueMut`],
238/// [`SliceByValueSubslice`], and [`SliceByValueSubsliceMut`].
239///
240/// The generated structure has the same visibility as the type the macro is
241/// applied to.
242///
243/// Note that [`SliceByValueSubslice`] methods will return the
244/// `<YOUR TYPE>SubsliceImpl` structure generated by the [`Subslices`] macro.
245///
246/// ## Chunks
247///
248/// Presently, [`try_chunks_mut`] is not supported.
249///
250/// ## Additional Bounds
251///
252/// Since this macro has no knowledge of the bounds of the generic parameters in
253/// the implementations of [`SliceByValue`] and [`SliceByValueMut`],
254/// additional bounds with respect to the type declaration must be specified
255/// using the `#[value_traits_subslices_mut(bound = "<BOUND>")]` attribute.
256/// Multiple bounds can be specified with multiple attributes.
257///
258/// [`SliceByValue`]: https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValue.html
259/// [`SliceByValueMut`]: https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueMut.html
260/// [`SliceByValueSubslice`]: https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueSubslice.html
261/// [`SliceByValueSubsliceMut`]: https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueSubsliceMut.html
262/// [`try_chunks_mut`]: https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueMut.html#method.try_chunks_mut
263#[proc_macro_derive(SubslicesMut, attributes(value_traits_subslices_mut))]
264pub fn subslices_mut(input: TokenStream) -> TokenStream {
265    let mut input = parse_macro_input!(input as DeriveInput);
266
267    // Extract and add additional bounds
268    let additional_bounds = extract_additional_bounds(&input, "value_traits_subslices_mut");
269    add_bounds_to_where_clause(&mut input.generics, additional_bounds);
270
271    let visibility = input.vis;
272    let input_ident = input.ident;
273    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
274    let params = get_params_without_defaults(&input.generics);
275    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
276
277    let names = get_names(ty_generics_token_stream);
278    let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
279    let subslice_impl_mut = quote::format_ident!("{}SubsliceImplMut", input_ident);
280    let mut res = quote! {
281        #[automatically_derived]
282        #[doc = concat!("Mutable subslice of [`", stringify!(#input_ident), "`] generated by the `SubslicesMut` derive macro.")]
283        #visibility struct #subslice_impl_mut<'__subslice_impl, #params> {
284            slice: &'__subslice_impl mut #input_ident #ty_generics,
285            range: ::core::ops::Range<usize>,
286        }
287
288        #[automatically_derived]
289        impl<'__subslice_impl, #params> ::core::fmt::Debug for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
290            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
291                f.debug_struct(stringify!(#subslice_impl_mut))
292                    .field("range", &self.range)
293                    .finish_non_exhaustive()
294            }
295        }
296
297        #[automatically_derived]
298        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValue for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
299            type Value = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
300
301            #[inline]
302            fn len(&self) -> usize {
303                self.range.len()
304            }
305
306            unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
307                // SAFETY: the invariant of this structure guarantees that
308                // `range` is within the bounds of `slice`; the caller
309                // guarantees that `index` is within the bounds of `range`.
310                unsafe {
311                    ::value_traits::slices::SliceByValue::get_value_unchecked(
312                        &*self.slice,
313                        index + self.range.start,
314                    )
315                }
316            }
317        }
318
319
320        #[automatically_derived]
321        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueMut for #subslice_impl_mut<'__subslice_impl, #names> #where_clause  {
322            unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
323                // SAFETY: the invariant of this structure guarantees that
324                // `range` is within the bounds of `slice`; the caller
325                // guarantees that `index` is within the bounds of `range`.
326                unsafe {
327                    ::value_traits::slices::SliceByValueMut::set_value_unchecked(
328                        &mut *self.slice,
329                        index + self.range.start,
330                        value,
331                    )
332                }
333            }
334
335            unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value {
336                // SAFETY: the invariant of this structure guarantees that
337                // `range` is within the bounds of `slice`; the caller
338                // guarantees that `index` is within the bounds of `range`.
339                unsafe {
340                    ::value_traits::slices::SliceByValueMut::replace_value_unchecked(
341                        &mut *self.slice,
342                        index + self.range.start,
343                        value,
344                    )
345                }
346            }
347
348            type ChunksMut<'a> = ::core::iter::Empty<&'a mut Self>
349            where
350                Self: 'a;
351
352            type ChunksMutError = ::value_traits::slices::ChunksMutNotSupported;
353
354            fn try_chunks_mut(&mut self, _chunk_size: usize) -> Result<Self::ChunksMut<'_>, Self::ChunksMutError> {
355                // Derived subslice types cannot provide mutable chunks
356                Err(::value_traits::slices::ChunksMutNotSupported)
357            }
358        }
359
360        #[automatically_derived]
361        impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_gat> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
362            type Subslice = #subslice_impl<'__subslice_gat, #names>;
363        }
364
365        #[automatically_derived]
366        impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGatMut<'__subslice_gat> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
367            type SubsliceMut = #subslice_impl_mut<'__subslice_gat, #names>;
368        }
369
370        #[automatically_derived]
371        impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceGatMut<'__subslice_impl> for #input_ident #ty_generics #where_clause  {
372            type SubsliceMut = #subslice_impl_mut<'__subslice_impl, #names>;
373        }
374
375    };
376
377    for range_type in [
378        quote! { ::core::ops::Range<usize> },
379        quote! { ::core::ops::RangeFrom<usize> },
380        quote! { ::core::ops::RangeToInclusive<usize> },
381        quote! { ::core::ops::RangeFull },
382        quote! { ::core::ops::RangeInclusive<usize> },
383        quote! { ::core::ops::RangeTo<usize> },
384    ] {
385        // Impl subslice mut traits for the original type
386        res.extend(quote!{
387            #[automatically_derived]
388            impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRangeMut<#range_type> for #input_ident #ty_generics #where_clause {
389                unsafe fn get_subslice_unchecked_mut(
390                    &mut self,
391                    range: #range_type,
392                ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
393                    let len = ::value_traits::slices::SliceByValue::len(&*self);
394                    #subslice_impl_mut {
395                        slice: self,
396                        range: ::value_traits::slices::ComposeRange::compose(&range, 0..len),
397                    }
398                }
399            }
400            #[automatically_derived]
401            impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<#range_type>
402                for #subslice_impl_mut<'__subslice_impl, #names> #where_clause
403            {
404                unsafe fn get_subslice_unchecked(
405                    &self,
406                    range: #range_type,
407                ) -> ::value_traits::slices::Subslice<'_, Self> {
408                    #subslice_impl {
409                        slice: &*self.slice,
410                        range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
411                    }
412                }
413            }
414            #[automatically_derived]
415            impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRangeMut<#range_type>
416                for #subslice_impl_mut<'__subslice_impl, #names> #where_clause
417            {
418                unsafe fn get_subslice_unchecked_mut(
419                    &mut self,
420                    range: #range_type,
421                ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
422                    #subslice_impl_mut {
423                        slice: self.slice,
424                        range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
425                    }
426                }
427            }
428        });
429    }
430
431    res.into()
432}
433
434/// A derive macro fully implementing [`IterateByValue`] and
435/// [`IterateByValueFrom`] for subslices on top of the
436/// `<YOUR TYPE>SubsliceImpl` structure generated by the derive macro
437/// [`Subslices`].
438///
439/// The macro defines a structure `<YOUR TYPE>Iter` that keeps track of a
440/// reference to a slice and of a current iteration range; the structure is
441/// used to implement [`IterateByValue`] and [`IterateByValueFrom`] on
442/// `<YOUR TYPE>SubsliceImpl`.
443///
444/// Note that the traits are implemented on `<YOUR TYPE>SubsliceImpl`, not on
445/// `<YOUR TYPE>` itself: to iterate over the whole slice, take first a full
446/// subslice with `index_subslice(..)`.
447///
448/// The generated structure has the same visibility as the type the macro is
449/// applied to.
450///
451/// ## Additional Bounds
452///
453/// Since this macro has no knowledge of the bounds of the generic
454/// parameters in the implementations of [`SliceByValue`],
455/// additional bounds with respect to the type declaration must be specified
456/// using the `#[value_traits_iterators(bound = "<BOUND>")]` attribute. Multiple bounds can
457/// be specified with multiple attributes.
458///
459/// [`SliceByValue`]: https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValue.html
460/// [`IterateByValue`]: https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValue.html
461/// [`IterateByValueFrom`]: https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValueFrom.html
462#[proc_macro_derive(Iterators, attributes(value_traits_iterators))]
463pub fn iterators(input: TokenStream) -> TokenStream {
464    let mut input = parse_macro_input!(input as DeriveInput);
465
466    // Extract and add additional bounds
467    let additional_bounds = extract_additional_bounds(&input, "value_traits_iterators");
468    add_bounds_to_where_clause(&mut input.generics, additional_bounds);
469
470    let visibility = input.vis;
471    let input_ident = input.ident;
472    input.generics.make_where_clause();
473    let (_impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
474    let params = get_params_without_defaults(&input.generics);
475    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
476
477    let names = get_names(ty_generics_token_stream);
478    let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
479    let iter = quote::format_ident!("{}Iter", input_ident);
480    // Ideally we would also implement `Iterator::advance_by`, but it is
481    // nightly, and `Iterator::skip`, `Iterator::take`, and
482    // `Iterator::step_by`, as we could do it more efficiently, but the
483    // `Iterator` trait definition does not allow to return an arbitrary type.
484    quote! {
485        #[automatically_derived]
486        #[doc = concat!("By-value iterator over [`", stringify!(#input_ident), "`] generated by the `Iterators` derive macro.")]
487        #visibility struct #iter<'__iter_ref, #params> {
488            subslice: &'__iter_ref #input_ident #ty_generics,
489            range: ::core::ops::Range<usize>,
490        }
491
492        #[automatically_derived]
493        impl<'__iter_ref, #params> ::core::clone::Clone for #iter<'__iter_ref, #names> #where_clause {
494            fn clone(&self) -> Self {
495                Self {
496                    subslice: self.subslice,
497                    range: ::core::clone::Clone::clone(&self.range),
498                }
499            }
500        }
501
502        #[automatically_derived]
503        impl<'__iter_ref, #params> ::core::fmt::Debug for #iter<'__iter_ref, #names> #where_clause {
504            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
505                f.debug_struct(stringify!(#iter))
506                    .field("range", &self.range)
507                    .finish_non_exhaustive()
508            }
509        }
510
511        #[automatically_derived]
512        impl<'__iter_ref, #params> #iter<'__iter_ref, #names> #where_clause {
513            /// Creates a new iterator over all the elements of the given
514            /// slice.
515            #visibility fn new(subslice: &'__iter_ref #input_ident #ty_generics) -> Self {
516                let len = ::value_traits::slices::SliceByValue::len(subslice);
517                Self {
518                    subslice,
519                    range: 0..len,
520                }
521            }
522
523            /// Creates a new iterator over the elements of the given slice
524            /// whose indices are in the given range.
525            ///
526            /// # Panics
527            ///
528            /// This method will panic if the range is not within the bounds
529            /// of the slice.
530            #visibility fn new_with_range(subslice: &'__iter_ref #input_ident #ty_generics, range: ::core::ops::Range<usize>) -> Self {
531                let len = ::value_traits::slices::SliceByValue::len(subslice);
532                assert!(
533                    range.start <= range.end && range.end <= len,
534                    "range {range:?} out of range for slice of length {len}",
535                );
536                Self {
537                    subslice,
538                    range,
539                }
540            }
541        }
542
543        #[automatically_derived]
544        impl<'__iter_ref, #params> ::core::iter::Iterator for #iter<'__iter_ref, #names> #where_clause {
545            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
546
547            #[inline]
548            fn next(&mut self) -> Option<Self::Item> {
549                if self.range.is_empty() {
550                    return ::core::option::Option::None;
551                }
552                // SAFETY: the invariant of this structure guarantees that
553                // `range` is within the bounds of `subslice`, and the range
554                // is not empty.
555                let value = unsafe {
556                    ::value_traits::slices::SliceByValue::get_value_unchecked(self.subslice, self.range.start)
557                };
558                self.range.start += 1;
559                ::core::option::Option::Some(value)
560            }
561
562            // Since we are indexing into a subslice, we can implement `nth`
563            // without needing to consume the first `n` elements.
564            #[inline]
565            fn nth(&mut self, n: usize) -> Option<Self::Item> {
566                if n >= self.range.len() {
567                    self.range.start = self.range.end; // consume the iterator
568                    return ::core::option::Option::None;
569                }
570                // SAFETY: the invariant of this structure guarantees that
571                // `range` is within the bounds of `subslice`, and n <
572                // `range.len()`.
573                let value = unsafe {
574                    ::value_traits::slices::SliceByValue::get_value_unchecked(self.subslice, self.range.start + n)
575                };
576                self.range.start += n + 1;
577                ::core::option::Option::Some(value)
578            }
579
580            #[inline]
581            fn size_hint(&self) -> (usize, Option<usize>) {
582                let len = self.range.len();
583                (len, Some(len))
584            }
585
586            #[inline]
587            fn count(self) -> usize {
588                self.range.len()
589            }
590
591            #[inline]
592            fn last(self) -> ::core::option::Option<Self::Item> {
593                if self.range.is_empty() {
594                    return ::core::option::Option::None;
595                }
596                // SAFETY: the invariant of this structure guarantees that
597                // `range` is within the bounds of `subslice`, and the range
598                // is not empty.
599                ::core::option::Option::Some(unsafe {
600                    ::value_traits::slices::SliceByValue::get_value_unchecked(self.subslice, self.range.end - 1)
601                })
602            }
603
604            fn fold<__FoldB, __FoldF>(self, init: __FoldB, mut f: __FoldF) -> __FoldB
605            where
606                __FoldF: FnMut(__FoldB, Self::Item) -> __FoldB,
607            {
608                let subslice = self.subslice;
609                let mut acc = init;
610                for idx in self.range {
611                    // SAFETY: the invariant of this structure guarantees that
612                    // `range` is within the bounds of `subslice`.
613                    acc = f(acc, unsafe {
614                        ::value_traits::slices::SliceByValue::get_value_unchecked(subslice, idx)
615                    });
616                }
617                acc
618            }
619
620            fn for_each<__ForEachF>(self, mut f: __ForEachF)
621            where
622                __ForEachF: FnMut(Self::Item),
623            {
624                let subslice = self.subslice;
625                for idx in self.range {
626                    // SAFETY: the invariant of this structure guarantees that
627                    // `range` is within the bounds of `subslice`.
628                    f(unsafe {
629                        ::value_traits::slices::SliceByValue::get_value_unchecked(subslice, idx)
630                    });
631                }
632            }
633        }
634
635        #[automatically_derived]
636        impl<'__iter_ref, #params> ::core::iter::DoubleEndedIterator for #iter<'__iter_ref, #names> #where_clause {
637            #[inline]
638            fn next_back(&mut self) -> Option<Self::Item> {
639                if self.range.is_empty() {
640                    return ::core::option::Option::None;
641                }
642                self.range.end -= 1;
643                // SAFETY: the invariant of this structure guarantees that
644                // `range` is within the bounds of `subslice`, and the range
645                // was not empty.
646                let value = unsafe {
647                    ::value_traits::slices::SliceByValue::get_value_unchecked(self.subslice, self.range.end)
648                };
649                ::core::option::Option::Some(value)
650            }
651
652            #[inline]
653            fn nth_back(&mut self, n: usize) -> ::core::option::Option<Self::Item> {
654                if n >= self.range.len() {
655                    self.range.end = self.range.start;
656                    return ::core::option::Option::None;
657                }
658                self.range.end -= n + 1;
659                // SAFETY: the invariant of this structure guarantees that
660                // `range` is within the bounds of `subslice`, and n <
661                // `range.len()`.
662                ::core::option::Option::Some(unsafe {
663                    ::value_traits::slices::SliceByValue::get_value_unchecked(self.subslice, self.range.end)
664                })
665            }
666
667            fn rfold<__RFoldB, __RFoldF>(self, init: __RFoldB, mut f: __RFoldF) -> __RFoldB
668            where
669                __RFoldF: FnMut(__RFoldB, Self::Item) -> __RFoldB,
670            {
671                let subslice = self.subslice;
672                let mut acc = init;
673                for idx in self.range.rev() {
674                    // SAFETY: the invariant of this structure guarantees that
675                    // `range` is within the bounds of `subslice`.
676                    acc = f(acc, unsafe {
677                        ::value_traits::slices::SliceByValue::get_value_unchecked(subslice, idx)
678                    });
679                }
680                acc
681            }
682        }
683
684        #[automatically_derived]
685        impl<'__iter_ref, #params> ::core::iter::ExactSizeIterator for #iter<'__iter_ref, #names> #where_clause {
686            #[inline]
687            fn len(&self) -> usize {
688                self.range.len()
689            }
690        }
691
692        #[automatically_derived]
693        impl<'__iter_ref, #params> ::core::iter::FusedIterator for #iter<'__iter_ref, #names> #where_clause {}
694
695        #[automatically_derived]
696        impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueGat<'__iter_ref> for #subslice_impl<'__subslice_impl, #names> #where_clause {
697            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
698            type Iter = #iter<'__iter_ref, #names>;
699        }
700
701        #[automatically_derived]
702        impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValue for #subslice_impl<'__subslice_impl, #names> #where_clause {
703            #[inline]
704            fn iter_value(&self) -> ::value_traits::iter::Iter<'_, Self> {
705                // The invariant of the subslice guarantees that `range` is
706                // within the bounds of `slice`.
707                #iter {
708                    subslice: self.slice,
709                    range: self.range.clone(),
710                }
711            }
712        }
713
714        #[automatically_derived]
715        impl<'__subslice_impl, '__iter_ref,#params> ::value_traits::iter::IterateByValueFromGat<'__iter_ref> for #subslice_impl<'__subslice_impl, #names> #where_clause {
716            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
717            type IterFrom = #iter<'__iter_ref, #names>;
718        }
719
720        #[automatically_derived]
721        impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValueFrom for #subslice_impl<'__subslice_impl, #names> #where_clause {
722            #[inline]
723            fn iter_value_from(&self, from: usize) -> ::value_traits::iter::IterFrom<'_, Self> {
724                let len = ::value_traits::slices::SliceByValue::len(self);
725                assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
726                // The invariant of the subslice guarantees that `range` is
727                // within the bounds of `slice`, and `from <= range.len()`, so
728                // the composed range is within the bounds of `slice`, too.
729                #iter {
730                    subslice: self.slice,
731                    range: ::value_traits::slices::ComposeRange::compose(&(from..), self.range.clone()),
732                }
733            }
734        }
735    }.into()
736}
737
738/// A derive macro that implements [`IterateByValue`] and
739/// [`IterateByValueFrom`] for mutable subslices on top of the
740/// `<YOUR TYPE>SubsliceImplMut` structure generated by the derive macro
741/// [`SubslicesMut`].
742///
743/// To call this macro, you first need to derive both [`SubslicesMut`] and
744/// [`Iterators`] on the same struct, as this macro uses the `<YOUR TYPE>Iter`
745/// structure defined by [`Iterators`].
746///
747/// ## Additional Bounds
748///
749/// Since this macro has no knowledge of the bounds of the generic parameters in
750/// the implementations of [`SliceByValue`] and [`SliceByValueMut`],
751/// additional bounds with respect to the type declaration must be specified
752/// using the `#[value_traits_iterators_mut(bound = "<BOUND>")]` attribute.
753/// Multiple bounds can be specified with multiple attributes.
754///
755/// [`SliceByValue`]: https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValue.html
756/// [`SliceByValueMut`]: https://docs.rs/value-traits/latest/value_traits/slices/trait.SliceByValueMut.html
757/// [`IterateByValue`]: https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValue.html
758/// [`IterateByValueFrom`]: https://docs.rs/value-traits/latest/value_traits/iter/trait.IterateByValueFrom.html
759#[proc_macro_derive(IteratorsMut, attributes(value_traits_iterators_mut))]
760pub fn iterators_mut(input: TokenStream) -> TokenStream {
761    let mut input = parse_macro_input!(input as DeriveInput);
762
763    // Extract and add additional bounds
764    let additional_bounds = extract_additional_bounds(&input, "value_traits_iterators_mut");
765    add_bounds_to_where_clause(&mut input.generics, additional_bounds);
766
767    let input_ident = input.ident;
768    input.generics.make_where_clause();
769    let (_impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
770    let params = get_params_without_defaults(&input.generics);
771    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
772
773    let names = get_names(ty_generics_token_stream);
774    let subslice_impl_mut = quote::format_ident!("{}SubsliceImplMut", input_ident);
775    let iter = quote::format_ident!("{}Iter", input_ident);
776    quote!{
777        #[automatically_derived]
778        impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueGat<'__iter_ref> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
779            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
780            type Iter = #iter<'__iter_ref, #names>;
781        }
782
783        #[automatically_derived]
784        impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValue for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
785            fn iter_value(&self) -> ::value_traits::iter::Iter<'_, Self> {
786                // The invariant of the subslice guarantees that `range` is
787                // within the bounds of `slice`.
788                #iter {
789                    subslice: &*self.slice,
790                    range: self.range.clone(),
791                }
792            }
793        }
794
795        #[automatically_derived]
796        impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueFromGat<'__iter_ref> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
797            type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
798            type IterFrom = #iter<'__iter_ref, #names>;
799        }
800
801        #[automatically_derived]
802        impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValueFrom for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
803            fn iter_value_from(&self, from: usize) -> ::value_traits::iter::IterFrom<'_, Self> {
804                let len = ::value_traits::slices::SliceByValue::len(self);
805                assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
806                // The invariant of the subslice guarantees that `range` is
807                // within the bounds of `slice`, and `from <= range.len()`, so
808                // the composed range is within the bounds of `slice`, too.
809                #iter {
810                    subslice: &*self.slice,
811                    range: ::value_traits::slices::ComposeRange::compose(&(from..), self.range.clone()),
812                }
813            }
814        }
815    }.into()
816}