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
9use proc_macro::TokenStream;
10use quote::{quote, ToTokens};
11use syn::{parse2, parse_macro_input, AngleBracketedGenericArguments, Data, DeriveInput};
12
13/// A procedural macro fully implementing subslices on top of a
14/// [`SliceByValueGet`].
15///
16/// The macro defines a structure `SubsliceImpl` that keeps track of a reference
17/// to a slice, and of the start and end of the subslice. `SubsliceImpl` then
18/// implements [`SliceByValueGet`] and [`SliceByValueSubslice`].
19#[proc_macro_derive(Subslices)]
20pub fn subslices(input: TokenStream) -> TokenStream {
21    let mut input = parse_macro_input!(input as DeriveInput);
22
23    let input_ident = input.ident;
24    input.generics.make_where_clause();
25    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
26    let params = &input.generics.params;
27    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
28
29    let names: proc_macro2::TokenStream = {
30        if ty_generics_token_stream.is_empty() {
31            // If the original struct has no generics (e.g., struct MyStruct;),
32            // then ty_generics is empty, and we want an empty stream.
33            proc_macro2::TokenStream::new()
34        } else {
35            // 2. Parse this TokenStream into a syn::AngleBracketedGenericArguments.
36            //    This syn type represents the `T, A, B` arguments enclosed in angle brackets.
37            let parsed_args: AngleBracketedGenericArguments =
38                parse2(ty_generics_token_stream)
39                    .expect("Failed to parse ty_generics into AngleBracketedGenericArguments. This indicates an unexpected structure in the generic parameters.");
40
41            // 3. The `args` field of AngleBracketedGenericArguments is a Punctuated list
42            //    (Punctuated<GenericArgument, Comma>) containing just the T, A, B.
43            //    When you convert this Punctuated list to a TokenStream, it will
44            //    automatically produce the comma-separated tokens without angle brackets.
45            parsed_args.args.into_token_stream()
46        }
47    };
48    match input.data {
49        Data::Struct(_) => {
50            quote! {
51                #[automatically_derived]
52                pub struct SubsliceImpl<'__subslice_impl, #params> {
53                    slice: &'__subslice_impl #input_ident #ty_generics,
54                    start: usize,
55                    end: usize,
56                }
57
58                #[automatically_derived]
59                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValue for SubsliceImpl<'__subslice_impl, #names> #where_clause {
60                    type Value = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
61
62                    #[inline]
63                    fn len(&self) -> usize {
64                        self.end - self.start
65                    }
66                }
67
68                #[automatically_derived]
69                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueGet for SubsliceImpl<'__subslice_impl, #names> #where_clause  {
70                    unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
71                        self.slice.get_value_unchecked(index + self.start)
72                    }
73                }
74
75                #[automatically_derived]
76                impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_gat> for SubsliceImpl<'__subslice_impl, #names> #where_clause {
77                    type Subslice = SubsliceImpl<'__subslice_gat, #names>;
78                }
79
80                #[automatically_derived]
81                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<core::ops::Range<usize>>
82                    for SubsliceImpl<'__subslice_impl, #names> #where_clause
83                {
84                    unsafe fn get_subslice_unchecked(
85                        &self,
86                        range: ::core::ops::Range<usize>,
87                    ) -> ::value_traits::slices::Subslice<'_, Self> {
88                        SubsliceImpl {
89                            slice: self.slice,
90                            start: self.start + range.start,
91                            end: self.start + range.end,
92                        }
93                    }
94                }
95
96                #[automatically_derived]
97                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<core::ops::RangeFrom<usize>>
98                    for SubsliceImpl<'__subslice_impl, #names> #where_clause
99                {
100                    unsafe fn get_subslice_unchecked(
101                        &self,
102                        range: ::core::ops::RangeFrom<usize>,
103                    ) -> ::value_traits::slices::Subslice<'_, Self> {
104                        SubsliceImpl {
105                            slice: self.slice,
106                            start: self.start + range.start,
107                            end: self.end,
108                        }
109                    }
110                }
111
112                #[automatically_derived]
113                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<::core::ops::RangeToInclusive<usize>>
114                    for SubsliceImpl<'__subslice_impl, #names> #where_clause
115                {
116                    unsafe fn get_subslice_unchecked(
117                        &self,
118                        range: ::core::ops::RangeToInclusive<usize>,
119                    ) -> ::value_traits::slices::Subslice<'_, Self> {
120                        SubsliceImpl {
121                            slice: self.slice,
122                            start: self.start,
123                            end: self.start + range.end + 1,
124                        }
125                    }
126                }
127
128                #[automatically_derived]
129                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<core::ops::RangeFull>
130                    for SubsliceImpl<'__subslice_impl, #names> #where_clause
131                {
132                    unsafe fn get_subslice_unchecked(
133                        &self,
134                        _range: ::core::ops::RangeFull,
135                    ) -> ::value_traits::slices::Subslice<'_, Self> {
136                        SubsliceImpl {
137                            slice: self.slice,
138                            start: self.start,
139                            end: self.end,
140                        }
141                    }
142                }
143
144                #[automatically_derived]
145                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<core::ops::RangeInclusive<usize>>
146                    for SubsliceImpl<'__subslice_impl, #names> #where_clause
147                {
148                    unsafe fn get_subslice_unchecked(
149                        &self,
150                        range: ::core::ops::RangeInclusive<usize>,
151                    ) -> ::value_traits::slices::Subslice<'_, Self> {
152                        use ::core::{
153                            ops::{Bound, RangeBounds},
154                            hint::unreachable_unchecked
155                        };
156                        let start = match range.start_bound() {
157                            Bound::Included(s) => *s,
158                            // SAFETY: we cannot take this branch
159                            _ => unsafe { unreachable_unchecked() },
160                        };
161                        let end = match range.end_bound() {
162                            Bound::Included(s) => *s,
163                            // SAFETY: we cannot take this branch
164                            _ => unsafe { unreachable_unchecked() },
165                        };
166                        SubsliceImpl {
167                            slice: self.slice,
168                            start: self.start + start,
169                            end: self.start + end + 1,
170                        }
171                    }
172                }
173
174                #[automatically_derived]
175                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<::core::ops::RangeTo<usize>>
176                    for SubsliceImpl<'__subslice_impl, #names> #where_clause
177                {
178                    unsafe fn get_subslice_unchecked(
179                        &self,
180                        range: ::core::ops::RangeTo<usize>,
181                    ) -> ::value_traits::slices::Subslice<'_, Self> {
182                        SubsliceImpl {
183                            slice: self.slice,
184                            start: self.start,
185                            end: self.start + range.end,
186                        }
187                    }
188                }
189
190                #[automatically_derived]
191                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_impl> for #input_ident #ty_generics #where_clause  {
192                    type Subslice = SubsliceImpl<'__subslice_impl, #names>;
193                }
194
195                #[automatically_derived]
196                impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRange<core::ops::Range<usize>> for #input_ident #ty_generics #where_clause {
197                    unsafe fn get_subslice_unchecked(
198                        &self,
199                        range: ::core::ops::Range<usize>,
200                    ) -> ::value_traits::slices::Subslice<'_, Self> {
201                        SubsliceImpl {
202                            slice: &self,
203                            start: range.start,
204                            end: range.end,
205                        }
206                    }
207                }
208
209                #[automatically_derived]
210                impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRange<core::ops::RangeFrom<usize>> for #input_ident #ty_generics #where_clause {
211                    unsafe fn get_subslice_unchecked(
212                        &self,
213                        range: ::core::ops::RangeFrom<usize>,
214                    ) -> ::value_traits::slices::Subslice<'_, Self> {
215                        SubsliceImpl {
216                            slice: &self,
217                            start: range.start,
218                            end: self.len(),
219                        }
220                    }
221                }
222
223                #[automatically_derived]
224                impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRange<::core::ops::RangeToInclusive<usize>> for #input_ident #ty_generics #where_clause {
225                    unsafe fn get_subslice_unchecked(
226                        &self,
227                        range: ::core::ops::RangeToInclusive<usize>,
228                    ) -> ::value_traits::slices::Subslice<'_, Self> {
229                        SubsliceImpl {
230                            slice: &self,
231                            start: 0,
232                            end: range.end + 1,
233                        }
234                    }
235                }
236
237                #[automatically_derived]
238                impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRange<core::ops::RangeFull> for #input_ident #ty_generics #where_clause {
239                    unsafe fn get_subslice_unchecked(
240                        &self,
241                        _range: ::core::ops::RangeFull,
242                    ) -> ::value_traits::slices::Subslice<'_, Self> {
243                        SubsliceImpl {
244                            slice: &self,
245                            start: 0,
246                            end: self.len(),
247                        }
248                    }
249                }
250
251                #[automatically_derived]
252                impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRange<core::ops::RangeInclusive<usize>> for #input_ident #ty_generics #where_clause {
253                    unsafe fn get_subslice_unchecked(
254                        &self,
255                        range: ::core::ops::RangeInclusive<usize>,
256                    ) -> ::value_traits::slices::Subslice<'_, Self> {
257                        use ::core::{
258                            ops::{Bound, RangeBounds},
259                            hint::unreachable_unchecked
260                        };
261                        let start = match range.start_bound() {
262                            Bound::Included(s) => *s,
263                            // SAFETY: we cannot take this branch
264                            _ => unsafe { unreachable_unchecked() },
265                        };
266                        let end = match range.end_bound() {
267                            Bound::Included(s) => *s,
268                            // SAFETY: we cannot take this branch
269                            _ => unsafe { unreachable_unchecked() },
270                        };
271                        SubsliceImpl {
272                            slice: &self,
273                            start: start,
274                            end: end + 1,
275                        }
276                    }
277                }
278
279                #[automatically_derived]
280                impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRange<::core::ops::RangeTo<usize>> for #input_ident #ty_generics #where_clause {
281                    unsafe fn get_subslice_unchecked(
282                        &self,
283                        range: ::core::ops::RangeTo<usize>,
284                    ) -> ::value_traits::slices::Subslice<'_, Self> {
285                        SubsliceImpl {
286                            slice: &self,
287                            start: 0,
288                            end: range.end,
289                        }
290                    }
291                }
292            }
293        },
294
295        _ => unimplemented!(),
296    }
297    .into()
298}
299
300/// A procedural macro fully implementing [`IterableByValue`] and
301/// [`IterableByValueFrom`] for subslices on top of a the `SubsliceImpl`
302/// structure generated by the derive macro [`Subslice`].
303///
304/// The macro defines a structure `Iter` that keeps track of a mutable reference
305/// to a slice, and of a current position, and that is used to implement
306/// [`IterableByValue`](crate::iter::IterableByValue) on `SubsliceImpl`.
307#[proc_macro_derive(Iterators)]
308pub fn iterators(input: TokenStream) -> TokenStream {
309    let mut input = parse_macro_input!(input as DeriveInput);
310
311    let input_ident = input.ident;
312    input.generics.make_where_clause();
313    let (_impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
314    let params = &input.generics.params;
315    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
316
317    let names: proc_macro2::TokenStream = {
318        if ty_generics_token_stream.is_empty() {
319            // If the original struct has no generics (e.g., struct MyStruct;),
320            // then ty_generics is empty, and we want an empty stream.
321            proc_macro2::TokenStream::new()
322        } else {
323            // 2. Parse this TokenStream into a syn::AngleBracketedGenericArguments.
324            //    This syn type represents the `T, A, B` arguments enclosed in angle brackets.
325            let parsed_args: AngleBracketedGenericArguments =
326                parse2(ty_generics_token_stream)
327                    .expect("Failed to parse ty_generics into AngleBracketedGenericArguments. This indicates an unexpected structure in the generic parameters.");
328
329            // 3. The `args` field of AngleBracketedGenericArguments is a Punctuated list
330            //    (Punctuated<GenericArgument, Comma>) containing just the T, A, B.
331            //    When you convert this Punctuated list to a TokenStream, it will
332            //    automatically produce the comma-separated tokens without angle brackets.
333            parsed_args.args.into_token_stream()
334        }
335    };
336    match input.data {
337        Data::Struct(_) => {
338            quote! {
339                #[automatically_derived]
340                pub struct Iter<'__subslice_impl, '__iter_ref, #params> {
341                    subslice: &'__iter_ref SubsliceImpl<'__subslice_impl, #names>,
342                    range: ::core::ops::Range<usize>,
343                }
344
345                #[automatically_derived]
346                impl<'__subslice_impl, '__iter_ref, #params> Iter<'__subslice_impl, '__iter_ref, #names> #where_clause {
347                    pub fn new(subslice: &'__iter_ref SubsliceImpl<'__subslice_impl, #names>) -> Self {
348                        Self {
349                            subslice,
350                            range: 0..subslice.len(),
351                        }
352                    }
353                    pub fn new_from(subslice: &'__iter_ref SubsliceImpl<'__subslice_impl, #names>, from: usize) -> Self {
354                        let len = subslice.len();
355                        assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
356
357                        Self {
358                            subslice,
359                            range: from..len,
360                        }
361                    }
362                }
363
364                #[automatically_derived]
365                /// Ideally we would like to also implement [`Iterator::advance_by`], but it is
366                /// nightly, and [`Iterator::skip`], [`Iterator::take`], [`Iterator::step_by`],
367                /// as we can do it more efficiently, but the [`Iterator`] trait definition
368                /// doesn't allow to return an arbitrary type.
369                impl<'__subslice_impl, '__iter_ref, #params> Iterator for Iter<'__subslice_impl, '__iter_ref, #names> #where_clause {
370                    type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
371
372                    #[inline]
373                    fn next(&mut self) -> Option<Self::Item> {
374                        if self.range.is_empty() {
375                            return ::core::option::Option::None;
376                        }
377                        let value = unsafe { self.subslice.get_value_unchecked(self.range.start) };
378                        self.range.start += 1;
379                        ::core::option::Option::Some(value)
380                    }
381
382                    /// Since we are indexing into a subslice, we can implement
383                    /// [`Iterator::nth`] without needing to consume the first `n` elements.
384                    #[inline]
385                    fn nth(&mut self, n: usize) -> Option<Self::Item> {
386                        if n >= self.range.end {
387                            self.range.start = self.range.end; // consume the iterator
388                            return ::core::option::Option::None;
389                        }
390                        let value = unsafe { self.subslice.get_value_unchecked(self.range.start + n) };
391                        self.range.start += n + 1;
392                        ::core::option::Option::Some(value)
393                    }
394
395                    #[inline]
396                    fn size_hint(&self) -> (usize, Option<usize>) {
397                        let len = self.range.len();
398                        (len, Some(len))
399                    }
400                }
401
402                impl<'__subslice_impl, '__iter_ref, #params> DoubleEndedIterator for Iter<'__subslice_impl, '__iter_ref, #names> #where_clause {
403                    #[inline]
404                    fn next_back(&mut self) -> Option<Self::Item> {
405                        if self.range.is_empty() {
406                            return ::core::option::Option::None;
407                        }
408                        self.range.end -= 1;
409                        let value = unsafe { self.subslice.get_value_unchecked(self.range.end) };
410                        ::core::option::Option::Some(value)
411                    }
412                }
413
414                impl<'__subslice_impl, '__iter_ref, #params> ExactSizeIterator for Iter<'__subslice_impl, '__iter_ref, #names> #where_clause {
415                    #[inline]
416                    fn len(&self) -> usize {
417                        self.range.len()
418                    }
419                }
420
421                #[automatically_derived]
422                impl<'__subslice_impl, #params> IterableByValue for SubsliceImpl<'__subslice_impl, #names> #where_clause {
423                    type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
424                    type Iter<'__iter_ref>
425                        = Iter<'__subslice_impl, '__iter_ref, #names>
426                    where
427                        Self: '__iter_ref;
428
429                    #[inline]
430                    fn iter_value(&self) -> Self::Iter<'_> {
431                        Iter::new(self)
432                    }
433                }
434
435                #[automatically_derived]
436                impl<'__subslice_impl, #params> IterableByValueFrom for SubsliceImpl<'__subslice_impl, #names> #where_clause {
437                    type IterFrom<'__iter_ref>
438                        = Iter<'__subslice_impl, '__iter_ref, #names>
439                    where
440                        Self: '__iter_ref;
441
442                    #[inline]
443                    fn iter_value_from(&self, from: usize) -> Self::IterFrom<'_> {
444                        let len = self.len();
445                        assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
446
447                        Iter::new_from(self, from)
448                    }
449                }
450            }
451        },
452
453        _ => unimplemented!(),
454    }
455    .into()
456}
457
458/// A procedural macro fully implementing mutable subslices on top of a
459/// [`SliceByValueSet`]/[`SliceByValueRepl`] for which the derive macro
460/// [`Subslice`] has been already applied.
461///
462/// The macro defines a structure `SubsliceImplMut` that keeps track of a
463/// mutable reference to a slice, and of the start and end of the subslice.
464/// `SubsliceImplMut` then implements [`SliceByValueGet`], [`SliceByValueSet`],
465/// [`SliceByValueRepl`], [`SliceByValueSubslice`], and
466/// [`SliceByValueSubsliceMut`].
467#[proc_macro_derive(SubslicesMut)]
468pub fn subslices_mut(input: TokenStream) -> TokenStream {
469    let mut input = parse_macro_input!(input as DeriveInput);
470
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 = &input.generics.params;
475    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
476
477    let names: proc_macro2::TokenStream = {
478        if ty_generics_token_stream.is_empty() {
479            // If the original struct has no generics (e.g., struct MyStruct;),
480            // then ty_generics is empty, and we want an empty stream.
481            proc_macro2::TokenStream::new()
482        } else {
483            // 2. Parse this TokenStream into a syn::AngleBracketedGenericArguments.
484            //    This syn type represents the `T, A, B` arguments enclosed in angle brackets.
485            let parsed_args: AngleBracketedGenericArguments =
486                parse2(ty_generics_token_stream)
487                    .expect("Failed to parse ty_generics into AngleBracketedGenericArguments. This indicates an unexpected structure in the generic parameters.");
488
489            // 3. The `args` field of AngleBracketedGenericArguments is a Punctuated list
490            //    (Punctuated<GenericArgument, Comma>) containing just the T, A, B.
491            //    When you convert this Punctuated list to a TokenStream, it will
492            //    automatically produce the comma-separated tokens without angle brackets.
493            parsed_args.args.into_token_stream()
494        }
495    };
496    match input.data {
497        Data::Struct(_) => {
498            quote! {
499                #[automatically_derived]
500                pub struct SubsliceImplMut<'__subslice_impl, #params> {
501                    slice: &'__subslice_impl mut #input_ident #ty_generics,
502                    start: usize,
503                    end: usize,
504                }
505
506                #[automatically_derived]
507                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValue for SubsliceImplMut<'__subslice_impl, #names> #where_clause {
508                    type Value = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
509
510                    #[inline]
511                    fn len(&self) -> usize {
512                        self.end - self.start
513                    }
514                }
515
516                #[automatically_derived]
517                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueGet for SubsliceImplMut<'__subslice_impl, #names> #where_clause  {
518                    unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
519                        self.slice.get_value_unchecked(index + self.start)
520                    }
521                }
522
523                #[automatically_derived]
524                impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_gat> for SubsliceImplMut<'__subslice_impl, #names> #where_clause {
525                    type Subslice = SubsliceImpl<'__subslice_gat, #names>;
526                }
527
528                #[automatically_derived]
529                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<core::ops::Range<usize>>
530                    for SubsliceImplMut<'__subslice_impl, #names> #where_clause
531                {
532                    unsafe fn get_subslice_unchecked(
533                        &self,
534                        range: ::core::ops::Range<usize>,
535                    ) -> ::value_traits::slices::Subslice<'_, Self> {
536                        SubsliceImpl {
537                            slice: self.slice,
538                            start: self.start + range.start,
539                            end: self.start + range.end,
540                        }
541                    }
542                }
543
544                #[automatically_derived]
545                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<core::ops::RangeFrom<usize>>
546                    for SubsliceImplMut<'__subslice_impl, #names> #where_clause
547                {
548                    unsafe fn get_subslice_unchecked(
549                        &self,
550                        range: ::core::ops::RangeFrom<usize>,
551                    ) -> ::value_traits::slices::Subslice<'_, Self> {
552                        SubsliceImpl {
553                            slice: self.slice,
554                            start: self.start + range.start,
555                            end: self.end,
556                        }
557                    }
558                }
559
560                #[automatically_derived]
561                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<::core::ops::RangeToInclusive<usize>>
562                    for SubsliceImplMut<'__subslice_impl, #names> #where_clause
563                {
564                    unsafe fn get_subslice_unchecked(
565                        &self,
566                        range: ::core::ops::RangeToInclusive<usize>,
567                    ) -> ::value_traits::slices::Subslice<'_, Self> {
568                        SubsliceImpl {
569                            slice: self.slice,
570                            start: self.start,
571                            end: self.start + range.end + 1,
572                        }
573                    }
574                }
575
576                #[automatically_derived]
577                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<core::ops::RangeFull>
578                    for SubsliceImplMut<'__subslice_impl, #names> #where_clause
579                {
580                    unsafe fn get_subslice_unchecked(
581                        &self,
582                        _range: ::core::ops::RangeFull,
583                    ) -> ::value_traits::slices::Subslice<'_, Self> {
584                        SubsliceImpl {
585                            slice: self.slice,
586                            start: self.start,
587                            end: self.end,
588                        }
589                    }
590                }
591
592                #[automatically_derived]
593                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<core::ops::RangeInclusive<usize>>
594                    for SubsliceImplMut<'__subslice_impl, #names> #where_clause
595                {
596                    unsafe fn get_subslice_unchecked(
597                        &self,
598                        range: ::core::ops::RangeInclusive<usize>,
599                    ) -> ::value_traits::slices::Subslice<'_, Self> {
600                        use core::ops::{Bound, RangeBounds};
601                        use std::hint::unreachable_unchecked;
602                        let start = match range.start_bound() {
603                            Bound::Included(s) => *s,
604                            // SAFETY: we cannot take this branch
605                            _ => unsafe { unreachable_unchecked() },
606                        };
607                        let end = match range.end_bound() {
608                            Bound::Included(s) => *s,
609                            // SAFETY: we cannot take this branch
610                            _ => unsafe { unreachable_unchecked() },
611                        };
612                        SubsliceImpl {
613                            slice: self.slice,
614                            start: self.start + start,
615                            end: self.start + end + 1,
616                        }
617                    }
618                }
619
620                #[automatically_derived]
621                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<::core::ops::RangeTo<usize>>
622                    for SubsliceImplMut<'__subslice_impl, #names> #where_clause
623                {
624                    unsafe fn get_subslice_unchecked(
625                        &self,
626                        range: ::core::ops::RangeTo<usize>,
627                    ) -> ::value_traits::slices::Subslice<'_, Self> {
628                        SubsliceImpl {
629                            slice: self.slice,
630                            start: self.start,
631                            end: self.start + range.end,
632                        }
633                    }
634                }
635
636                #[automatically_derived]
637                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSet for SubsliceImplMut<'__subslice_impl, #names> #where_clause  {
638                    unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
639                        self.slice.set_value_unchecked(index + self.start, value)
640                    }
641                }
642
643                #[automatically_derived]
644                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueRepl for SubsliceImplMut<'__subslice_impl, #names> #where_clause  {
645                    unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value {
646                        self.slice.replace_value_unchecked(index + self.start, value)
647                    }
648                }
649
650                #[automatically_derived]
651                impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGatMut<'__subslice_gat> for SubsliceImplMut<'__subslice_impl, #names> #where_clause {
652                    type Subslice = SubsliceImplMut<'__subslice_gat, #names>;
653                }
654
655                #[automatically_derived]
656                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRangeMut<core::ops::Range<usize>>
657                    for SubsliceImplMut<'__subslice_impl, #names> #where_clause
658                {
659                    unsafe fn get_subslice_unchecked_mut(
660                        &mut self,
661                        range: ::core::ops::Range<usize>,
662                    ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
663                        SubsliceImplMut {
664                            slice: self.slice,
665                            start: self.start + range.start,
666                            end: self.start + range.end,
667                        }
668                    }
669                }
670
671                #[automatically_derived]
672                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRangeMut<core::ops::RangeFrom<usize>>
673                    for SubsliceImplMut<'__subslice_impl, #names> #where_clause
674                {
675                    unsafe fn get_subslice_unchecked_mut(
676                        &mut self,
677                        range: ::core::ops::RangeFrom<usize>,
678                    ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
679                        SubsliceImplMut {
680                            slice: self.slice,
681                            start: self.start + range.start,
682                            end: self.end,
683                        }
684                    }
685                }
686
687                #[automatically_derived]
688                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRangeMut<::core::ops::RangeToInclusive<usize>>
689                    for SubsliceImplMut<'__subslice_impl, #names> #where_clause
690                {
691                    unsafe fn get_subslice_unchecked_mut(
692                        &mut self,
693                        range: ::core::ops::RangeToInclusive<usize>,
694                    ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
695                        SubsliceImplMut {
696                            slice: self.slice,
697                            start: self.start,
698                            end: self.start + range.end + 1,
699                        }
700                    }
701                }
702
703                #[automatically_derived]
704                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRangeMut<core::ops::RangeFull>
705                    for SubsliceImplMut<'__subslice_impl, #names> #where_clause
706                {
707                    unsafe fn get_subslice_unchecked_mut(
708                        &mut self,
709                        _range: ::core::ops::RangeFull,
710                    ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
711                        SubsliceImplMut {
712                            slice: self.slice,
713                            start: self.start,
714                            end: self.end,
715                        }
716                    }
717                }
718
719                #[automatically_derived]
720                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRangeMut<core::ops::RangeInclusive<usize>>
721                    for SubsliceImplMut<'__subslice_impl, #names> #where_clause
722                {
723                    unsafe fn get_subslice_unchecked_mut(
724                        &mut self,
725                        range: ::core::ops::RangeInclusive<usize>,
726                    ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
727                        use core::ops::{Bound, RangeBounds};
728                        use std::hint::unreachable_unchecked;
729                        let start = match range.start_bound() {
730                            Bound::Included(s) => *s,
731                            // SAFETY: we cannot take this branch
732                            _ => unsafe { unreachable_unchecked() },
733                        };
734                        let end = match range.end_bound() {
735                            Bound::Included(s) => *s,
736                            // SAFETY: we cannot take this branch
737                            _ => unsafe { unreachable_unchecked() },
738                        };
739                        SubsliceImplMut {
740                            slice: self.slice,
741                            start: self.start + start,
742                            end: self.start + end + 1,
743                        }
744                    }
745                }
746
747                #[automatically_derived]
748                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRangeMut<::core::ops::RangeTo<usize>>
749                    for SubsliceImplMut<'__subslice_impl, #names> #where_clause
750                {
751                    unsafe fn get_subslice_unchecked_mut(
752                        &mut self,
753                        range: ::core::ops::RangeTo<usize>,
754                    ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
755                        SubsliceImplMut {
756                            slice: self.slice,
757                            start: self.start,
758                            end: self.start + range.end,
759                        }
760                    }
761                }
762
763                #[automatically_derived]
764                impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceGatMut<'__subslice_impl> for #input_ident #ty_generics #where_clause  {
765                    type Subslice = SubsliceImplMut<'__subslice_impl, #names>;
766                }
767
768                #[automatically_derived]
769                impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRangeMut<core::ops::Range<usize>> for #input_ident #ty_generics #where_clause {
770                    unsafe fn get_subslice_unchecked_mut(
771                        &mut self,
772                        range: ::core::ops::Range<usize>,
773                    ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
774                        SubsliceImplMut {
775                            slice: self,
776                            start: range.start,
777                            end: range.end,
778                        }
779                    }
780                }
781
782                #[automatically_derived]
783                impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRangeMut<core::ops::RangeFrom<usize>> for #input_ident #ty_generics #where_clause {
784                    unsafe fn get_subslice_unchecked_mut(
785                        &mut self,
786                        range: ::core::ops::RangeFrom<usize>,
787                    ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
788                        let end = self.len();
789                        SubsliceImplMut {
790                            slice: self,
791                            start: range.start,
792                            end
793                        }
794                    }
795                }
796
797                #[automatically_derived]
798                impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRangeMut<::core::ops::RangeToInclusive<usize>> for #input_ident #ty_generics #where_clause {
799                    unsafe fn get_subslice_unchecked_mut(
800                        &mut self,
801                        range: ::core::ops::RangeToInclusive<usize>,
802                    ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
803                        SubsliceImplMut {
804                            slice: self,
805                            start: 0,
806                            end: range.end + 1,
807                        }
808                    }
809                }
810
811                #[automatically_derived]
812                impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRangeMut<core::ops::RangeFull> for #input_ident #ty_generics #where_clause {
813                    unsafe fn get_subslice_unchecked_mut(
814                        &mut self,
815                        _range: ::core::ops::RangeFull,
816                    ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
817                        let end = self.len();
818                        SubsliceImplMut {
819                            slice: self,
820                            start: 0,
821                            end,
822                        }
823                    }
824                }
825
826                #[automatically_derived]
827                impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRangeMut<core::ops::RangeInclusive<usize>> for #input_ident #ty_generics #where_clause {
828                    unsafe fn get_subslice_unchecked_mut(
829                        &mut self,
830                        range: ::core::ops::RangeInclusive<usize>,
831                    ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
832                        use core::ops::{Bound, RangeBounds};
833                        use std::hint::unreachable_unchecked;
834
835                        let start = match range.start_bound() {
836                            Bound::Included(s) => *s,
837                            // SAFETY: we cannot take this branch
838                            _ => unsafe { unreachable_unchecked() },
839                        };
840                        let end = match range.end_bound() {
841                            Bound::Included(s) => *s,
842                            // SAFETY: we cannot take this branch
843                            _ => unsafe { unreachable_unchecked() },
844                        };
845                        SubsliceImplMut {
846                            slice: self,
847                            start: start,
848                            end: end + 1,
849                        }
850                    }
851                }
852
853                #[automatically_derived]
854                impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRangeMut<::core::ops::RangeTo<usize>> for #input_ident #ty_generics #where_clause {
855                    unsafe fn get_subslice_unchecked_mut(
856                        &mut self,
857                        range: ::core::ops::RangeTo<usize>,
858                    ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
859                        SubsliceImplMut {
860                            slice: self,
861                            start: 0,
862                            end: range.end,
863                        }
864                    }
865                }
866            }
867        },
868
869        _ => unimplemented!(),
870    }
871    .into()
872}
873
874/// A procedural macro fully implementing [`IterableByValue`] and
875/// [`IterableByValueFrom`] for subslices on top of a the `SubsliceImplMut`
876/// structure generated by the derive macro [`SubsliceMut`].
877///
878/// The macro defines a structure `IterMut` that keeps track of a mutable reference
879/// to a slice, and of a current position, and that is used to implement
880/// [`IterableByValue`](crate::iter::IterableByValue) on `SubsliceImpl`.
881///
882/// Note that since `IterMut` provides iterators by value, it cannot use to
883/// mutate the subslice. Moreover, non-mutable subslicing on a
884/// `SubsliceImplMut` will yield a `SubsliceImpl`.
885#[proc_macro_derive(IteratorsMut)]
886pub fn iterators_mut(input: TokenStream) -> TokenStream {
887    let mut input = parse_macro_input!(input as DeriveInput);
888
889    let input_ident = input.ident;
890    input.generics.make_where_clause();
891    let (_impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
892    let params = &input.generics.params;
893    let ty_generics_token_stream = ty_generics.clone().into_token_stream();
894
895    let names: proc_macro2::TokenStream = {
896        if ty_generics_token_stream.is_empty() {
897            // If the original struct has no generics (e.g., struct MyStruct;),
898            // then ty_generics is empty, and we want an empty stream.
899            proc_macro2::TokenStream::new()
900        } else {
901            // 2. Parse this TokenStream into a syn::AngleBracketedGenericArguments.
902            //    This syn type represents the `T, A, B` arguments enclosed in angle brackets.
903            let parsed_args: AngleBracketedGenericArguments =
904                parse2(ty_generics_token_stream)
905                    .expect("Failed to parse ty_generics into AngleBracketedGenericArguments. This indicates an unexpected structure in the generic parameters.");
906
907            // 3. The `args` field of AngleBracketedGenericArguments is a Punctuated list
908            //    (Punctuated<GenericArgument, Comma>) containing just the T, A, B.
909            //    When you convert this Punctuated list to a TokenStream, it will
910            //    automatically produce the comma-separated tokens without angle brackets.
911            parsed_args.args.into_token_stream()
912        }
913    };
914    match input.data {
915        Data::Struct(_) => {
916            quote! {
917                // TODO: maybe referring directly to the slice?
918                #[automatically_derived]
919                pub struct IterMut<'__subslice_impl, '__iter_ref, #params> {
920                    subslice: &'__iter_ref SubsliceImplMut<'__subslice_impl, #names>,
921                    index: usize,
922                }
923
924                #[automatically_derived]
925                impl<'__subslice_impl, '__iter_ref, #params> Iterator for IterMut<'__subslice_impl, '__iter_ref, #names> #where_clause {
926                    type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
927
928                    #[inline]
929                    fn next(&mut self) -> Option<Self::Item> {
930                        if self.index < self.subslice.len() {
931                            let value = unsafe { self.subslice.get_value_unchecked(self.index) };
932                            self.index += 1;
933                            ::core::option::Option::Some(value)
934                        } else {
935                            ::core::option::Option::None
936                        }
937                    }
938                }
939
940                #[automatically_derived]
941                impl<'__subslice_impl, #params> IterableByValue for SubsliceImplMut<'__subslice_impl, #names> #where_clause {
942                    type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
943                    type Iter<'__iter_ref>
944                        = IterMut<'__subslice_impl, '__iter_ref, #names>
945                    where
946                        Self: '__iter_ref;
947
948                    #[inline]
949                    fn iter_value(&self) -> Self::Iter<'_> {
950                        IterMut {
951                            subslice: self,
952                            index: 0,
953                        }
954                    }
955                }
956
957                #[automatically_derived]
958                impl<'__subslice_impl, #params> IterableByValueFrom for SubsliceImplMut<'__subslice_impl, #names> #where_clause {
959                    type IterFrom<'__iter_ref>
960                        = IterMut<'__subslice_impl, '__iter_ref, #names>
961                    where
962                        Self: '__iter_ref;
963
964                    #[inline]
965                    fn iter_value_from(&self, from: usize) -> Self::IterFrom<'_> {
966                        let len = self.len();
967                        assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
968
969                        IterMut {
970                            subslice: self,
971                            index: from,
972                        }
973                    }
974                }
975            }
976        },
977
978        _ => unimplemented!(),
979    }
980    .into()
981}