inplace-iter

Crates.ioinplace-iter
lib.rsinplace-iter
version0.3.0
created_at2025-05-27 15:08:19.346928+00
updated_at2025-05-29 13:22:57.92185+00
descriptionEfficient in-place iteration with O(1) element removal and taking operations
homepagehttps://github.com/anickaburova/inplace-iter
repositoryhttps://github.com/anickaburova/inplace-iter
max_upload_size
id1691229
size54,397
(AnickaBurova)

documentation

https://docs.rs/inplace-iter

README

In-Place Iteration with Removal/Take Operations

Crates.io Documentation License

A Rust library providing iterators that allow efficient in-place modification of collections with O(1) removal and take operations.

Features

  • Efficient Removal: Remove elements in O(1) time by swapping with the last element
  • Zero-Copy Taking: Take ownership of elements without cloning
  • Safe Abstraction: Encapsulates unsafe code behind a safe API
  • Optional Lifetime Guard: Additional runtime checks with loop-lifetime-guard feature (enabled by default)

Usage

Add this to your Cargo.toml:

[dependencies]
inplace-iter = "0.1"

Examples

Removing Elements

use inplace_iter::prelude::*;

let mut numbers = vec![1, 2, 3, 4, 5];
for item in numbers.removable_iter() {
    if *item.get() % 2 == 0 {
        item.remove(); // Efficiently remove even numbers
    }
}
// Order is not preserved, but all even numbers are removed
assert_eq!(numbers.len(), 3);

Taking Elements

use inplace_iter::prelude::*;

let mut names = vec!["Alice".to_string(), "Bob".to_string(), "Charlie".to_string()];
let mut long_names = Vec::new();

for item in names.takeable_iter() {
    if item.get().len() > 4 {
        long_names.push(item.take()); // Take ownership of long names
    }
}

assert_eq!(long_names, vec!["Alice".to_string(), "Charlie".to_string()]);
assert_eq!(names.len(), 1);
assert_eq!(names[0], "Bob");

Taking Elements with Mutable Access

use inplace_iter::prelude::*;

let mut numbers = vec![1, 2, 3, 4, 5];
let mut sum = 0;
for mut item in numbers.takeable_iter_mut() {
    if *item.get() > 3 {
        // Take ownership of elements > 3
        sum += item.take();
    } else {
        // Double odd numbers
        *item.get_mut() *= 2;
    }
}
assert_eq!(sum, 9); // 4 + 5
assert_eq!(numbers.len(), 3);
assert_eq!(numbers, vec![2, 4, 6]);

Removing elements while iterating with confirmation

use inplace_iter::prelude::*;

let mut numbers = vec![1, 2, 3, 4, 5];
let mut confirm = numbers.removable_confirm_iter();
for item in confirm.iter() {
    if *item.get() % 2 == 0 {
        item.remove(); // Efficiently remove even numbers
    }
}
// Multiple calls to `iter()` are allowed, and the subsequent iterations will not yield the removed elements.
let next_iter = confirm.iter().map(|i| *i.get()).collect::<Vec<_>>();
assert_eq!(next_iter, vec![1,5,3]);
confirm.confirm_removals();


assert_eq!(numbers, vec![1, 5, 3]);

Removing elements while iterating with confirmation, but cancelling

use inplace_iter::prelude::*;

let mut numbers = vec![1, 2, 3, 4, 5];
let mut confirm = numbers.removable_confirm_iter();
for item in confirm.iter() {
    if *item.get() % 2 == 0 {
        item.remove(); // Efficiently remove even numbers
    }
}
confirm.cancel_removals();
// Order after cancellation is not guaranteed. Also, if used on mutable iterator, the elements will stay
// modified after cancelling!
assert_eq!(numbers, vec![1, 5, 3, 4, 2]);

Safety

This library uses unsafe code internally to provide its functionality. While the API is designed to be safe, incorrect usage can lead to undefined behavior. Always follow these guidelines:

  1. Don't hold multiple mutable references to the same element

  2. Don't use an item after it has been removed/taken

  3. The loop-lifetime-guard feature (enabled by default) adds runtime checks to detect invalid item usage

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[0.2.0] - 2025-05-28

Added

  • Mutable versions of all iterators (iter_mut() variants)

[0.3.0] - 2025-05-29

Added

  • Confirmation of removals iterator wrapper (mut and const)

License

Licensed under either of:

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Commit count: 8

cargo fmt