wrapper_lite/lib.rs
1#![doc = include_str!("../README.md")]
2#![no_std]
3
4#[macro_export]
5/// Helper macro for creating a wrapper over any type (new-type idiom).
6///
7/// This is a shortcut for using the [`wrapper!`] macro with the most common
8/// impls (`AsRef`, `Borrow`, `From`).
9///
10/// ```rust
11/// wrapper_lite::general_wrapper!(
12/// #[derive(Debug, Clone, Copy)]
13/// pub struct ExampleWrapper<'a, P>(pub(crate) &'a P);
14/// );
15/// ```
16///
17/// This is equivalent to using the `wrapper!` macro with the following
18/// attributes:
19///
20/// ```rust
21/// wrapper_lite::wrapper!(
22/// #[wrapper_impl(AsRef)]
23/// #[wrapper_impl(Borrow)]
24/// #[wrapper_impl(From)]
25/// #[derive(Debug, Clone, Copy)]
26/// pub struct ExampleWrapper<'a, P>(pub(crate) &'a P);
27/// );
28/// ```
29///
30/// You can certainly add attributes like `#[wrapper_impl(Deref)]` other than
31/// the preset ones. See [`wrapper!`] for more details.
32///
33/// ```rust
34/// wrapper_lite::general_wrapper!(
35/// #[wrapper_impl(Deref)]
36/// #[derive(Debug, Clone, Copy)]
37/// pub struct ExampleWrapper<'a, P>(pub(crate) &'a P);
38/// );
39/// ```
40macro_rules! general_wrapper {
41 ($($tt:tt)+) => {
42 $crate::wrapper! {
43 #[wrapper_impl(AsRef)]
44 #[wrapper_impl(Borrow)]
45 #[wrapper_impl(From)]
46 $($tt)+
47 }
48 };
49}
50
51#[macro_export]
52/// Helper macro for creating a wrapper over any type (new-type idiom).
53///
54/// # Usage
55///
56/// It's worth noting that `wrapper! { ... }` is almost equivalent to
57/// `wrapper!( ... );` but lacking cargo-fmt support. We recommend using the
58/// latter.
59///
60/// ## Usage: basic
61///
62/// ```rust
63/// wrapper_lite::wrapper!(
64/// #[wrapper_impl(AsRef)]
65/// #[wrapper_impl(AsMut)]
66/// // #[wrapper_impl(Borrow)]
67/// #[wrapper_impl(BorrowMut)]
68/// // #[wrapper_impl(Deref)]
69/// #[wrapper_impl(DerefMut)]
70/// #[wrapper_impl(From)]
71/// #[derive(Debug, Clone, Copy)]
72/// pub struct ExampleWrapper<'a, P>(pub(crate) &'a P);
73/// );
74/// ```
75///
76/// Generates const accessor methods for wrapper types implementing `AsRef` and
77/// `AsMut` traits.
78///
79/// For types implementing `AsRef`, this creates a const method `as_inner` that
80/// returns a reference to the wrapped value. For types implementing `AsMut`,
81/// this creates a const method `as_inner_mut` that returns a mutable reference
82/// to the wrapped value.
83///
84/// Additionally generates a const constructor method `const_from` for the
85/// wrapper type, using the same visibility as the inner field. When the `From`
86/// trait is implemented, also generates a public const method `from`.
87///
88/// ## Usage: advanced
89///
90/// You can also create a wrapper type with a struct with multiple fields,
91/// especially when some lifetime markers or generics markers are too complex,
92/// or you need some custom fields.
93///
94/// Here's an complex example:
95///
96/// ```rust
97/// wrapper_lite::wrapper!(
98/// #[wrapper_impl(AsMut)]
99/// #[wrapper_impl(AsRef)]
100/// // #[wrapper_impl(Borrow)]
101/// #[wrapper_impl(BorrowMut)]
102/// // #[wrapper_impl(Deref)]
103/// #[wrapper_impl(DerefMut)]
104/// // #[wrapper_impl(From)]
105/// #[wrapper_impl(Debug)]
106/// #[derive(Clone, Copy, PartialEq, Eq)]
107/// #[repr(transparent)]
108/// pub struct ExampleWrapperComplex<'a, 'b, P> {
109/// inner: P,
110/// _a: ::core::marker::PhantomData<&'a ()>,
111/// _b: ::core::marker::PhantomData<&'b ()>,
112/// }
113/// );
114///
115/// wrapper_lite::wrapper!(
116/// #[wrapper_impl(AsMut)]
117/// #[wrapper_impl(AsRef)]
118/// // #[wrapper_impl(Borrow)]
119/// #[wrapper_impl(BorrowMut)]
120/// // #[wrapper_impl(Deref)]
121/// #[wrapper_impl(DerefMut)]
122/// #[wrapper_impl(From)]
123/// #[wrapper_impl(Debug)]
124/// #[derive(Clone, Copy, PartialEq, Eq)]
125/// #[repr(transparent)]
126/// pub struct ExampleWrapperComplexWithDefault<'a, 'b, P> {
127/// inner: P,
128/// _a: ::core::marker::PhantomData<&'a ()> = ::core::marker::PhantomData,
129/// _b: ::core::marker::PhantomData<&'b ()> = ::core::marker::PhantomData,
130/// }
131/// );
132/// ```
133///
134/// There're some limitations:
135///
136/// - The inner field must be the first field declared in the struct.
137/// - When there's no default value specified, we cannot implement the `From`
138/// trait for the wrapper type.
139/// - The macro does not know if other fields were zero-sized types (ZST), hence
140/// we will not automatically apply `repr(transparent)` attribute.
141///
142/// ## Special usages
143///
144/// ### `Debug` and `DebugName`
145///
146/// We offer `Debug` and `DebugName` attributes to control how the wrapper type
147/// is printed when using the `Debug` trait, instead of `#[derive(Debug)]`.
148///
149/// - `#[wrapper_impl(Debug)]`: transparently implements the `Debug` trait if
150/// the inner type implements it. The debug output is the same as the inner
151/// one.
152/// - `#[wrapper_impl(DebugName)]`: implements the `Debug` trait, but only
153/// prints the name of the wrapper type.
154///
155/// ```rust
156/// wrapper_lite::wrapper!(
157/// #[wrapper_impl(Debug)]
158/// #[derive(Clone, Copy)]
159/// pub struct ExampleWrapperDebug<'a, P>(&'a P);
160/// );
161///
162/// wrapper_lite::wrapper!(
163/// #[wrapper_impl(DebugName)]
164/// #[derive(Clone, Copy)]
165/// pub struct ExampleWrapperDebugName<'a, P>(&'a P);
166/// );
167///
168/// let data = "Hello".to_string();
169///
170/// // Here we transparently print the debug output of the inner type.
171/// assert_eq!(
172/// format!("{:?}", ExampleWrapperDebug { inner: &data }),
173/// "\"Hello\""
174/// );
175/// // Here we only print the name of the wrapper type.
176/// assert_eq!(
177/// format!("{:?}", ExampleWrapperDebugName { inner: &data }),
178/// "ExampleWrapperDebugName"
179/// );
180/// ```
181///
182/// ### `Display`
183///
184/// Like `Debug`.
185///
186/// ```rust
187/// wrapper_lite::wrapper!(
188/// #[wrapper_impl(Display)]
189/// #[derive(Clone, Copy)]
190/// pub struct ExampleWrapperDisplay<'a, P>(&'a P);
191/// );
192///
193/// let data = "Hello".to_string();
194///
195/// // Here we transparently print the debug output of the inner type.
196/// assert_eq!(
197/// format!("{}", ExampleWrapperDisplay { inner: &data }),
198/// "Hello"
199/// );
200/// ```
201///
202/// ### `ConstAsMut`
203///
204/// Like `AsMut`, but instead generates a const version of `as_inner_mut` method
205/// (stable since Rust 1.83.0+).
206///
207/// ```rust,no_run
208/// wrapper_lite::wrapper!(
209/// #[wrapper_impl(ConstAsMut)]
210/// #[derive(Debug, Clone, Copy)]
211/// pub struct ExampleWrapper<P>(pub(crate) P);
212/// );
213///
214/// const fn const_fn_example<P>(w: &mut ExampleWrapper<P>) -> &mut P {
215/// w.as_inner_mut()
216/// }
217/// ```
218///
219/// ### `AsRef<T>`, `AsMut<T>`, `Borrow<T>`, `BorrowMut<T>`, `Deref<T>`, `DerefMut<T>`
220///
221/// These attributes allow you to specify a target type `T` for the respective
222/// traits (experimental). This is done by auto-dereferencing the inner type to
223/// get a reference to `T`.
224///
225/// ```rust
226/// wrapper_lite::wrapper!(
227/// #[wrapper_impl(AsRef<[u8]>)]
228/// #[wrapper_impl(AsMut<[u8]>)]
229/// // #[wrapper_impl(Borrow<[u8]>)]
230/// #[wrapper_impl(BorrowMut<[u8]>)]
231/// // #[wrapper_impl(Deref<[u8]>)]
232/// #[wrapper_impl(DerefMut<[u8]>)]
233/// pub struct ExampleWrapper(pub(crate) Vec<u8>);
234/// );
235/// ```
236///
237/// ### `repr(align(cache))`
238///
239/// You can use `#[repr(align(cache))]` to pad and align the wrapper type to the
240/// cache line size. This is useful for performance optimization in certain
241/// scenarios.
242///
243/// ```
244/// wrapper_lite::wrapper!(
245/// #[wrapper_impl(From)]
246/// #[repr(align(cache))]
247/// /// Example doc
248/// pub struct ExampleWrapperCachePadded(u64);
249/// );
250/// #[cfg(target_arch = "x86_64")]
251/// assert_eq!(core::mem::align_of::<ExampleWrapperCachePadded>(), 128);
252/// ```
253///
254/// Credits: <https://docs.rs/crossbeam/latest/crossbeam/utils/struct.CachePadded.html>.
255///
256/// Notes that `repr(align(cache))` must be placed after other
257/// `#[wrapper_impl(...)]` attributes and before any other attributes, including
258/// docs.
259///
260/// ## Notes
261///
262/// - The `wrapper_impl` attribute must be on top of any other attributes.
263/// - For `BorrowMut` and `DerefMut`, the macro will automatically implement the
264/// corresponding `Borrow` and `Deref` traits, so the following two examples
265/// will fail to compile:
266///
267/// ```rust,compile_fail
268/// wrapper_lite::wrapper!(
269/// #[wrapper_impl(Borrow)]
270/// #[wrapper_impl(BorrowMut)]
271/// pub struct ExampleWrapper<P>(pub(crate) P);
272/// );
273/// ```
274///
275/// ```rust,compile_fail
276/// wrapper_lite::wrapper!(
277/// #[wrapper_impl(Deref)]
278/// #[wrapper_impl(DerefMut)]
279/// pub struct ExampleWrapper<P>(pub(crate) P);
280/// );
281/// ```
282macro_rules! wrapper {
283 // To filter out the `wrapper_impl` attribute and extract the inner type.
284 (
285 @INTERNAL IMPL
286 #[wrapper_impl(AsRef $(<$target:ty>)? )]
287 $($tt:tt)*
288 ) => {
289 $crate::wrapper! {
290 @INTERNAL IMPL
291 $($tt)*
292 }
293 };
294 (
295 @INTERNAL IMPL
296 #[wrapper_impl(AsMut $(<$target:ty>)? )]
297 $($tt:tt)*
298 ) => {
299 $crate::wrapper! {
300 @INTERNAL IMPL
301 $($tt)*
302 }
303 };
304 (
305 @INTERNAL IMPL
306 #[wrapper_impl(ConstAsMut $(<$target:ty>)? )]
307 $($tt:tt)*
308 ) => {
309 $crate::wrapper! {
310 @INTERNAL IMPL
311 $($tt)*
312 }
313 };
314 (
315 @INTERNAL IMPL
316 #[wrapper_impl(Borrow $(<$target:ty>)? )]
317 $($tt:tt)*
318 ) => {
319 $crate::wrapper! {
320 @INTERNAL IMPL
321 $($tt)*
322 }
323 };
324 (
325 @INTERNAL IMPL
326 #[wrapper_impl(BorrowMut $(<$target:ty>)? )]
327 $($tt:tt)*
328 ) => {
329 $crate::wrapper! {
330 @INTERNAL IMPL
331 $($tt)*
332 }
333 };
334 (
335 @INTERNAL IMPL
336 #[wrapper_impl(Deref $(<$target:ty>)? )]
337 $($tt:tt)*
338 ) => {
339 $crate::wrapper! {
340 @INTERNAL IMPL
341 $($tt)*
342 }
343 };
344 (
345 @INTERNAL IMPL
346 #[wrapper_impl(DerefMut $(<$target:ty>)? )]
347 $($tt:tt)*
348 ) => {
349 $crate::wrapper! {
350 @INTERNAL IMPL
351 $($tt)*
352 }
353 };
354 (
355 @INTERNAL IMPL
356 #[wrapper_impl(From)]
357 $($tt:tt)*
358 ) => {
359 $crate::wrapper! {
360 @INTERNAL IMPL
361 $($tt)*
362 }
363 };
364 (
365 @INTERNAL IMPL
366 #[wrapper_impl(Debug)]
367 $($tt:tt)*
368 ) => {
369 $crate::wrapper! {
370 @INTERNAL IMPL
371 $($tt)*
372 }
373 };
374 (
375 @INTERNAL IMPL
376 #[wrapper_impl(DebugName)]
377 $($tt:tt)*
378 ) => {
379 $crate::wrapper! {
380 @INTERNAL IMPL
381 $($tt)*
382 }
383 };
384 (
385 @INTERNAL IMPL
386 #[wrapper_impl(Display)]
387 $($tt:tt)*
388 ) => {
389 $crate::wrapper! {
390 @INTERNAL IMPL
391 $($tt)*
392 }
393 };
394
395 // The actual implementation of the wrapper type: `pub Name<...>(...)`
396 (
397 @INTERNAL IMPL
398 #[repr(align(cache))]
399 $(#[$outer:meta])*
400 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
401 ) => {
402 // Starting from Intel's Sandy Bridge, spatial prefetcher is now pulling pairs of 64-byte cache
403 // lines at a time, so we have to align to 128 bytes rather than 64.
404 //
405 // Sources:
406 // - https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf
407 // - https://github.com/facebook/folly/blob/1b5288e6eea6df074758f877c849b6e73bbb9fbb/folly/lang/Align.h#L107
408 //
409 // aarch64/arm64ec's big.LITTLE architecture has asymmetric cores and "big" cores have 128-byte cache line size.
410 //
411 // Sources:
412 // - https://www.mono-project.com/news/2016/09/12/arm64-icache/
413 //
414 // powerpc64 has 128-byte cache line size.
415 //
416 // Sources:
417 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_ppc64x.go#L9
418 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/powerpc/include/asm/cache.h#L26
419 #[cfg_attr(
420 any(
421 target_arch = "x86_64",
422 target_arch = "aarch64",
423 target_arch = "arm64ec",
424 target_arch = "powerpc64",
425 ),
426 repr(align(128))
427 )]
428 // arm, mips, mips64, sparc, and hexagon have 32-byte cache line size.
429 //
430 // Sources:
431 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_arm.go#L7
432 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips.go#L7
433 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mipsle.go#L7
434 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips64x.go#L9
435 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/sparc/include/asm/cache.h#L17
436 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/hexagon/include/asm/cache.h#L12
437 #[cfg_attr(
438 any(
439 target_arch = "arm",
440 target_arch = "mips",
441 target_arch = "mips32r6",
442 target_arch = "mips64",
443 target_arch = "mips64r6",
444 target_arch = "sparc",
445 target_arch = "hexagon",
446 ),
447 repr(align(32))
448 )]
449 // m68k has 16-byte cache line size.
450 //
451 // Sources:
452 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/m68k/include/asm/cache.h#L9
453 #[cfg_attr(target_arch = "m68k", repr(align(16)))]
454 // s390x has 256-byte cache line size.
455 //
456 // Sources:
457 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_s390x.go#L7
458 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/s390/include/asm/cache.h#L13
459 #[cfg_attr(target_arch = "s390x", repr(align(256)))]
460 // x86, wasm, riscv, and sparc64 have 64-byte cache line size.
461 //
462 // Sources:
463 // - https://github.com/golang/go/blob/dda2991c2ea0c5914714469c4defc2562a907230/src/internal/cpu/cpu_x86.go#L9
464 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_wasm.go#L7
465 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/riscv/include/asm/cache.h#L10
466 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/sparc/include/asm/cache.h#L19
467 //
468 // All others are assumed to have 64-byte cache line size.
469 #[cfg_attr(
470 not(any(
471 target_arch = "x86_64",
472 target_arch = "aarch64",
473 target_arch = "arm64ec",
474 target_arch = "powerpc64",
475 target_arch = "arm",
476 target_arch = "mips",
477 target_arch = "mips32r6",
478 target_arch = "mips64",
479 target_arch = "mips64r6",
480 target_arch = "sparc",
481 target_arch = "hexagon",
482 target_arch = "m68k",
483 target_arch = "s390x",
484 )),
485 repr(align(64))
486 )]
487 $(#[$outer])*
488 $vis struct $name$(<$($lt),+>)? {
489 /// Inner value
490 $inner_vis inner: $inner_ty,
491 }
492
493 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt),+>)? {
494 #[inline(always)]
495 #[doc = concat!("Creates a new instance of [`", stringify!($name), "`]")]
496 $inner_vis const fn const_from(inner: $inner_ty) -> Self {
497 Self {
498 inner,
499 }
500 }
501 }
502 };
503
504 (
505 @INTERNAL IMPL
506 $(#[$outer:meta])*
507 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
508 ) => {
509 $(#[$outer])*
510 #[repr(transparent)]
511 $vis struct $name$(<$($lt),+>)? {
512 /// Inner value
513 $inner_vis inner: $inner_ty,
514 }
515
516 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt),+>)? {
517 #[inline(always)]
518 #[doc = concat!("Creates a new instance of [`", stringify!($name), "`]")]
519 $inner_vis const fn const_from(inner: $inner_ty) -> Self {
520 Self {
521 inner,
522 }
523 }
524 }
525 };
526
527 // The actual implementation of the wrapper type: `pub struct Name<...> { ... }`
528 // with field initial value provided, make `const_from` const.
529 (
530 @INTERNAL IMPL
531 #[repr(align(cache))]
532 $(#[$outer:meta])*
533 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
534 $(#[$field_inner_meta:meta])*
535 $inner_vis:vis $inner:ident: $inner_ty:ty
536 $(
537 ,
538 $(#[$field_meta:meta])*
539 $field_vis:vis $field:ident: $field_ty:ty = $field_default: expr
540 )*
541 $(,)?
542 }
543 ) => {
544 // Starting from Intel's Sandy Bridge, spatial prefetcher is now pulling pairs of 64-byte cache
545 // lines at a time, so we have to align to 128 bytes rather than 64.
546 //
547 // Sources:
548 // - https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf
549 // - https://github.com/facebook/folly/blob/1b5288e6eea6df074758f877c849b6e73bbb9fbb/folly/lang/Align.h#L107
550 //
551 // aarch64/arm64ec's big.LITTLE architecture has asymmetric cores and "big" cores have 128-byte cache line size.
552 //
553 // Sources:
554 // - https://www.mono-project.com/news/2016/09/12/arm64-icache/
555 //
556 // powerpc64 has 128-byte cache line size.
557 //
558 // Sources:
559 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_ppc64x.go#L9
560 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/powerpc/include/asm/cache.h#L26
561 #[cfg_attr(
562 any(
563 target_arch = "x86_64",
564 target_arch = "aarch64",
565 target_arch = "arm64ec",
566 target_arch = "powerpc64",
567 ),
568 repr(align(128))
569 )]
570 // arm, mips, mips64, sparc, and hexagon have 32-byte cache line size.
571 //
572 // Sources:
573 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_arm.go#L7
574 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips.go#L7
575 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mipsle.go#L7
576 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips64x.go#L9
577 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/sparc/include/asm/cache.h#L17
578 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/hexagon/include/asm/cache.h#L12
579 #[cfg_attr(
580 any(
581 target_arch = "arm",
582 target_arch = "mips",
583 target_arch = "mips32r6",
584 target_arch = "mips64",
585 target_arch = "mips64r6",
586 target_arch = "sparc",
587 target_arch = "hexagon",
588 ),
589 repr(align(32))
590 )]
591 // m68k has 16-byte cache line size.
592 //
593 // Sources:
594 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/m68k/include/asm/cache.h#L9
595 #[cfg_attr(target_arch = "m68k", repr(align(16)))]
596 // s390x has 256-byte cache line size.
597 //
598 // Sources:
599 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_s390x.go#L7
600 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/s390/include/asm/cache.h#L13
601 #[cfg_attr(target_arch = "s390x", repr(align(256)))]
602 // x86, wasm, riscv, and sparc64 have 64-byte cache line size.
603 //
604 // Sources:
605 // - https://github.com/golang/go/blob/dda2991c2ea0c5914714469c4defc2562a907230/src/internal/cpu/cpu_x86.go#L9
606 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_wasm.go#L7
607 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/riscv/include/asm/cache.h#L10
608 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/sparc/include/asm/cache.h#L19
609 //
610 // All others are assumed to have 64-byte cache line size.
611 #[cfg_attr(
612 not(any(
613 target_arch = "x86_64",
614 target_arch = "aarch64",
615 target_arch = "arm64ec",
616 target_arch = "powerpc64",
617 target_arch = "arm",
618 target_arch = "mips",
619 target_arch = "mips32r6",
620 target_arch = "mips64",
621 target_arch = "mips64r6",
622 target_arch = "sparc",
623 target_arch = "hexagon",
624 target_arch = "m68k",
625 target_arch = "s390x",
626 )),
627 repr(align(64))
628 )]
629 $(#[$outer])*
630 $vis struct $name$(<$($lt),+>)? {
631 $(#[$field_inner_meta])*
632 $inner_vis $inner: $inner_ty,
633 $(
634 $(#[$field_meta])*
635 $field_vis $field: $field_ty
636 ),*
637 }
638
639 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt),+>)? {
640 #[inline(always)]
641 #[doc = concat!("Creates a new instance of [`", stringify!($name), "`]")]
642 $inner_vis const fn const_from($inner: $inner_ty) -> Self {
643 Self {
644 $inner,
645 $(
646 $field: $field_default,
647 )*
648 }
649 }
650 }
651 };
652
653 (
654 @INTERNAL IMPL
655 $(#[$outer:meta])*
656 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
657 $(#[$field_inner_meta:meta])*
658 $inner_vis:vis $inner:ident: $inner_ty:ty
659 $(
660 ,
661 $(#[$field_meta:meta])*
662 $field_vis:vis $field:ident: $field_ty:ty = $field_default: expr
663 )*
664 $(,)?
665 }
666 ) => {
667 $(#[$outer])*
668 $vis struct $name$(<$($lt),+>)? {
669 $(#[$field_inner_meta])*
670 $inner_vis $inner: $inner_ty,
671 $(
672 $(#[$field_meta])*
673 $field_vis $field: $field_ty
674 ),*
675 }
676
677 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt),+>)? {
678 #[inline(always)]
679 #[doc = concat!("Creates a new instance of [`", stringify!($name), "`]")]
680 $inner_vis const fn const_from($inner: $inner_ty) -> Self {
681 Self {
682 $inner,
683 $(
684 $field: $field_default,
685 )*
686 }
687 }
688 }
689 };
690
691 // The actual implementation of the wrapper type with fields: `pub struct Name<...> { ... }`
692 (
693 @INTERNAL IMPL
694 #[repr(align(cache))]
695 $(#[$outer:meta])*
696 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
697 $(#[$field_inner_meta:meta])*
698 $inner_vis:vis $inner:ident: $inner_ty:ty
699 $(
700 ,
701 $(#[$field_meta:meta])*
702 $field_vis:vis $field:ident: $field_ty:ty
703 )*
704 $(,)?
705 }
706 ) => {
707 // Starting from Intel's Sandy Bridge, spatial prefetcher is now pulling pairs of 64-byte cache
708 // lines at a time, so we have to align to 128 bytes rather than 64.
709 //
710 // Sources:
711 // - https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf
712 // - https://github.com/facebook/folly/blob/1b5288e6eea6df074758f877c849b6e73bbb9fbb/folly/lang/Align.h#L107
713 //
714 // aarch64/arm64ec's big.LITTLE architecture has asymmetric cores and "big" cores have 128-byte cache line size.
715 //
716 // Sources:
717 // - https://www.mono-project.com/news/2016/09/12/arm64-icache/
718 //
719 // powerpc64 has 128-byte cache line size.
720 //
721 // Sources:
722 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_ppc64x.go#L9
723 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/powerpc/include/asm/cache.h#L26
724 #[cfg_attr(
725 any(
726 target_arch = "x86_64",
727 target_arch = "aarch64",
728 target_arch = "arm64ec",
729 target_arch = "powerpc64",
730 ),
731 repr(align(128))
732 )]
733 // arm, mips, mips64, sparc, and hexagon have 32-byte cache line size.
734 //
735 // Sources:
736 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_arm.go#L7
737 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips.go#L7
738 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mipsle.go#L7
739 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips64x.go#L9
740 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/sparc/include/asm/cache.h#L17
741 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/hexagon/include/asm/cache.h#L12
742 #[cfg_attr(
743 any(
744 target_arch = "arm",
745 target_arch = "mips",
746 target_arch = "mips32r6",
747 target_arch = "mips64",
748 target_arch = "mips64r6",
749 target_arch = "sparc",
750 target_arch = "hexagon",
751 ),
752 repr(align(32))
753 )]
754 // m68k has 16-byte cache line size.
755 //
756 // Sources:
757 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/m68k/include/asm/cache.h#L9
758 #[cfg_attr(target_arch = "m68k", repr(align(16)))]
759 // s390x has 256-byte cache line size.
760 //
761 // Sources:
762 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_s390x.go#L7
763 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/s390/include/asm/cache.h#L13
764 #[cfg_attr(target_arch = "s390x", repr(align(256)))]
765 // x86, wasm, riscv, and sparc64 have 64-byte cache line size.
766 //
767 // Sources:
768 // - https://github.com/golang/go/blob/dda2991c2ea0c5914714469c4defc2562a907230/src/internal/cpu/cpu_x86.go#L9
769 // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_wasm.go#L7
770 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/riscv/include/asm/cache.h#L10
771 // - https://github.com/torvalds/linux/blob/3516bd729358a2a9b090c1905bd2a3fa926e24c6/arch/sparc/include/asm/cache.h#L19
772 //
773 // All others are assumed to have 64-byte cache line size.
774 #[cfg_attr(
775 not(any(
776 target_arch = "x86_64",
777 target_arch = "aarch64",
778 target_arch = "arm64ec",
779 target_arch = "powerpc64",
780 target_arch = "arm",
781 target_arch = "mips",
782 target_arch = "mips32r6",
783 target_arch = "mips64",
784 target_arch = "mips64r6",
785 target_arch = "sparc",
786 target_arch = "hexagon",
787 target_arch = "m68k",
788 target_arch = "s390x",
789 )),
790 repr(align(64))
791 )]
792 $(#[$outer])*
793 $vis struct $name$(<$($lt),+>)? {
794 $(#[$field_inner_meta])*
795 $inner_vis $inner: $inner_ty
796 $(
797 ,
798 $(#[$field_meta])*
799 $field_vis $field: $field_ty
800 )*
801 }
802 };
803
804 (
805 @INTERNAL IMPL
806 $(#[$outer:meta])*
807 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
808 $(#[$field_inner_meta:meta])*
809 $inner_vis:vis $inner:ident: $inner_ty:ty
810 $(
811 ,
812 $(#[$field_meta:meta])*
813 $field_vis:vis $field:ident: $field_ty:ty
814 )*
815 $(,)?
816 }
817 ) => {
818 $(#[$outer])*
819 $vis struct $name$(<$($lt),+>)? {
820 $(#[$field_inner_meta])*
821 $inner_vis $inner: $inner_ty
822 $(
823 ,
824 $(#[$field_meta])*
825 $field_vis $field: $field_ty
826 )*
827 }
828 };
829
830 // === Process all `wrapper_impl` attributes, and generate impls. ===
831
832 // Extract wrapper impl for `AsRef` trait.
833 (
834 @INTERNAL WRAPPER_IMPL
835 #[wrapper_impl(AsRef $(<$target:ty>)? )]
836 $($tt:tt)*
837 ) => {
838 $crate::wrapper! {
839 @INTERNAL WRAPPER_IMPL_AS_REF $(<$target>)?
840 $($tt)*
841 }
842
843 $crate::wrapper! {
844 @INTERNAL WRAPPER_IMPL
845 $($tt)*
846 }
847 };
848
849 // Extract wrapper impl for `AsMut` trait.
850 (
851 @INTERNAL WRAPPER_IMPL
852 #[wrapper_impl(AsMut $(<$target:ty>)? )]
853 $($tt:tt)*
854 ) => {
855 $crate::wrapper! {
856 @INTERNAL WRAPPER_IMPL_AS_MUT $(<$target>)?
857 $($tt)*
858 }
859
860 $crate::wrapper! {
861 @INTERNAL WRAPPER_IMPL
862 $($tt)*
863 }
864 };
865
866 // Extract wrapper impl for `AsMut` trait, const version.
867 (
868 @INTERNAL WRAPPER_IMPL
869 #[wrapper_impl(ConstAsMut $(<$target:ty>)? )]
870 $($tt:tt)*
871 ) => {
872 $crate::wrapper! {
873 @INTERNAL WRAPPER_IMPL_CONST_AS_MUT $(<$target>)?
874 $($tt)*
875 }
876
877 $crate::wrapper! {
878 @INTERNAL WRAPPER_IMPL
879 $($tt)*
880 }
881 };
882
883 // Extract wrapper impl for `Borrow` trait.
884 (
885 @INTERNAL WRAPPER_IMPL
886 #[wrapper_impl(Borrow $(<$target:ty>)? )]
887 $($tt:tt)*
888 ) => {
889 $crate::wrapper! {
890 @INTERNAL WRAPPER_IMPL_BORROW $(<$target>)?
891 $($tt)*
892 }
893
894 $crate::wrapper! {
895 @INTERNAL WRAPPER_IMPL
896 $($tt)*
897 }
898 };
899
900 // Extract wrapper impl for `BorrowMut` trait.
901 (
902 @INTERNAL WRAPPER_IMPL
903 #[wrapper_impl(BorrowMut $(<$target:ty>)? )]
904 $($tt:tt)*
905 ) => {
906 $crate::wrapper! {
907 @INTERNAL WRAPPER_IMPL_BORROW $(<$target>)?
908 $($tt)*
909 }
910
911 $crate::wrapper! {
912 @INTERNAL WRAPPER_IMPL_BORROW_MUT $(<$target>)?
913 $($tt)*
914 }
915
916 $crate::wrapper! {
917 @INTERNAL WRAPPER_IMPL
918 $($tt)*
919 }
920 };
921
922 // Extract wrapper impl for `Debug` trait.
923 (
924 @INTERNAL WRAPPER_IMPL
925 #[wrapper_impl(Debug)]
926 $($tt:tt)*
927 ) => {
928 $crate::wrapper! {
929 @INTERNAL WRAPPER_IMPL_DEBUG
930 $($tt)*
931 }
932
933 $crate::wrapper! {
934 @INTERNAL WRAPPER_IMPL
935 $($tt)*
936 }
937 };
938
939 // Extract wrapper impl for `Debug` trait printing its name only.
940 (
941 @INTERNAL WRAPPER_IMPL
942 #[wrapper_impl(DebugName)]
943 $($tt:tt)*
944 ) => {
945 $crate::wrapper! {
946 @INTERNAL WRAPPER_IMPL_DEBUG_NAME
947 $($tt)*
948 }
949
950 $crate::wrapper! {
951 @INTERNAL WRAPPER_IMPL
952 $($tt)*
953 }
954 };
955
956 // Extract wrapper impl for `Display` trait.
957 (
958 @INTERNAL WRAPPER_IMPL
959 #[wrapper_impl(Display)]
960 $($tt:tt)*
961 ) => {
962 $crate::wrapper! {
963 @INTERNAL WRAPPER_IMPL_DISPLAY
964 $($tt)*
965 }
966
967 $crate::wrapper! {
968 @INTERNAL WRAPPER_IMPL
969 $($tt)*
970 }
971 };
972
973 // Extract wrapper impl for `Deref` trait.
974 (
975 @INTERNAL WRAPPER_IMPL
976 #[wrapper_impl(Deref $(<$target:ty>)? )]
977 $($tt:tt)*
978 ) => {
979 $crate::wrapper! {
980 @INTERNAL WRAPPER_IMPL_DEREF $(<$target>)?
981 $($tt)*
982 }
983
984 $crate::wrapper! {
985 @INTERNAL WRAPPER_IMPL
986 $($tt)*
987 }
988 };
989
990 // Extract wrapper impl for `DerefMut` trait (and `Deref`).
991 (
992 @INTERNAL WRAPPER_IMPL
993 #[wrapper_impl(DerefMut $(<$target:ty>)? )]
994 $($tt:tt)*
995 ) => {
996 $crate::wrapper! {
997 @INTERNAL WRAPPER_IMPL_DEREF $(<$target>)?
998 $($tt)*
999 }
1000
1001 $crate::wrapper! {
1002 @INTERNAL WRAPPER_IMPL_DEREF_MUT $(<$target>)?
1003 $($tt)*
1004 }
1005
1006 $crate::wrapper! {
1007 @INTERNAL WRAPPER_IMPL
1008 $($tt)*
1009 }
1010 };
1011
1012 // Extract wrapper impl for `From` trait.
1013 (
1014 @INTERNAL WRAPPER_IMPL
1015 #[wrapper_impl(From)]
1016 $($tt:tt)*
1017 ) => {
1018 $crate::wrapper! {
1019 @INTERNAL WRAPPER_IMPL_FROM
1020 $($tt)*
1021 }
1022
1023 $crate::wrapper! {
1024 @INTERNAL WRAPPER_IMPL
1025 $($tt)*
1026 }
1027 };
1028
1029 // ================ Impl `AsRef` trait for the wrapper type. ================
1030 (
1031 @INTERNAL WRAPPER_IMPL_AS_REF <$target:ty>
1032 $(#[$meta:meta])*
1033 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1034 ) => {
1035 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsRef<$target> for $name$(<$($lt),+>)? {
1036 fn as_ref(&self) -> &$target {
1037 &self.inner
1038 }
1039 }
1040 };
1041 (
1042 @INTERNAL WRAPPER_IMPL_AS_REF <$target:ty>
1043 $(#[$meta:meta])*
1044 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1045 $(#[$field_inner_meta:meta])*
1046 $inner_vis:vis $inner:ident: $inner_ty:ty
1047 $(
1048 ,
1049 $(#[$field_meta:meta])*
1050 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1051 )*
1052 $(,)?
1053 }
1054 ) => {
1055 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsRef<$target> for $name$(<$($lt),+>)? {
1056 fn as_ref(&self) -> &$target {
1057 &self.$inner
1058 }
1059 }
1060 };
1061 (
1062 @INTERNAL WRAPPER_IMPL_AS_REF
1063 $(#[$meta:meta])*
1064 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1065 ) => {
1066 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsRef<$inner_ty> for $name$(<$($lt),+>)? {
1067 fn as_ref(&self) -> &$inner_ty {
1068 &self.inner
1069 }
1070 }
1071
1072 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt),+>)? {
1073 /// Returns a reference to the inner value.
1074 #[inline(always)]
1075 pub const fn as_inner(&self) -> &$inner_ty {
1076 &self.inner
1077 }
1078 }
1079 };
1080 (
1081 @INTERNAL WRAPPER_IMPL_AS_REF
1082 $(#[$meta:meta])*
1083 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1084 $(#[$field_inner_meta:meta])*
1085 $inner_vis:vis $inner:ident: $inner_ty:ty
1086 $(
1087 ,
1088 $(#[$field_meta:meta])*
1089 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1090 )*
1091 $(,)?
1092 }
1093 ) => {
1094 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsRef<$inner_ty> for $name$(<$($lt),+>)? {
1095 fn as_ref(&self) -> &$inner_ty {
1096 &self.$inner
1097 }
1098 }
1099
1100 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt),+>)? {
1101 /// Returns a reference to the inner value.
1102 #[inline(always)]
1103 pub const fn as_inner(&self) -> &$inner_ty {
1104 &self.$inner
1105 }
1106 }
1107 };
1108 // ================ Impl `AsRef` trait for the wrapper type. ================
1109
1110
1111 // ================ Impl `AsMut` trait for the wrapper type. ================
1112 (
1113 @INTERNAL WRAPPER_IMPL_AS_MUT <$target:ty>
1114 $(#[$meta:meta])*
1115 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1116 ) => {
1117 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsMut<$target> for $name$(<$($lt),+>)? {
1118 fn as_mut(&mut self) -> &mut $target {
1119 &mut self.inner
1120 }
1121 }
1122 };
1123 (
1124 @INTERNAL WRAPPER_IMPL_AS_MUT <$target:ty>
1125 $(#[$meta:meta])*
1126 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1127 $(#[$field_inner_meta:meta])*
1128 $inner_vis:vis $inner:ident: $inner_ty:ty
1129 $(
1130 ,
1131 $(#[$field_meta:meta])*
1132 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1133 )*
1134 $(,)?
1135 }
1136 ) => {
1137 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsMut<$target> for $name$(<$($lt),+>)? {
1138 #[inline(always)]
1139 fn as_mut(&mut self) -> &mut $target {
1140 &mut self.$inner
1141 }
1142 }
1143 };
1144 (
1145 @INTERNAL WRAPPER_IMPL_AS_MUT
1146 $(#[$meta:meta])*
1147 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1148 ) => {
1149 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsMut<$inner_ty> for $name$(<$($lt),+>)? {
1150 fn as_mut(&mut self) -> &mut $inner_ty {
1151 &mut self.inner
1152 }
1153 }
1154
1155 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt),+>)? {
1156 #[inline(always)]
1157 /// Returns a mutable reference to the inner value.
1158 pub fn as_inner_mut(&mut self) -> &mut $inner_ty {
1159 &mut self.inner
1160 }
1161 }
1162 };
1163 (
1164 @INTERNAL WRAPPER_IMPL_AS_MUT
1165 $(#[$meta:meta])*
1166 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1167 $(#[$field_inner_meta:meta])*
1168 $inner_vis:vis $inner:ident: $inner_ty:ty
1169 $(
1170 ,
1171 $(#[$field_meta:meta])*
1172 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1173 )*
1174 $(,)?
1175 }
1176 ) => {
1177 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsMut<$inner_ty> for $name$(<$($lt),+>)? {
1178 #[inline(always)]
1179 fn as_mut(&mut self) -> &mut $inner_ty {
1180 &mut self.$inner
1181 }
1182 }
1183
1184 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt),+>)? {
1185 #[inline(always)]
1186 /// Returns a mutable reference to the inner value.
1187 pub fn as_inner_mut(&mut self) -> &mut $inner_ty {
1188 &mut self.$inner
1189 }
1190 }
1191 };
1192 (
1193 @INTERNAL WRAPPER_IMPL_CONST_AS_MUT <$target:ty>
1194 $(#[$meta:meta])*
1195 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1196 ) => {
1197 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsMut<$target> for $name$(<$($lt),+>)? {
1198 fn as_mut(&mut self) -> &mut $target {
1199 &mut self.inner
1200 }
1201 }
1202 };
1203 (
1204 @INTERNAL WRAPPER_IMPL_CONST_AS_MUT
1205 $(#[$meta:meta])*
1206 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1207 $(#[$field_inner_meta:meta])*
1208 $inner_vis:vis $inner:ident: $inner_ty:ty
1209 $(
1210 ,
1211 $(#[$field_meta:meta])*
1212 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1213 )*
1214 $(,)?
1215 }
1216 ) => {
1217 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsMut<$target> for $name$(<$($lt),+>)? {
1218 #[inline(always)]
1219 fn as_mut(&mut self) -> &mut $target {
1220 &mut self.$inner
1221 }
1222 }
1223 };
1224 (
1225 @INTERNAL WRAPPER_IMPL_CONST_AS_MUT
1226 $(#[$meta:meta])*
1227 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1228 ) => {
1229 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsMut<$inner_ty> for $name$(<$($lt),+>)? {
1230 fn as_mut(&mut self) -> &mut $inner_ty {
1231 &mut self.inner
1232 }
1233 }
1234
1235 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt),+>)? {
1236 #[inline(always)]
1237 /// Returns a mutable reference to the inner value.
1238 pub const fn as_inner_mut(&mut self) -> &mut $inner_ty {
1239 &mut self.inner
1240 }
1241 }
1242 };
1243 (
1244 @INTERNAL WRAPPER_IMPL_CONST_AS_MUT
1245 $(#[$meta:meta])*
1246 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1247 $(#[$field_inner_meta:meta])*
1248 $inner_vis:vis $inner:ident: $inner_ty:ty
1249 $(
1250 ,
1251 $(#[$field_meta:meta])*
1252 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1253 )*
1254 $(,)?
1255 }
1256 ) => {
1257 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::AsMut<$inner_ty> for $name$(<$($lt),+>)? {
1258 #[inline(always)]
1259 fn as_mut(&mut self) -> &mut $inner_ty {
1260 &mut self.$inner
1261 }
1262 }
1263
1264 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt),+>)? {
1265 #[inline(always)]
1266 /// Returns a mutable reference to the inner value.
1267 pub const fn as_inner_mut(&mut self) -> &mut $inner_ty {
1268 &mut self.$inner
1269 }
1270 }
1271 };
1272 // ================ Impl `AsMut` trait for the wrapper type. ================
1273
1274 // ================ Impl `Borrow` trait for the wrapper type. ================
1275 (
1276 @INTERNAL WRAPPER_IMPL_BORROW <$target:ty>
1277 $(#[$meta:meta])*
1278 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1279 ) => {
1280 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::borrow::Borrow<$target> for $name$(<$($lt),+>)? {
1281 fn borrow(&self) -> &$target {
1282 &self.inner
1283 }
1284 }
1285 };
1286 (
1287 @INTERNAL WRAPPER_IMPL_BORROW <$target:ty>
1288 $(#[$meta:meta])*
1289 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1290 $(#[$field_inner_meta:meta])*
1291 $inner_vis:vis $inner:ident: $inner_ty:ty
1292 $(
1293 ,
1294 $(#[$field_meta:meta])*
1295 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1296 )*
1297 $(,)?
1298 }
1299 ) => {
1300 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::borrow::Borrow<$target> for $name$(<$($lt),+>)? {
1301 fn borrow(&self) -> &$target {
1302 &self.$inner
1303 }
1304 }
1305 };
1306 (
1307 @INTERNAL WRAPPER_IMPL_BORROW
1308 $(#[$meta:meta])*
1309 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1310 ) => {
1311 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::borrow::Borrow<$inner_ty> for $name$(<$($lt),+>)? {
1312 fn borrow(&self) -> &$inner_ty {
1313 &self.inner
1314 }
1315 }
1316 };
1317 (
1318 @INTERNAL WRAPPER_IMPL_BORROW
1319 $(#[$meta:meta])*
1320 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1321 $(#[$field_inner_meta:meta])*
1322 $inner_vis:vis $inner:ident: $inner_ty:ty
1323 $(
1324 ,
1325 $(#[$field_meta:meta])*
1326 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1327 )*
1328 $(,)?
1329 }
1330 ) => {
1331 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::borrow::Borrow<$inner_ty> for $name$(<$($lt),+>)? {
1332 fn borrow(&self) -> &$inner_ty {
1333 &self.$inner
1334 }
1335 }
1336 };
1337 // ================ Impl `Borrow` trait for the wrapper type. ================
1338
1339 // ================ Impl `BorrowMut` trait for the wrapper type. ================
1340 (
1341 @INTERNAL WRAPPER_IMPL_BORROW_MUT <$target:ty>
1342 $(#[$meta:meta])*
1343 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1344 ) => {
1345 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::borrow::BorrowMut<$target> for $name$(<$($lt),+>)? {
1346 fn borrow_mut(&mut self) -> &mut $target {
1347 &mut self.inner
1348 }
1349 }
1350 };
1351 (
1352 @INTERNAL WRAPPER_IMPL_BORROW_MUT <$target:ty>
1353 $(#[$meta:meta])*
1354 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1355 $(#[$field_inner_meta:meta])*
1356 $inner_vis:vis $inner:ident: $inner_ty:ty
1357 $(
1358 ,
1359 $(#[$field_meta:meta])*
1360 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1361 )*
1362 $(,)?
1363 }
1364 ) => {
1365 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::borrow::BorrowMut<$target> for $name$(<$($lt),+>)? {
1366 fn borrow_mut(&mut self) -> &mut $target {
1367 &mut self.$inner
1368 }
1369 }
1370 };
1371 (
1372 @INTERNAL WRAPPER_IMPL_BORROW_MUT
1373 $(#[$meta:meta])*
1374 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1375 ) => {
1376 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::borrow::BorrowMut<$inner_ty> for $name$(<$($lt),+>)? {
1377 fn borrow_mut(&mut self) -> &mut $inner_ty {
1378 &mut self.inner
1379 }
1380 }
1381 };
1382 (
1383 @INTERNAL WRAPPER_IMPL_BORROW_MUT
1384 $(#[$meta:meta])*
1385 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1386 $(#[$field_inner_meta:meta])*
1387 $inner_vis:vis $inner:ident: $inner_ty:ty
1388 $(
1389 ,
1390 $(#[$field_meta:meta])*
1391 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1392 )*
1393 $(,)?
1394 }
1395 ) => {
1396 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::borrow::BorrowMut<$inner_ty> for $name$(<$($lt),+>)? {
1397 fn borrow_mut(&mut self) -> &mut $inner_ty {
1398 &mut self.$inner
1399 }
1400 }
1401 };
1402 // ================ Impl `Borrow` trait for the wrapper type. ================
1403
1404 // ================ Impl `Debug` trait for the wrapper type. ================
1405 (
1406 @INTERNAL WRAPPER_IMPL_DEBUG
1407 $(#[$meta:meta])*
1408 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1409 ) => {
1410 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::fmt::Debug for $name$(<$($lt),+>)?
1411 where
1412 $inner_ty: ::core::fmt::Debug,
1413 {
1414 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1415 self.inner.fmt(f)
1416 }
1417 }
1418 };
1419 (
1420 @INTERNAL WRAPPER_IMPL_DEBUG
1421 $(#[$meta:meta])*
1422 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1423 $(#[$field_inner_meta:meta])*
1424 $inner_vis:vis $inner:ident: $inner_ty:ty
1425 $(
1426 ,
1427 $(#[$field_meta:meta])*
1428 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1429 )*
1430 $(,)?
1431 }
1432 ) => {
1433 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::fmt::Debug for $name$(<$($lt),+>)?
1434 where
1435 $inner_ty: ::core::fmt::Debug,
1436 {
1437 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1438 self.$inner.fmt(f)
1439 }
1440 }
1441 };
1442 // ================ Impl `Debug` trait for the wrapper type. ================
1443
1444 // ================ Impl `DebugName` trait for the wrapper type. ================
1445 (
1446 @INTERNAL WRAPPER_IMPL_DEBUG_NAME
1447 $(#[$meta:meta])*
1448 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1449 ) => {
1450 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::fmt::Debug for $name$(<$($lt),+>)? {
1451 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1452 f.debug_struct(stringify!($name)).finish()
1453 }
1454 }
1455 };
1456 (
1457 @INTERNAL WRAPPER_IMPL_DEBUG_NAME
1458 $(#[$meta:meta])*
1459 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1460 $(#[$field_inner_meta:meta])*
1461 $inner_vis:vis $inner:ident: $inner_ty:ty
1462 $(
1463 ,
1464 $(#[$field_meta:meta])*
1465 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1466 )*
1467 $(,)?
1468 }
1469 ) => {
1470 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::fmt::Debug for $name$(<$($lt),+>)? {
1471 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1472 f.debug_struct(stringify!($name)).finish()
1473 }
1474 }
1475 };
1476 // ================ Impl `DebugName` trait for the wrapper type. ================
1477
1478 // ================ Impl `Display` trait for the wrapper type. ================
1479 (
1480 @INTERNAL WRAPPER_IMPL_DISPLAY
1481 $(#[$meta:meta])*
1482 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1483 ) => {
1484 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::fmt::Display for $name$(<$($lt),+>)?
1485 where
1486 $inner_ty: ::core::fmt::Display,
1487 {
1488 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1489 self.inner.fmt(f)
1490 }
1491 }
1492 };
1493 (
1494 @INTERNAL WRAPPER_IMPL_DISPLAY
1495 $(#[$meta:meta])*
1496 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1497 $(#[$field_inner_meta:meta])*
1498 $inner_vis:vis $inner:ident: $inner_ty:ty
1499 $(
1500 ,
1501 $(#[$field_meta:meta])*
1502 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1503 )*
1504 $(,)?
1505 }
1506 ) => {
1507 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::fmt::Display for $name$(<$($lt),+>)?
1508 where
1509 $inner_ty: ::core::fmt::Display,
1510 {
1511 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
1512 self.$inner.fmt(f)
1513 }
1514 }
1515 };
1516 // ================ Impl `Display` trait for the wrapper type. ================
1517
1518 // ================ Impl `Deref` trait for the wrapper type. ================
1519 (
1520 @INTERNAL WRAPPER_IMPL_DEREF <$target:ty>
1521 $(#[$meta:meta])*
1522 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1523 ) => {
1524 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::ops::Deref for $name$(<$($lt),+>)? {
1525 type Target = $target;
1526
1527 fn deref(&self) -> &Self::Target {
1528 &self.inner
1529 }
1530 }
1531 };
1532 (
1533 @INTERNAL WRAPPER_IMPL_DEREF <$target:ty>
1534 $(#[$meta:meta])*
1535 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1536 $(#[$field_inner_meta:meta])*
1537 $inner_vis:vis $inner:ident: $inner_ty:ty
1538 $(
1539 ,
1540 $(#[$field_meta:meta])*
1541 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1542 )*
1543 $(,)?
1544 }
1545 ) => {
1546 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::ops::Deref for $name$(<$($lt),+>)? {
1547 type Target = $target;
1548
1549 fn deref(&self) -> &Self::Target {
1550 &self.$inner
1551 }
1552 }
1553 };
1554 (
1555 @INTERNAL WRAPPER_IMPL_DEREF
1556 $(#[$meta:meta])*
1557 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1558 ) => {
1559 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::ops::Deref for $name$(<$($lt),+>)? {
1560 type Target = $inner_ty;
1561
1562 fn deref(&self) -> &Self::Target {
1563 &self.inner
1564 }
1565 }
1566 };
1567 (
1568 @INTERNAL WRAPPER_IMPL_DEREF
1569 $(#[$meta:meta])*
1570 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1571 $(#[$field_inner_meta:meta])*
1572 $inner_vis:vis $inner:ident: $inner_ty:ty
1573 $(
1574 ,
1575 $(#[$field_meta:meta])*
1576 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1577 )*
1578 $(,)?
1579 }
1580 ) => {
1581 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::ops::Deref for $name$(<$($lt),+>)? {
1582 type Target = $inner_ty;
1583
1584 fn deref(&self) -> &Self::Target {
1585 &self.$inner
1586 }
1587 }
1588 };
1589 // ================ Impl `Deref` trait for the wrapper type. ================
1590
1591 // ================ Impl `DerefMut` traits for the wrapper type. ================
1592 (
1593 @INTERNAL WRAPPER_IMPL_DEREF_MUT <$target:ty>
1594 $(#[$meta:meta])*
1595 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1596 ) => {
1597 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::ops::DerefMut for $name$(<$($lt),+>)? {
1598 fn deref_mut(&mut self) -> &mut Self::Target {
1599 &mut self.inner
1600 }
1601 }
1602 };
1603 (
1604 @INTERNAL WRAPPER_IMPL_DEREF_MUT <$target:ty>
1605 $(#[$meta:meta])*
1606 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1607 $(#[$field_inner_meta:meta])*
1608 $inner_vis:vis $inner:ident: $inner_ty:ty
1609 $(
1610 ,
1611 $(#[$field_meta:meta])*
1612 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1613 )*
1614 $(,)?
1615 }
1616 ) => {
1617 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::ops::DerefMut for $name$(<$($lt),+>)? {
1618 fn deref_mut(&mut self) -> &mut Self::Target {
1619 &mut self.$inner
1620 }
1621 }
1622 };
1623 (
1624 @INTERNAL WRAPPER_IMPL_DEREF_MUT
1625 $(#[$meta:meta])*
1626 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1627 ) => {
1628 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::ops::DerefMut for $name$(<$($lt),+>)? {
1629 fn deref_mut(&mut self) -> &mut Self::Target {
1630 &mut self.inner
1631 }
1632 }
1633 };
1634 (
1635 @INTERNAL WRAPPER_IMPL_DEREF_MUT
1636 $(#[$meta:meta])*
1637 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1638 $(#[$field_inner_meta:meta])*
1639 $inner_vis:vis $inner:ident: $inner_ty:ty
1640 $(
1641 ,
1642 $(#[$field_meta:meta])*
1643 $field_vis:vis $field:ident: $field_ty:ty$( = $field_default: expr)?
1644 )*
1645 $(,)?
1646 }
1647 ) => {
1648 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::ops::DerefMut for $name$(<$($lt),+>)? {
1649 fn deref_mut(&mut self) -> &mut Self::Target {
1650 &mut self.$inner
1651 }
1652 }
1653 };
1654 // ================ Impl `DerefMut` traits for the wrapper type. ================
1655
1656 // ================ Impl `From` trait for the wrapper type. ================
1657 (
1658 @INTERNAL WRAPPER_IMPL_FROM
1659 $(#[$meta:meta])*
1660 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? ($inner_vis:vis $inner_ty:ty);
1661 ) => {
1662 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::From<$inner_ty> for $name$(<$($lt),+>)? {
1663 fn from(inner: $inner_ty) -> Self {
1664 Self::const_from(inner)
1665 }
1666 }
1667
1668 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt),+>)? {
1669 /// Creates a new instance of the wrapper type from the inner value.
1670 #[allow(unreachable_pub)]
1671 #[inline(always)]
1672 pub const fn from(inner: $inner_ty) -> Self {
1673 Self::const_from(inner)
1674 }
1675 }
1676 };
1677 (
1678 @INTERNAL WRAPPER_IMPL_FROM
1679 $(#[$meta:meta])*
1680 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1681 $(#[$field_inner_meta:meta])*
1682 $inner_vis:vis $inner:ident: $inner_ty:ty
1683 $(
1684 ,
1685 $(#[$field_meta:meta])*
1686 $field_vis:vis $field:ident: $field_ty:ty = $field_default:expr
1687 )*
1688 $(,)?
1689 }
1690 ) => {
1691 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? ::core::convert::From<$inner_ty> for $name$(<$($lt),+>)? {
1692 fn from($inner: $inner_ty) -> Self {
1693 Self::const_from($inner)
1694 }
1695 }
1696
1697 impl$(<$($lt$(:$clt$(+$dlt)*)?),+>)? $name$(<$($lt),+>)? {
1698 /// Creates a new instance of the wrapper type from the inner value.
1699 #[allow(unreachable_pub)]
1700 #[inline(always)]
1701 pub const fn from($inner: $inner_ty) -> Self {
1702 Self::const_from($inner)
1703 }
1704 }
1705 };
1706 (
1707 @INTERNAL WRAPPER_IMPL_FROM
1708 $(#[$meta:meta])*
1709 $vis:vis struct $name:ident$(<$($lt:tt$(:$clt:tt$(+$dlt:tt)*)?),+>)? {
1710 $(#[$field_inner_meta:meta])*
1711 $inner_vis:vis $inner:ident: $inner_ty:ty
1712 $(
1713 ,
1714 $(#[$field_meta:meta])*
1715 $field_vis:vis $field:ident: $field_ty:ty
1716 )*
1717 $(,)?
1718 }
1719 ) => {
1720 compile_error!(
1721 "Invalid usage of `wrapper!` macro, cannot implement \
1722 `From` trait for wrapper types with multiple fields\
1723 but no default values given."
1724 );
1725 };
1726 // ================ Impl `From` trait for the wrapper type. ================
1727
1728 // No other wrapper_impl meta
1729 (@INTERNAL WRAPPER_IMPL $($tt:tt)*) => {};
1730
1731 // Catch-all for invalid usage of the macro.
1732 (@INTERNAL $($tt:tt)*) => {
1733 compile_error!(
1734 "Invalid usage of `wrapper!` macro. @INTERNAL \
1735 Please refer to the documentation for the correct syntax."
1736 );
1737 };
1738
1739 // Core macro for the wrapper type.
1740 ($($tt:tt)*) => {
1741 $crate::wrapper!(@INTERNAL IMPL $($tt)*);
1742 $crate::wrapper!(@INTERNAL WRAPPER_IMPL $($tt)*);
1743 };
1744}