Skip to content

Commit c2333fd

Browse files
committed
Initial commit
0 parents  commit c2333fd

File tree

7 files changed

+482
-0
lines changed

7 files changed

+482
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
/Cargo.lock

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5+
6+
## [0.1.0] - 2023-07-10
7+
8+
### Internal
9+
10+
- 🎉 Initial release.
11+
12+
[0.1.0]: https://github.com/sunsided/swap3-rs/releases/tag/0.1.0

Cargo.toml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[package]
2+
name = "swap3"
3+
version = "0.1.0"
4+
description = "Swapping of three references, rotating the values left or right"
5+
authors = ["Markus Mayer"]
6+
repository = "https://github.com/sunsided/swap3-rs"
7+
keywords = ["swapping", "rotation"]
8+
categories = ["algorithms"]
9+
license = "MIT"
10+
readme = "README.md"
11+
edition = "2021"
12+
13+
[features]
14+
unsafe = []
15+
16+
[dev-dependencies]
17+
criterion = "0.5.1"
18+
rand = "0.8.5"
19+
20+
[[bench]]
21+
name = "rot_slice"
22+
harness = false
23+
24+
[package.metadata.docs.rs]
25+
all-features = true
26+
rustdoc-args = ["--cfg", "docsrs"]

LICENSE.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# The MIT License (MIT)
2+
3+
Copyright © 2023 Markus Mayer
4+
Copyright © The Rust Core Library authors
5+
6+
Permission is hereby granted, free of charge, to any person
7+
obtaining a copy of this software and associated documentation
8+
files (the “Software”), to deal in the Software without
9+
restriction, including without limitation the rights to use,
10+
copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the
12+
Software is furnished to do so, subject to the following
13+
conditions:
14+
15+
The above copyright notice and this permission notice shall be
16+
included in all copies or substantial portions of the Software.
17+
18+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
19+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25+
OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# swap3
2+
3+
Provides utility functions for simultaneously swapping three values by rotating them
4+
either left (`abc``bca`) or right (`abc``cab`). These functions can come in handy e.g.
5+
when rotating elements of a binary tree in list representation.
6+
7+
The provided functions work on arbitrary types and do *not* require the type to be `Clone`, `Copy`
8+
or `Default`.
9+
10+
## Examples
11+
12+
For individual references, the `swap3_bca` (rotate left) and `swap3_cab` (rotate right)
13+
functions are available:
14+
15+
```rust
16+
fn swap3_bca() {
17+
let mut a = 10;
18+
let mut b = 20;
19+
let mut c = 30;
20+
21+
swap3::swap3_bca(&mut a, &mut b, &mut c);
22+
assert_eq!([a, b, c], [20, 30, 10]);
23+
}
24+
```
25+
26+
For slices, the `swap3_bca_slice` and `swap3_cab_slice` functions can be used:
27+
28+
```rust
29+
fn swap3_bca() {
30+
let mut vec = vec![10, 20, 30, 40, 50, 60];
31+
swap3::swap3_bca_slice(&mut vec, 0, 1, 4);
32+
assert_eq!(vec, &[30, 50, 30, 40, 10, 60]);
33+
}
34+
```

benches/rot_slice.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use criterion::{black_box, criterion_group, criterion_main, Criterion};
2+
use rand::prelude::*;
3+
use swap3::slice;
4+
5+
pub fn criterion_benchmark(c: &mut Criterion) {
6+
let indexes = get_indexes(42);
7+
8+
c.bench_function("bca_safe", |bencher| {
9+
let mut values = black_box(get_values());
10+
bencher.iter(|| {
11+
for (a, b, c) in indexes.iter().cloned() {
12+
slice::bca_safe(&mut values, a, b, c)
13+
}
14+
})
15+
});
16+
17+
#[cfg(feature = "unsafe")]
18+
c.bench_function("bca_unsafe", |bencher| {
19+
let mut values = black_box(get_values());
20+
bencher.iter(|| {
21+
for (a, b, c) in indexes.iter().cloned() {
22+
slice::bca_unsafe(&mut values, a, b, c)
23+
}
24+
})
25+
});
26+
27+
c.bench_function("cab_safe", |bencher| {
28+
let mut values = black_box(get_values());
29+
bencher.iter(|| {
30+
for (a, b, c) in indexes.iter().cloned() {
31+
slice::cab_safe(&mut values, a, b, c)
32+
}
33+
})
34+
});
35+
36+
#[cfg(feature = "unsafe")]
37+
c.bench_function("cab_unsafe", |bencher| {
38+
let mut values = black_box(get_values());
39+
bencher.iter(|| {
40+
for (a, b, c) in indexes.iter().cloned() {
41+
slice::cab_unsafe(&mut values, a, b, c)
42+
}
43+
})
44+
});
45+
}
46+
47+
fn get_values() -> Vec<u64> {
48+
(0..100).map(|v| v + 1000).collect()
49+
}
50+
51+
fn get_indexes(seed: u64) -> Vec<(usize, usize, usize)> {
52+
let mut rng = StdRng::seed_from_u64(seed);
53+
(0..100)
54+
.map(|_| {
55+
let a = rng.gen_range(0..100);
56+
let mut b = rng.gen_range(0..100);
57+
while b == a {
58+
b = rng.gen_range(0..100);
59+
}
60+
let mut c = rng.gen_range(0..100);
61+
while c == a || c == b {
62+
c = rng.gen_range(0..100);
63+
}
64+
(a, b, c)
65+
})
66+
.collect()
67+
}
68+
69+
criterion_group!(benches, criterion_benchmark);
70+
criterion_main!(benches);

0 commit comments

Comments
 (0)