Skip to content

Commit

Permalink
swap
Browse files Browse the repository at this point in the history
  • Loading branch information
2A5F committed Nov 22, 2023
1 parent 611512b commit 11f13bf
Show file tree
Hide file tree
Showing 9 changed files with 30,902 additions and 13 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Provides many useful tools related to tuples
- Shorthand Macro
- Call
- Apply
- Swap
- Sort

## Examples
Expand Down Expand Up @@ -246,6 +247,25 @@ Provides many useful tools related to tuples
let r = foo.apply_tuple(a);
assert_eq!(r, 6)
```
- swap
```rust
let mut a = (1, 2, 3, 4, 5);
a.swap(1, 3);
assert_eq!(a, (1, 4, 3, 2, 5));
```
- swap_n

**Not enabled by default**

```toml
features = ["tuple_swap_n"]
```

```rust
let mut a = (1, 2, 3, 4, 5);
a.swap_1_3();
assert_eq!(a, (1, 4, 3, 2, 5));
```
- sort
currently implemented

Expand Down
79 changes: 79 additions & 0 deletions code_gen/src/code_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub fn code_gen(out_dir: &Path) {
gen_apply_tuple(&ctx, &out_dir);
gen_capt(&ctx, &out_dir);
gen_tuple_get(&ctx, &out_dir);
gen_tuple_swap(&ctx, &out_dir);
}

#[allow(dead_code)]
Expand Down Expand Up @@ -1400,6 +1401,84 @@ fn gen_tuple_get_size(ctx: &Ctx, size: usize) -> TokenStream {
}
}
}

impl<T> TupleSwap for (#(#ts,)*) {
fn swap(&mut self, a: usize, b: usize) {
if a >= #size || b >= #size {
panic!("index out of bounds: the len is {} but the index is {} and {}", #size, a, b);
}
if a == b {
return;
}
unsafe {
let this = self as *mut Self;
let a = (&mut *this).get_mut(a);
let b = (&mut *this).get_mut(b);
core::mem::swap(a, b);
}
}

fn try_swap(&mut self, a: usize, b: usize) -> bool {
if a >= #size || b >= #size {
return false;
}
if a == b {
return true;
}
unsafe {
let this = self as *mut Self;
let a = (&mut *this).get_mut(a);
let b = (&mut *this).get_mut(b);
core::mem::swap(a, b);
}
true
}
}
};
tks
}

fn gen_tuple_swap(ctx: &Ctx, out_dir: &Path) {
let tks = gen_tuple_swap_cart(ctx);
let mut code = tks.to_string();
code.insert_str(0, "// This file is by code gen, do not modify\n\n");
let dest_path = Path::new(out_dir).join("tuple_swap_n.rs");
fs::write(&dest_path, code).unwrap();
}

fn gen_tuple_swap_cart(ctx: &Ctx) -> TokenStream {
let nts = &ctx.nts[0..32usize];
let size_lits = &ctx.size_lits[0..32usize];
let swap = (0..32usize).flat_map(|a| (a..32usize).map(move |b| (a, b))).filter(|(a, b)| *a != *b).map(|(a, b)| {
let trait_name = format_ident!("TupleSwap_{}_{}", a, b);
let fn_name = format_ident!("swap_{}_{}", a, b);
let fixed_type = format_ident!("T");
let min = a.max(b) + 1;
let impls = (min..33usize).map(|n| {
let in_nts: Vec<_> = (&nts[..n]).iter().enumerate().filter(|(i, _)| *i != a && *i != b).map(|(_, t)| t).collect();
let im_nts: Vec<_> = (&nts[..n]).iter().enumerate().map(|(i, t)| if i == a || i == b { &fixed_type } else { t }).collect();
let ai = &size_lits[a];
let bi = &size_lits[b];
quote! {
impl<T, #(#in_nts),*> #trait_name for (#(#im_nts),*) {
fn #fn_name(&mut self) {
core::mem::swap(&mut self.#ai, &mut self.#bi);
}
}
}
});
quote! {
#[doc = "Swaps two elements in the tuple"]
pub trait #trait_name {
#[doc = "Swaps two elements in the tuple"]
fn #fn_name(&mut self);
}
#(#impls)*
}
});

let tks = quote! {
#(#swap)*
};
tks
}
7 changes: 6 additions & 1 deletion tuples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ license = "MIT"
name = "tuples"
readme = "../README.md"
repository = "https://github.com/libsugar/tuplers"
version = "1.14.0"
version = "1.15.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

[features]
all = ["default", "tuple_swap_n"]
apply_tuple = []
capt = []
cloned = []
Expand Down Expand Up @@ -54,3 +55,7 @@ tuple_get = []
tuple_iter = []
tuple_map = []
tuple_meta = []
tuple_swap_n = []

[package.metadata.docs.rs]
all-features = true
Loading

0 comments on commit 11f13bf

Please sign in to comment.