Skip to content

Add Enumerable trait and deriving mode #14002

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

Closed
wants to merge 1 commit into from

Conversation

kemurphy
Copy link
Contributor

@kemurphy kemurphy commented May 7, 2014

Enumerable is for enumerating all possible values of an enum.
The deriving mode works for all C-like enums.

Use like so:

use std::enums::Enumerable;

#[deriving(Enumerable, Show)]
enum Shape {
    Circle,
    Square,
    Triangle,
}

fn main() {
    let shapes: Vec<Shape> = Enumerable::values();
    println!("There are {} possible Shapes: {}", shapes.len(), &shapes);
}

Enumerable is for enumerating all possible values of an enum.
The deriving mode works for all C-like enums.
@lilyball
Copy link
Contributor

lilyball commented May 7, 2014

Why does this return Vec<T>? That's a wholly unnecessary allocation. It should return &'static [T], so the derived function looks something like

impl Enumerable for Shape {
    fn values() -> &'static [Shape] {
        static VALUES: &'static [Shape] = [Circle, Square, Triangle];
        VALUES
    }
}

@kemurphy
Copy link
Contributor Author

kemurphy commented May 7, 2014

Slices aren't representable in derivings, it looks like. Take a look at libsyntax/ext/deriving/ty.rs:81 -- there's no variant for [T].

@huonw
Copy link
Member

huonw commented May 7, 2014

@kemurphy that's just because there's been no previous need for it; the existence/non-existence is just an implementation detail and can freely be changed.

@huonw
Copy link
Member

huonw commented May 7, 2014

Also, I somewhat think that Enumerable should return an iterator rather than an actual vector, so that, e.g., uint can implement it (this would allow range to be generalised properly).

@lilyball
Copy link
Contributor

lilyball commented May 7, 2014

@huonw Hmm. I considered Iterator before and decided &'static [T] was better, because you can create an iterator from the static but you can't create a static from the iterator. But I hadn't considered extending this to something like uint and using it with range(). That's an interesting idea, but there's 2 major flaws I see:

  1. How do you actually specify the range? If I do range(-1i, 10i), how do I get the Iterator to only cover that range (or at least, to start at -1)? I'd have to know the lower bound of the iterator and how many elements lie between that bound and my starting value.
  2. This is incompatible with ranging over floating-point numbers, which is currently supported.

Given that, I think &'static [T] is still the way to go.

@huonw
Copy link
Member

huonw commented May 7, 2014

you can't create a static from the iterator

Hm, that's true... could have an extension trait for StaticallyEnumerable or something.

How do you actually specify the range?

Eq or Ord?

This is incompatible with ranging over floating-point numbers, which is currently supported.

I don't think this is necessarily a good idea, e.g. range(1e16, 1e16 + 2.0) is actually an infinite series of 1e16, since 1e16 + 1.0 == 1e16. Using an integer counter that is converted to floating point later is safer in this respect.

@lilyball
Copy link
Contributor

lilyball commented May 7, 2014

How do you actually specify the range?

Eq or Ord?

What do you mean? The proposed Enumerable doesn't take any sort of range, and giving it a range defeats the original purpose of it (which is to enumerate all the values). For using it with range() you'd need to do something like values().skip_while(|x| *x < start).take_while(|x *x < end), and that's not very nice (making an iterator on int skip 2 billion values? Yeah maybe it will inline, but I'd rather not require inlining to have even slightly sane behavior).

As for floating-point, yes, ranging over floating-point numbers has some issues. But from a practical standpoint it's a lot nicer to support range(1.5f32, 12).

@brson
Copy link
Contributor

brson commented May 8, 2014

This is a major feature request for std. Can you write it up as an RFC to solicit feedback on the design?

@alexcrichton
Copy link
Member

Closing as this should have an RFC due to the scope of the change.

bors pushed a commit to rust-lang-ci/rust that referenced this pull request Jan 28, 2025
resurrection of rust-lang/rust-clippy#10984

fixes rust-lang/rust-clippy#10981

changelog: [`sliced_string_as_bytes`]: add new lint
`sliced_string_as_bytes`
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.

5 participants