-
Notifications
You must be signed in to change notification settings - Fork 11
BTreeMultiset + iter specializations #27
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
base: master
Are you sure you want to change the base?
Conversation
1ae0269 to
7f86640
Compare
Only nth could be optimized further, feel free to implement it :)
|
Doing a quick |
|
If we could that would indeed be better but as I mentioned above unfortunately we need GATs to be able to output the iterator when making the MultiSet generic, which we can't have at the moment. I've also experimented with a macro version (one liner for each sub-map) but it breaks the documentation and doesn't feel very clean. |
|
Another approach if you'd like to avoid using macros is a build script that does a simple search and replace which produces the second file which should be in gitignore. If the docs are run after the build script it should even produce duplicate docs. |
mashedcode
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job on the build.rs script.
Please remove the btree_multiset.rs file from 567aadb with a rebase.
I'd prefer it even more if you could split this PR into two separate ones. One for BTreeMultiset and one for the iterator stuff. But I guess it's fine like this.
I agree it would hurt in the general history but I'd rather keep the PR history easily accessible along the discussion, so I think we should just squash and merge it. |
|
Up |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for addressing the review comments and adding test cases for the iterator!!
| } | ||
| self.len -= 1; | ||
| Some(key) | ||
| } else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clippy: this else { if .. } block can be collapsed to else if.
| } | ||
| self.len -= 1; | ||
| Some(key) | ||
| } else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clippy: this else { if .. } block can be collapsed to else if.
| + BitXor<<IterItem as BitXor>::Output, Output = <IterItem as BitXor>::Output> | ||
| + Clone, | ||
| <IterItem as BitXor>::Output: | ||
| BitXor<Output = <IterItem as BitXor>::Output> + Eq + Debug + Clone, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems unnecessary to abstract this much and create so many single use functions. I wrote-up an example of a more specific implementation. (I took the freedom to use a macro for check_specialized.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comes from an implementation I had originally written for itertools, where I had several different iterators to test, so the functions were not single use. I just reused the same. ^^
Tbh, I hate writing tests, but I'm absolutely open to use whichever test implementation you prefer. :)
| Iter: Iterator<Item = IterItem> + Clone + 'a, | ||
| { | ||
| check_specialized(it, |mut i| { | ||
| let first = i.next().map(|f| f.clone() ^ (f.clone() ^ f)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why since x ^ x ^ x == x? How about Default instead? Or even better yet 0i32?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That minimizes the amount of requirements on the generic function. Only output is constrained, so I need to hit a few XORs here to satisfy the type system.
Now again, if you'd rather use another implementation that doesn't try to minimize the constraints when writing the final test (and I agree this particular constraint probably wouldn't change anything), I'm absolutely open to it :)
| } | ||
|
|
||
| quickcheck! { | ||
| fn hms_test_qc(test_vec: Vec<i32>) -> () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "hms" stand for? hash multi set test? Or does it just test some iterator functionality?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, hms stands for "hash multi set". qc is for quickcheck, a crate that allows to test on randomly generated inputs.
|
I need use the BTreeMultiset, I hope @jmitchell can merge this PR. |
Resolves #25
Resolves #26
What it does:
BTreeMultiSetimplementationIterfor performanceDue to GATs not being available in rust yet the
MultiSetcould not be generic on both types of map (could not create theIterassociated type because it is generic on a lifetime). In order to avoid code duplication, the code for theBTreeMultisetis generated at build time through abuild.rsscript, using simple replacements from thehash_multisetfile.The iterator I was able to factor however, so the specializations are only here once.
This is non semver-compatible due to the
Itertype being more generic.