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

Add ArrayVec::resize and friends #82

Closed
wants to merge 3 commits into from
Closed

Conversation

tbu-
Copy link
Collaborator

@tbu- tbu- commented Nov 1, 2017

ArrayVec::resize_default
ArrayVec::resize
ArrayVec::try_resize_default
ArrayVec::try_resize

Fixes #72.

`ArrayVec::resize_default`
`ArrayVec::resize`
`ArrayVec::try_resize_default`
`ArrayVec::try_resize`

Fixes bluss#72.
@bluss
Copy link
Owner

bluss commented Nov 1, 2017

This duplicates the set Len on drop-ish struct. It can be refactored, can't it?

@bluss
Copy link
Owner

bluss commented Nov 1, 2017

Thanks a lot for working on this. To clarify from before, it looks like this duplicates instead of factors out the logic inside extend and its ScopeExitGuard (which has the same function as SetLenOnDrop). It's best to not duplicate it.

What's the reason for the extra methods and types? Maybe the existing .extend() can handle it well?

This removes the use of `ScopeExitGuard`.
@tbu-
Copy link
Collaborator Author

tbu- commented Nov 1, 2017

@bluss I basically copied it from stdlib's implementation. extend is a little worse here, because it has to clone the elements one time too often.

Copy link
Owner

@bluss bluss left a comment

Choose a reason for hiding this comment

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

Thanks it looks good.

I would like to challenge you to combine the two extend methods in some way. If not using the old method for the new, maybe the other way around, old extend uses a modified form of extend_with? They are similar.

src/lib.rs Outdated
@@ -597,6 +597,190 @@ impl<A: Array> ArrayVec<A> {
}
}

impl<A: Array> ArrayVec<A>
where A::Item: Clone,
{
Copy link
Owner

Choose a reason for hiding this comment

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

Style wise I'd prefer a single impl block. The where clause can go on each method fine. Split impl blocks feels archaic.

src/lib.rs Outdated
/// Resizes the `ArrayVec` in-place so that `len` is equal to `new_len`.
///
/// Does the same thing as `try_resize`, but panics on error instead of
/// returning it as a `Result`.
Copy link
Owner

Choose a reason for hiding this comment

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

Documentation for panic should be consistent and visible. Other methods use this style, panic the first word of the line and bold:

/// ***Panics*** if the `index` is out of bounds.

src/lib.rs Outdated
self.try_resize(new_len, value).unwrap()
}

/// Resizes the `ArrayVec` in-place so that `len` is equal to `new_len`.
Copy link
Owner

Choose a reason for hiding this comment

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

Rust's own formulation in their docs "so that len is equal" is awkward. Sounds better to just say "so that its length becomes new_len" or similar.

src/lib.rs Outdated

/// Resizes the `ArrayVec` in-place so that `len` is equal to `new_len`.
///
/// If `new_len` is greater than `len`, the `ArrayVec` is extended by the
Copy link
Owner

Choose a reason for hiding this comment

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

I think we should say length instead of len.

src/lib.rs Outdated
fn extend_with<E: ExtendWith<A::Item>>(&mut self, n: usize, value: E)
-> Result<(), CapacityError>
{
if self.len() + n > self.capacity() {
Copy link
Owner

Choose a reason for hiding this comment

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

This addition feels wrong, as if it could wrap around. But it's a private function and all callers are without problem.

Also fix a couple of doc strings.
@tbu-
Copy link
Collaborator Author

tbu- commented Nov 2, 2017

Done I think.

@bluss
Copy link
Owner

bluss commented Nov 3, 2017

Cool. Please have some patience. I'll make a new suggestion :-)

Copy link
Owner

@bluss bluss left a comment

Choose a reason for hiding this comment

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

extend_with doesn't need to be removed -- it can simply be a method that takes the needed_capacity number as the first parameter and the iterator as the second. Do error handling and then pass on the iterator to the existing extend method. Do you think that works?

///
/// Doesn't extend the vector and returns an error if the number of added
/// elements exceed the capacity of the underlying array.
fn extend_with<E>(&mut self, values: E) -> Result<(), CapacityError>
Copy link
Owner

Choose a reason for hiding this comment

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

This should just use the existing extend I think.

Some(if self.0 > 0 {
self.1.as_ref().unwrap().clone()
} else {
self.1.take().unwrap()
Copy link
Owner

Choose a reason for hiding this comment

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

These .unwrap are avoidable, aren't they? The Some/None-ness can be used to guard the end of the iteration.

Copy link
Owner

Choose a reason for hiding this comment

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

One could spy at itertools' repeat_n, but I'm not sure if that spoils the fun.

Copy link
Owner

Choose a reason for hiding this comment

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

or indeed if it spoils the performance.

}
}

struct ExtendDefault<T: Default>(usize, PhantomData<T>);
Copy link
Owner

Choose a reason for hiding this comment

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

The ExtendDefault iterator is not needed, it can be passed as a regular iterator inline, maybe something like (0..n).map(|_| X::default())

}
}

struct ExtendIter<I: Iterator>(I);
Copy link
Owner

Choose a reason for hiding this comment

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

This trivial wrapper is not needed.

@bluss
Copy link
Owner

bluss commented Dec 31, 2017

I'll pick this up at some point

@bluss bluss closed this Dec 31, 2017
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.

None yet

2 participants