devela/sys/mem/cswap.rs
1// devela::sys::mem::cswap
2//
3//! Defines the [`cswap!`] macro.
4//
5
6/// Swaps two mutable variables in a *compile-time* friendly manner.
7///
8/// For that it uses either:
9/// 1. a temporary variable.
10/// 3. [`Mem::swap`] over their respective mutable references.
11/// 3. the [xor swap method], making sure the values are not the same, first.
12/// 4. the xor swap method, unchecked. If both values are the same they will get corrupted.
13///
14/// [xor swap method]: https://en.wikipedia.org/wiki/XOR_swap_algorithm
15#[macro_export]
16#[cfg_attr(cargo_primary_package, doc(hidden))]
17macro_rules! cswap {
18 ( // defaults to `tmp`
19 $a:expr, $b:expr) => {{ $crate::cswap![tmp: $a, $b]; }};
20 (xor // deprecated(since = "0.23.0", note = "Use `xor:`")
21 $a:expr, $b:expr) => {{ $crate::cswap![xor: $a, $b]; }};
22 (tmp:
23 // swaps two values using a temporary variable.
24 $a:expr, $b:expr) => {{ let tmp = $a; $a = $b; $b = tmp; }};
25 (mut:
26 // swaps two values by calling core's `swap` over their mut references.
27 $a:expr, $b:expr) => {{ $crate::Mem::swap(&mut $a, &mut $b); }};
28 (xor:
29 // swaps two `T: PartialEq + BitXorAssign` values without a temporary variable.
30 $a:expr, $b:expr) => {{ if $a != $b { $a ^= $b; $b ^= $a; $a ^= $b; } }};
31 (xor_unchecked:
32 // swaps two `T: PartialEq + BitXorAssign` values without a temporary variable,
33 // without making sure they are both equal, in which case they'll get corrupted.
34 $a:expr, $b:expr) => {{ $a ^= $b; $b ^= $a; $a ^= $b; }};
35}
36#[doc(inline)]
37pub use cswap;