1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
//! A crate to swap values between possibly-overlapping references.
//!
//! ## Motivating Example
//!
//! You cannot simply use [`std::mem::swap`] to replace values within an array:
//!
//! ```rust,compile_fail
//! let mut a = [1, 2, 3];
//! // You cannot prove their disjointness!
//! std::mem::swap(&mut a[0], &mut a[2]);
//! ```
//!
//! You get the following message:
//!
//! ```text
//! error[E0499]: cannot borrow `a[_]` as mutable more than once at a time
//! --> src/main.rs:4:31
//! |
//! 4 | std::mem::swap(&mut a[0], &mut a[2]);
//! | -------------- --------- ^^^^^^^^^ second mutable borrow occurs here
//! | | |
//! | | first mutable borrow occurs here
//! | first borrow later used by call
//! |
//! = help: consider using `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices
//! ```
//!
//! You can use the dedicated [`<[T]>::swap`][slice::swap()] instead:
//!
//! ```rust
//! let mut a = [1, 2, 3];
//! a.swap(0, 2);
//! ```
//!
//! But how about two-dimensional arrays?
//!
//! ```rust,compile_fail
//! let mut a = [[1, 2], [3, 4]];
//! // You cannot prove their disjointness!
//! std::mem::swap(&mut a[0][0], &mut a[1][1]);
//! ```
//!
//! This is not as simple as the first one.
//!
//! ## Solution
//!
//! This crate solves the problem by providing a generic framework for
//! **sentinel-based swapping**.
//!
//! The idea is simple: it leaves a dummy value behind to safely
//! move values around:
//!
//! ```rust
//! let mut a = [[1, 2], [3, 4]];
//! let tmp = std::mem::replace(&mut a[0][0], 0);
//! let tmp = std::mem::replace(&mut a[1][1], tmp);
//! a[0][0] = tmp;
//! # assert_eq!(a, [[4, 2], [3, 1]]);
//! ```
//!
//! However, in Rust, the best sentinel value differs between types.
//!
//! The macro [`swap!`] automatically chooses the best sentinel and
//! provides the same interface as [`std::mem::swap`]:
//!
//! ```rust
//! let mut a = [[1, 2], [3, 4]];
//! omniswap::swap!(&mut a[0][0], &mut a[1][1]);
//! # assert_eq!(a, [[4, 2], [3, 1]]);
//! ```
//!
//! ## Usage
//!
//! Simply use [`swap!`] where you want to use [`std::mem::swap`]:
//!
//! ```rust
//! let mut x = 42;
//! let mut y = 84;
//! omniswap::swap!(&mut x, &mut y);
//! ```
//!
//! See [`swap!`] for detailed usages.
//!
//! ## Other APIs
//!
//! The crate provides the following variants:
//!
//! - [`rotate!`] -- swaps more than two values at once
//!
//!
//! The crate also exposes [`take!`] and [`Replace`].
//! These are primitives used in [`swap!`] and [`rotate!`].
#![no_std]
mod replace;
mod swap;
mod take;
pub use crate::replace::Replace;
pub use crate::take::{TakeHelper, TakeHelper2, TakeHelper3};