Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[framework] vector macros wave 3 #18796

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Conversation

damirka
Copy link
Contributor

@damirka damirka commented Jul 25, 2024

Description

Adds the 3rd wave of macros for vector.
Also fixes a bug introduced in find_index which consumed the vector.

Test plan

How did you test the new or updated feature?


Release notes

Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required.

For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates.

  • Protocol:
  • Nodes (Validators and Full nodes):
  • Indexer:
  • JSON-RPC:
  • GraphQL:
  • CLI:
  • Rust SDK:
  • REST API:

@damirka damirka self-assigned this Jul 25, 2024
@damirka damirka requested a review from ronny-mysten as a code owner July 25, 2024 13:02
Copy link

vercel bot commented Jul 25, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
sui-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 26, 2024 2:16pm
3 Skipped Deployments
Name Status Preview Comments Updated (UTC)
multisig-toolkit ⬜️ Ignored (Inspect) Visit Preview Jul 26, 2024 2:16pm
sui-kiosk ⬜️ Ignored (Inspect) Visit Preview Jul 26, 2024 2:16pm
sui-typescript-docs ⬜️ Ignored (Inspect) Visit Preview Jul 26, 2024 2:16pm

@damirka
Copy link
Contributor Author

damirka commented Jul 26, 2024

@tnowacki @tzakian, I've updated the PR to follow the conversation

@@ -158,6 +158,40 @@ module std::vector {
v.pop_back()
}

/// Take all elements of the vector `v` except the first `n` elements. Aborts if `n` is greater
/// than the length of `v`. Modifies the original vector.
public fun skip_mut<T>(v: &mut vector<T>, n: u64): vector<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first, I thought maybe this was backwards and this should be take_mut, but I think this makes sense: you want to return the desired elements. In short, you want the return values of skip|take to match with (skip|take)_mut

