Skip to content

Add BitOps for BTreeSet. #19514

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

Merged
merged 1 commit into from
Dec 12, 2014
Merged

Conversation

jbranchaud
Copy link
Contributor

I am trying to add an implementation of bitor for BTreeSet. I think I am most of the way there, but I am going to need some guidance to take it all the way.

When I run make check, I get:

error: cannot move out of dereference of `&`-pointer
self.union(_rhs).map(|&i| i).collect::<BTreeSet<T>>()
                      ^~

I'd appreciate any nudges in the right direction. If I can figure this one out, I am sure I will be able to implement bitand, bitxor, and sub as well.

/cc @gankro


Update

I have added implementations for BitOr, BitAnd, BitXor, and Sub for BTreeSet.

@reem
Copy link
Contributor

reem commented Dec 4, 2014

If you want to stick to that implementation strategy, you'll need to bind T: Clone and use .map(|i| i.clone())

@reem
Copy link
Contributor

reem commented Dec 4, 2014

That said, I'm not convinced that this is actually desirable, and no other collections overload operators like this.

cc @aturon what are your thoughts on using |, -, and & for this kind of stuff.

@jbranchaud
Copy link
Contributor Author

I am working on this based on the Set Operations: Combinations section in the RFC. Also, this. /cc @reem

@aturon
Copy link
Member

aturon commented Dec 4, 2014

@reem The use of overloaded operations for sets was part of the collections reform RFC. Here are my thoughts.

Part of the motivation there is that there are actually several ways you may want to combine sets -- you can do so to get an iterator, you can do so to get a new set, or you can mutate a set in place. Each of these wants a specialized implementation for performance reasons, but it's a natural fit to make e.g. union yield an iterator while + and eventually += create new sets/mutate in place, respectively.

Further, this use of the operators is very consistent with their normal mathematical usage, so it seems like a fairly unobjectionable use of overloading to me.

@reem
Copy link
Contributor

reem commented Dec 4, 2014

Ok, that seems perfectly reasonable. I just hadn't read that part of the RFC so was confused.

@@ -340,6 +340,12 @@ impl<T: Ord> Default for BTreeSet<T> {
}
}

impl<T: Ord> BitOr<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
fn bitor(&self, _rhs: &BTreeSet<T>) -> BTreeSet<T> {
self.union(_rhs).map(|&i| i).collect::<BTreeSet<T>>()
Copy link
Contributor

Choose a reason for hiding this comment

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

self.union(_rhs).cloned().collect() (without the BTreeSet annotation on collect, it can be inferred) should do the job. But yes, you'll need to add the Clone constraint to T.

Copy link
Contributor

Choose a reason for hiding this comment

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

I would remove the _ from rhs. We usually use that to indicate the value isn't used, which is clearly not true here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@gankro I am not sure what you mean by adding the Clone constraint to T. Could you elaborate a bit more on that?

Copy link
Contributor

Choose a reason for hiding this comment

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

Clone is the trait that allows values to be deep-copied. You need to specify that T implements Clone, because after this operation there should be two logical copies of some values. For instance, if T was a Box, just moving out of a reference would create two Boxes that point to the same location in heap. Not safe. Clone will duplicate the actual location in memory, making two independent boxes.

You can add the bound as follows:

impl<T: Ord + Clone> BitOr<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That clears it up a lot. Thanks for explaining that! 😄

@Gankra
Copy link
Contributor

Gankra commented Dec 4, 2014

Basic implementation strategy is correct, just need my two notes to get it production-ready.

@jbranchaud jbranchaud changed the title Add initial attempt at implementing BitOr for BTreeSet. Add BitOps for BTreeSet. Dec 5, 2014
@csouth3
Copy link
Contributor

csouth3 commented Dec 5, 2014

Hi! Just a couple of things I see (though as a disclaimer I'm a complete newbie here myself, so take with a grain of salt!). First, it's probably good to remove the FIXME at the top of the file for implementing these traits as a part of this PR since you have taken care of implementing them. Also, it may be desirable to roll these commits into one to keep the Git commit history clean, though I'd wait for official word from Gankro on that one since it may not be necessary. Luckily enough, Git makes that easy to do though :)

Cheers, and good work!

@Gankra
Copy link
Contributor

Gankra commented Dec 5, 2014

Yeah everything csouth said is correct. Kill the FIXME, and eventually squash the commits when we're done. However you should include some tests for this functionality. In addition it just occurred to me that you should document the trait implementations and mark them with the collections reform "unstable" marker. See #19561 for dicussion.

@csouth3
Copy link
Contributor

csouth3 commented Dec 11, 2014

@jbranchaud What's the status of this? Looks like it should be ready for the buildbot with the addition of appropriate documentation/doctests and unit tests :)

@Gankra
Copy link
Contributor

Gankra commented Dec 11, 2014

Doc tests should be sufficient as far as unit tests go (the implementations aren't exactly difficult to verify). @jbranchaud You can steal the appropriate docs from TreeSet.

Add initial attempt at implementing BitOr for BTreeSet.

Update the implementation of the bitor operator for BTreeSets.

`make check` ran fine through this.

Add implementations for BitAnd, BitXor, and Sub as well.

Remove the FIXME comment and add unstable flags.

Add doctests for the bitop functions.
@jbranchaud
Copy link
Contributor Author

This should be ready to go. I'm glad to address any other comments though 😃

bors added a commit that referenced this pull request Dec 12, 2014
I am trying to add an implementation of `bitor` for `BTreeSet`. I think I am most of the way there, but I am going to need some guidance to take it all the way.

When I run `make check`, I get:

```
error: cannot move out of dereference of `&`-pointer
self.union(_rhs).map(|&i| i).collect::<BTreeSet<T>>()
                      ^~
```

I'd appreciate any nudges in the right direction. If I can figure this one out, I am sure I will be able to implement `bitand`, `bitxor`, and `sub` as well.

/cc @gankro 

---

**Update**

I have added implementations for `BitOr`, `BitAnd`, `BitXor`, and `Sub` for `BTreeSet`.
@bors bors closed this Dec 12, 2014
@bors bors merged commit cd008c4 into rust-lang:master Dec 12, 2014
emk added a commit to emk/rust that referenced this pull request Dec 12, 2014
This fixes rust-lang#19514 using a two-line patch suggested by @lifthrasiir.  The
code snippet:

```rust
extern crate serialize;

fn main() {
    let s = serialize::json::encode(&'c');
    println!("Encoded: {}, bytes: {}", s, s.as_bytes());
}
```

...serialized 'c' as `[34, 99, 0, 0, 0, 34]` when it should have used
`[34, 99, 34]`.  A test case is included.
lnicola pushed a commit to lnicola/rust that referenced this pull request Apr 28, 2025
…s-string

Fix color brackets in string context
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.

6 participants