{"id":13484749,"url":"https://github.com/qnighy/omniswap","last_synced_at":"2025-05-01T12:50:29.781Z","repository":{"id":62445014,"uuid":"526881188","full_name":"qnighy/omniswap","owner":"qnighy","description":"a crate to swap values between possibly-overlapping references","archived":false,"fork":false,"pushed_at":"2022-08-22T22:28:01.000Z","size":13,"stargazers_count":23,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-01T12:49:45.808Z","etag":null,"topics":["rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/qnighy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-08-20T09:27:40.000Z","updated_at":"2023-07-02T09:06:31.000Z","dependencies_parsed_at":"2022-11-01T23:33:39.037Z","dependency_job_id":null,"html_url":"https://github.com/qnighy/omniswap","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qnighy%2Fomniswap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qnighy%2Fomniswap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qnighy%2Fomniswap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qnighy%2Fomniswap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qnighy","download_url":"https://codeload.github.com/qnighy/omniswap/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251879117,"owners_count":21658690,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["rust"],"created_at":"2024-07-31T17:01:32.401Z","updated_at":"2025-05-01T12:50:29.699Z","avatar_url":"https://github.com/qnighy.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# omniswap: a crate to swap values between possibly-overlapping references\n\n## Motivating Example\n\nYou cannot simply use `std::mem::swap` to replace values within an array:\n\n```rust\nlet mut a = [1, 2, 3];\n// You cannot prove their disjointness!\nstd::mem::swap(\u0026mut a[0], \u0026mut a[2]);\n```\n\nYou get the following message:\n\n```text\nerror[E0499]: cannot borrow `a[_]` as mutable more than once at a time\n --\u003e src/main.rs:4:31\n  |\n4 |     std::mem::swap(\u0026mut a[0], \u0026mut a[2]);\n  |     -------------- ---------  ^^^^^^^^^ second mutable borrow occurs here\n  |     |              |\n  |     |              first mutable borrow occurs here\n  |     first borrow later used by call\n  |\n  = help: consider using `.split_at_mut(position)` or similar method to obtain two mutable non-overlapping sub-slices\n```\n\nYou can use the dedicated `\u003c[T]\u003e::swap` instead:\n\n```rust\nlet mut a = [1, 2, 3];\na.swap(0, 2);\n```\n\nBut how about two-dimensional arrays?\n\n```rust\nlet mut a = [[1, 2], [3, 4]];\n// You cannot prove their disjointness!\nstd::mem::swap(\u0026mut a[0][0], \u0026mut a[1][1]);\n```\n\nThis is not as simple as the first one.\n\n## Solution\n\nThis crate solves the problem by providing a generic framework for\n**sentinel-based swapping**.\n\nThe idea is simple: it leaves a dummy value behind to safely\nmove values around:\n\n```rust\nlet mut a = [[1, 2], [3, 4]];\nlet tmp = std::mem::replace(\u0026mut a[0][0], 0);\nlet tmp = std::mem::replace(\u0026mut a[1][1], tmp);\na[0][0] = tmp;\n# assert_eq!(a, [[4, 2], [3, 1]]);\n```\n\nHowever, in Rust, the best sentinel value differs between types.\n\nThe macro `swap!` automatically chooses the best sentinel and\nprovides the same interface as `std::mem::swap`:\n\n```rust\nlet mut a = [[1, 2], [3, 4]];\nomniswap::swap!(\u0026mut a[0][0], \u0026mut a[1][1]);\n# assert_eq!(a, [[4, 2], [3, 1]]);\n```\n\n## Usage\n\nSimply use `swap!` where you want to use `std::mem::swap`:\n\n```rust\nlet mut x = 42;\nlet mut y = 84;\nomniswap::swap!(\u0026mut x, \u0026mut y);\n```\n\nSee `swap!` for detailed usages.\n\n## Other APIs\n\nThe crate provides the following variants:\n\n- `rotate!` -- swaps more than two values at once\n\n\nThe crate also exposes `take!` and `Replace`.\nThese are primitives used in `swap!` and `rotate!`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqnighy%2Fomniswap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqnighy%2Fomniswap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqnighy%2Fomniswap/lists"}