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;