1#![warn(missing_docs)]
10#![warn(clippy::missing_errors_doc)]
11#![warn(clippy::missing_panics_doc)]
12
13use proc_macro::TokenStream;
16use quote::{quote, ToTokens};
17use syn::{parse2, parse_macro_input, AngleBracketedGenericArguments, DeriveInput};
18
19fn get_names(ty_generics_token_stream: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
21 if ty_generics_token_stream.is_empty() {
22 proc_macro2::TokenStream::new()
23 } else {
24 let parsed_args: AngleBracketedGenericArguments =
25 parse2(ty_generics_token_stream)
26 .expect("Failed to parse ty_generics into AngleBracketedGenericArguments. This indicates an unexpected structure in the generic parameters.");
27
28 parsed_args.args.into_token_stream()
29 }
30}
31
32#[proc_macro_derive(Subslices)]
49pub fn subslices(input: TokenStream) -> TokenStream {
50 let mut input = parse_macro_input!(input as DeriveInput);
51
52 let input_ident = input.ident;
53 input.generics.make_where_clause();
54 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
55 let params = &input.generics.params;
56 let ty_generics_token_stream = ty_generics.clone().into_token_stream();
57
58 let names = get_names(ty_generics_token_stream);
59 let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
60 let mut res = quote! {
61 #[automatically_derived]
62 pub struct #subslice_impl<'__subslice_impl, #params> {
63 slice: &'__subslice_impl #input_ident #ty_generics,
64 range: ::core::ops::Range<usize>,
65 }
66
67 #[automatically_derived]
68 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValue for #subslice_impl<'__subslice_impl, #names> #where_clause {
69 type Value = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
70
71 #[inline]
72 fn len(&self) -> usize {
73 self.range.len()
74 }
75 }
76
77 #[automatically_derived]
78 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueGet for #subslice_impl<'__subslice_impl, #names> #where_clause {
79 unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
80 self.slice.get_value_unchecked(index + self.range.start)
81 }
82 }
83
84 #[automatically_derived]
85 impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_gat> for #subslice_impl<'__subslice_impl, #names> #where_clause {
86 type Subslice = #subslice_impl<'__subslice_gat, #names>;
87 }
88
89 #[automatically_derived]
90 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_impl> for #input_ident #ty_generics #where_clause {
91 type Subslice = #subslice_impl<'__subslice_impl, #names>;
92 }
93 };
94
95 for range_type in [
96 quote! { core::ops::Range<usize> },
97 quote! { core::ops::RangeFrom<usize> },
98 quote! { core::ops::RangeToInclusive<usize> },
99 quote! { core::ops::RangeFull },
100 quote! { core::ops::RangeInclusive<usize> },
101 quote! { core::ops::RangeTo<usize> },
102 ] {
103 res.extend(quote! {
104 #[automatically_derived]
105 impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRange<#range_type> for #input_ident #ty_generics #where_clause {
106 unsafe fn get_subslice_unchecked(
107 &self,
108 range: #range_type,
109 ) -> ::value_traits::slices::Subslice<'_, Self> {
110 #subslice_impl {
111 slice: &self,
112 range: ::value_traits::slices::ComposeRange::compose(&range, 0..self.len()),
113 }
114 }
115 }
116 #[automatically_derived]
117 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<#range_type>
118 for #subslice_impl<'__subslice_impl, #names> #where_clause
119 {
120 unsafe fn get_subslice_unchecked(
121 &self,
122 range: #range_type,
123 ) -> ::value_traits::slices::Subslice<'_, Self> {
124 #subslice_impl {
125 slice: self.slice,
126 range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
127 }
128 }
129 }
130 });
131 }
132
133 res.into()
134}
135
136#[proc_macro_derive(SubslicesMut)]
162pub fn subslices_mut(input: TokenStream) -> TokenStream {
163 let mut input = parse_macro_input!(input as DeriveInput);
164
165 let input_ident = input.ident;
166 input.generics.make_where_clause();
167 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
168 let params = &input.generics.params;
169 let ty_generics_token_stream = ty_generics.clone().into_token_stream();
170
171 let names = get_names(ty_generics_token_stream);
172 let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
173 let subslice_impl_mut = quote::format_ident!("{}SubsliceImplMut", input_ident);
174 let mut res = quote! {
175 #[automatically_derived]
176 pub struct #subslice_impl_mut<'__subslice_impl, #params> {
177 slice: &'__subslice_impl mut #input_ident #ty_generics,
178 range: ::core::ops::Range<usize>,
179 }
180
181 #[automatically_derived]
182 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValue for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
183 type Value = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
184
185 #[inline]
186 fn len(&self) -> usize {
187 self.range.len()
188 }
189 }
190
191 #[automatically_derived]
192 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueGet for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
193 unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
194 self.slice.get_value_unchecked(index + self.range.start)
195 }
196 }
197
198 #[automatically_derived]
199 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSet for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
200 unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
201 self.slice.set_value_unchecked(index + self.range.start, value)
202 }
203 }
204
205 #[automatically_derived]
206 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueRepl for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
207 unsafe fn replace_value_unchecked(&mut self, index: usize, value: Self::Value) -> Self::Value {
208 self.slice.replace_value_unchecked(index + self.range.start, value)
209 }
210 }
211
212 #[automatically_derived]
213 impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGat<'__subslice_gat> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
214 type Subslice = #subslice_impl<'__subslice_gat, #names>;
215 }
216
217 #[automatically_derived]
218 impl<'__subslice_impl, '__subslice_gat, #params> ::value_traits::slices::SliceByValueSubsliceGatMut<'__subslice_gat> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
219 type SubsliceMut = #subslice_impl_mut<'__subslice_gat, #names>;
220 }
221
222 #[automatically_derived]
223 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceGatMut<'__subslice_impl> for #input_ident #ty_generics #where_clause {
224 type SubsliceMut = #subslice_impl_mut<'__subslice_impl, #names>;
225 }
226
227 };
228
229 for range_type in [
230 quote! { ::core::ops::Range<usize> },
231 quote! { ::core::ops::RangeFrom<usize> },
232 quote! { ::core::ops::RangeToInclusive<usize> },
233 quote! { ::core::ops::RangeFull },
234 quote! { ::core::ops::RangeInclusive<usize> },
235 quote! { ::core::ops::RangeTo<usize> },
236 ] {
237 res.extend(quote!{
239 #[automatically_derived]
240 impl #impl_generics ::value_traits::slices::SliceByValueSubsliceRangeMut<#range_type> for #input_ident #ty_generics #where_clause {
241 unsafe fn get_subslice_unchecked_mut(
242 &mut self,
243 range: #range_type,
244 ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
245 let len = self.len();
246 #subslice_impl_mut {
247 slice: self,
248 range: ::value_traits::slices::ComposeRange::compose(&range, 0..len),
249 }
250 }
251 }
252 #[automatically_derived]
253 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRange<#range_type>
254 for #subslice_impl_mut<'__subslice_impl, #names> #where_clause
255 {
256 unsafe fn get_subslice_unchecked(
257 &self,
258 range: #range_type,
259 ) -> ::value_traits::slices::Subslice<'_, Self> {
260 #subslice_impl {
261 slice: &*self.slice,
262 range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
263 }
264 }
265 }
266 #[automatically_derived]
267 impl<'__subslice_impl, #params> ::value_traits::slices::SliceByValueSubsliceRangeMut<#range_type>
268 for #subslice_impl_mut<'__subslice_impl, #names> #where_clause
269 {
270 unsafe fn get_subslice_unchecked_mut(
271 &mut self,
272 range: #range_type,
273 ) -> ::value_traits::slices::SubsliceMut<'_, Self> {
274 #subslice_impl_mut {
275 slice: self.slice,
276 range: ::value_traits::slices::ComposeRange::compose(&range, self.range.clone()),
277 }
278 }
279 }
280 });
281 }
282
283 res.into()
284}
285
286#[proc_macro_derive(Iterators)]
301pub fn iterators(input: TokenStream) -> TokenStream {
302 let mut input = parse_macro_input!(input as DeriveInput);
303
304 let input_ident = input.ident;
305 input.generics.make_where_clause();
306 let (_impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
307 let params = &input.generics.params;
308 let ty_generics_token_stream = ty_generics.clone().into_token_stream();
309
310 let names = get_names(ty_generics_token_stream);
311 let subslice_impl = quote::format_ident!("{}SubsliceImpl", input_ident);
312 let iter = quote::format_ident!("{}Iter", input_ident);
313 quote! {
314 #[automatically_derived]
315 pub struct #iter<'__iter_ref, #params> {
316 subslice: &'__iter_ref #input_ident #ty_generics,
317 range: ::core::ops::Range<usize>,
318 }
319
320 #[automatically_derived]
321 impl<'__iter_ref, #params> #iter<'__iter_ref, #names> #where_clause {
322 pub fn new(subslice: &'__iter_ref #input_ident #ty_generics) -> Self {
323 let len = subslice.len();
324 Self {
325 subslice,
326 range: 0..len,
327 }
328 }
329 pub fn new_with_range(subslice: &'__iter_ref #input_ident #ty_generics, range: ::core::ops::Range<usize>) -> Self {
330 Self {
331 subslice,
332 range,
333 }
334 }
335 }
336
337 #[automatically_derived]
367 impl<'__iter_ref, #params> ::core::iter::Iterator for #iter<'__iter_ref, #names> #where_clause {
372 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
373
374 #[inline]
375 fn next(&mut self) -> Option<Self::Item> {
376 if self.range.is_empty() {
377 return ::core::option::Option::None;
378 }
379 let value = unsafe { self.subslice.get_value_unchecked(self.range.start) };
380 self.range.start += 1;
381 ::core::option::Option::Some(value)
382 }
383
384 #[inline]
387 fn nth(&mut self, n: usize) -> Option<Self::Item> {
388 if n >= self.range.end {
389 self.range.start = self.range.end; return ::core::option::Option::None;
391 }
392 let value = unsafe { self.subslice.get_value_unchecked(self.range.start + n) };
393 self.range.start += n + 1;
394 ::core::option::Option::Some(value)
395 }
396
397 #[inline]
398 fn size_hint(&self) -> (usize, Option<usize>) {
399 let len = self.range.len();
400 (len, Some(len))
401 }
402 }
403
404 impl<'__iter_ref, #params> ::core::iter::DoubleEndedIterator for #iter<'__iter_ref, #names> #where_clause {
405 #[inline]
406 fn next_back(&mut self) -> Option<Self::Item> {
407 if self.range.is_empty() {
408 return ::core::option::Option::None;
409 }
410 self.range.end -= 1;
411 let value = unsafe { self.subslice.get_value_unchecked(self.range.end) };
412 ::core::option::Option::Some(value)
413 }
414 }
415
416 impl<'__iter_ref, #params> ::core::iter::ExactSizeIterator for #iter<'__iter_ref, #names> #where_clause {
417 #[inline]
418 fn len(&self) -> usize {
419 self.range.len()
420 }
421 }
422
423 #[automatically_derived]
424 impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueGat<'__iter_ref> for #subslice_impl<'__subslice_impl, #names> #where_clause {
425 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
426 type Iter = #iter<'__iter_ref, #names>;
427 }
428
429 #[automatically_derived]
430 impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValue for #subslice_impl<'__subslice_impl, #names> #where_clause {
431 #[inline]
432 fn iter_value(&self) -> ::value_traits::iter::Iter<'_, Self> {
433 #iter::new(self.slice)
434 }
435 }
436
437 #[automatically_derived]
438 impl<'__subslice_impl, '__iter_ref,#params> ::value_traits::iter::IterateByValueFromGat<'__iter_ref> for #subslice_impl<'__subslice_impl, #names> #where_clause {
439 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
440 type IterFrom = #iter<'__iter_ref, #names>;
441 }
442
443 #[automatically_derived]
444 impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValueFrom for #subslice_impl<'__subslice_impl, #names> #where_clause {
445 #[inline]
446 fn iter_value_from(&self, from: usize) -> ::value_traits::iter::IterFrom<'_, Self> {
447 let len = self.len();
448 assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
449 let range = ::value_traits::slices::ComposeRange::compose(&(from..), self.range.clone());
450 #iter::new_with_range(self.slice, range)
451 }
452 }
453 }.into()
454}
455
456#[proc_macro_derive(IteratorsMut)]
467pub fn iterators_mut(input: TokenStream) -> TokenStream {
468 let mut input = parse_macro_input!(input as DeriveInput);
469
470 let input_ident = input.ident;
471 input.generics.make_where_clause();
472 let (_impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
473 let params = &input.generics.params;
474 let ty_generics_token_stream = ty_generics.clone().into_token_stream();
475
476 let names = get_names(ty_generics_token_stream);
477 let subslice_impl_mut = quote::format_ident!("{}SubsliceImplMut", input_ident);
478 let iter = quote::format_ident!("{}Iter", input_ident);
479 quote!{
480 #[automatically_derived]
481 impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueGat<'__iter_ref> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
482 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
483 type Iter = #iter<'__iter_ref, #names>;
484 }
485
486 #[automatically_derived]
487 impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValue for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
488 fn iter_value(&self) -> ::value_traits::iter::Iter<'_, Self> {
489 #iter::new(self.slice)
490 }
491 }
492
493 #[automatically_derived]
494 impl<'__subslice_impl, '__iter_ref, #params> ::value_traits::iter::IterateByValueFromGat<'__iter_ref> for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
495 type Item = <#input_ident #ty_generics as ::value_traits::slices::SliceByValue>::Value;
496 type IterFrom = #iter<'__iter_ref, #names>;
497 }
498
499 #[automatically_derived]
500 impl<'__subslice_impl, #params> ::value_traits::iter::IterateByValueFrom for #subslice_impl_mut<'__subslice_impl, #names> #where_clause {
501 fn iter_value_from(&self, from: usize) -> ::value_traits::iter::IterFrom<'_, Self> {
502 let len = self.len();
503 assert!(from <= len, "index out of bounds: the len is {len} but the starting index is {from}");
504 let range = ::value_traits::slices::ComposeRange::compose(&(from..), self.range.clone());
505 #iter::new_with_range(self.slice, range)
506 }
507 }
508 }.into()
509}