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