/// Take all elements of the vector `v` except the first `n` elements. Aborts if `n` is greater
/// than the length of `v`. Modifies the original vector.
public fun skip_mut<T>(v: &mut vector<T>, n: u64): vector<T> {
assert!(n <= v.length());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is the correct choice, but just wanted to double check.
If folks don't want it to assert they should do let len = v.length(); v.skip(n.min(len)), which hopefully makes this more explicit for the person auditing/reading the code

/// Destroys the original vector after taking the elements.
public macro fun take_while<$T: drop>($v: vector<$T>, $p: |&$T| -> bool): vector<$T> {
let mut v = $v;
take_mut_while!(&mut v, $p)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
take_mut_while!(&mut v, $p)
v.take_mut_while!($p)

/// and drop the vector.
public macro fun skip_while<$T: drop>($v: vector<$T>, $p: |&$T| -> bool): vector<$T> {
let mut v = $v;
skip_mut_while!(&mut v, $p)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
skip_mut_while!(&mut v, $p)
v.skip_mut_while!($p)

public macro fun skip_mut_while<$T>($v: &mut vector<$T>, $p: |&$T| -> bool): vector<$T> {
let v = $v;
// find first element that does not satisfy the predicate, then skip from there
v.find_index!(|e| !$p(e)).map!(|c| v.skip_mut(c)).destroy_or!(vector[])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, while slick, it might be nice to avoid the 2 separate iterations over v. Especially since this is library code, small optimizations can be really meaningful

Comment on lines +869 to +871
assert!(vector[1, 1, 1, 2, 2, 2, 3, 3, 3].skip_while!(|e| *e == 1) == vector[2, 2, 2, 3, 3, 3]);
assert!(vector[1, 1, 1, 2, 2, 2, 3, 3, 3].skip_while!(|e| *e == 2) == vector[1, 1, 1, 2, 2, 2, 3, 3, 3]);
assert!(vector[1, 1, 1, 2, 2, 2, 3, 3, 3].skip_while!(|e| *e == 3) == vector[1, 1, 1, 2, 2, 2, 3, 3, 3]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert!(vector[1, 1, 1, 2, 2, 2, 3, 3, 3].skip_while!(|e| *e == 1) == vector[2, 2, 2, 3, 3, 3]);
assert!(vector[1, 1, 1, 2, 2, 2, 3, 3, 3].skip_while!(|e| *e == 2) == vector[1, 1, 1, 2, 2, 2, 3, 3, 3]);
assert!(vector[1, 1, 1, 2, 2, 2, 3, 3, 3].skip_while!(|e| *e == 3) == vector[1, 1, 1, 2, 2, 2, 3, 3, 3]);
let v = vector[1, 1, 1, 2, 2, 2, 3, 3, 3];
assert_eq!(v.skip_while!(|_| false), v);
assert_eq!(v.skip_while!(|e| *e == 1), vector[2, 2, 2, 3, 3, 3]);
assert_eq!(v.skip_while!(|e| *e <= 2), vector[3, 3, 3]);
assert_eq!(v.skip_while!(|_| true), vector[]);

Comment on lines +861 to +864
let mut v = vector[1, 1, 1, 2, 2, 2, 3, 3, 3];
assert!(v.skip_mut_while!(|e| *e == 1) == vector[2, 2, 2, 3, 3, 3]);
assert!(v.skip_mut_while!(|e| *e == 2) == vector[1, 1, 1]);
assert!(v.skip_mut_while!(|e| *e == 3) == vector[]); // v = vector[]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let mut v = vector[1, 1, 1, 2, 2, 2, 3, 3, 3];
assert!(v.skip_mut_while!(|e| *e == 1) == vector[2, 2, 2, 3, 3, 3]);
assert!(v.skip_mut_while!(|e| *e == 2) == vector[1, 1, 1]);
assert!(v.skip_mut_while!(|e| *e == 3) == vector[]); // v = vector[]
let mut v = vector[1, 1, 1, 2, 2, 2, 3, 3, 3];
assert_eq!(v.skip_mut_while!(|_| false), vector[1, 1, 1, 2, 2, 2, 3, 3, 3]);
assert_eq!(v, vector[]);
let mut v = vector[1, 1, 1, 2, 2, 2, 3, 3, 3];
assert_eq!(v.skip_mut_while!(|e| *e == 1), vector[2, 2, 2, 3, 3, 3]);
assert_eq!(v, vector[1, 1, 1]);
let mut v = vector[1, 1, 1, 2, 2, 2, 3, 3, 3];
assert_eq!(v.skip_mut_while!(|e| *e <= 2), vector[3, 3, 3]);
assert_eq!(v, vector[1, 1, 1, 2, 2, 2]);
let mut v = vector[1, 1, 1, 2, 2, 2, 3, 3, 3];
assert_eq!(v.skip_mut_while!(|_| true), vector[]);
assert_eq!(v, vector[1, 1, 1, 2, 2, 2, 3, 3, 3]);

Comment on lines +854 to +856
assert!(vector[1, 1, 1, 2, 2, 2, 3, 3, 3].take_while!(|e| *e == 1) == vector[1, 1, 1]);
assert!(vector[1, 1, 1, 2, 2, 2, 3, 3, 3].take_while!(|e| *e == 2) == vector[]);
assert!(vector[1, 1, 1, 2, 2, 2, 3, 3, 3].take_while!(|e| *e == 3) == vector[]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert!(vector[1, 1, 1, 2, 2, 2, 3, 3, 3].take_while!(|e| *e == 1) == vector[1, 1, 1]);
assert!(vector[1, 1, 1, 2, 2, 2, 3, 3, 3].take_while!(|e| *e == 2) == vector[]);
assert!(vector[1, 1, 1, 2, 2, 2, 3, 3, 3].take_while!(|e| *e == 3) == vector[]);
let v = vector[1, 1, 1, 2, 2, 2, 3, 3, 3];
assert_eq!(v.take_while!(|_| false), vector[]);
assert_eq!(v.take_while!(|e| *e == 1), vector[1, 1, 1]);
assert_eq!(v.take_while!(|e| *e <= 2), vector[1, 1, 1, 2, 2, 2]);
assert_eq!(v.take_while!(|_| true), v);

Comment on lines +843 to +849
let mut v = vector[1, 1, 1, 2, 2, 2, 3, 3, 3];
assert!(v.take_mut_while!(|e| *e == 1) == vector[1, 1, 1]);
assert!(v == vector[2, 2, 2, 3, 3, 3]);
assert!(v.take_mut_while!(|e| *e == 2) == vector[2, 2, 2]);
assert!(v == vector[3, 3, 3]);
assert!(v.take_mut_while!(|e| *e == 3) == vector[3, 3, 3]);
assert!(v.length() == 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let mut v = vector[1, 1, 1, 2, 2, 2, 3, 3, 3];
assert!(v.take_mut_while!(|e| *e == 1) == vector[1, 1, 1]);
assert!(v == vector[2, 2, 2, 3, 3, 3]);
assert!(v.take_mut_while!(|e| *e == 2) == vector[2, 2, 2]);
assert!(v == vector[3, 3, 3]);
assert!(v.take_mut_while!(|e| *e == 3) == vector[3, 3, 3]);
assert!(v.length() == 0);
let mut v = vector[1, 1, 1, 2, 2, 2, 3, 3, 3];
assert_eq!(v.take_mut_while!(|_| false), vector[]);
assert_eq!(v, vector[1, 1, 1, 2, 2, 2, 3, 3, 3]);
let mut v = vector[1, 1, 1, 2, 2, 2, 3, 3, 3];
assert_eq!(v.take_mut_while!(|e| *e == 1), vector[1, 1, 1]);
assert_eq!(v, vector[2, 2, 2, 3, 3, 3]);
let mut v = vector[1, 1, 1, 2, 2, 2, 3, 3, 3];
assert_eq!(v.take_mut_while!(|e| *e <= 2), vector[1, 1, 1, 2, 2, 2]);
assert_eq!(v, vector[3, 3, 3]);
let mut v = vector[1, 1, 1, 2, 2, 2, 3, 3, 3];
assert_eq!(v.take_mut_while!(|_| true), vector[1, 1, 1, 2, 2, 2, 3, 3, 3]);
assert_eq!(v, vector[]);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants