Skip to content
Snippets Groups Projects
Commit 5b91d682 authored by homunkulus's avatar homunkulus
Browse files

Auto merge of #11 - japaric:release, r=japaric

v0.2.0

None
parents cd538447 9d821076
No related branches found
No related tags found
No related merge requests found
...@@ -7,8 +7,27 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ...@@ -7,8 +7,27 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased] ## [Unreleased]
## [v0.2.0] - 2017-11-22
### Added
- A single producer single consumer mode to `RingBuffer`.
- A `truncate` method to `Vec`.
### Changed
- [breaking-change] Both `Vec::new` and `RingBuffer::new` no longer require an initial value. The
signature of `new` is now `const fn() -> Self`.
- [breaking-change] The error type of all operations that may fail has changed from `()` to
`BufferFullError`.
- Both `RingBuffer` and `Vec` now support arrays of *any* size for their backup storage.
## [v0.1.0] - 2017-04-27 ## [v0.1.0] - 2017-04-27
- Initial release - Initial release
[Unreleased]: https://github.com/japaric/heapless/compare/v0.1.0...HEAD [Unreleased]: https://github.com/japaric/heapless/compare/v0.2.0...HEAD
[v0.2.0]: https://github.com/japaric/heapless/compare/v0.1.0...v0.2.0
...@@ -6,9 +6,8 @@ use core::{intrinsics, ptr}; ...@@ -6,9 +6,8 @@ use core::{intrinsics, ptr};
use untagged_option::UntaggedOption; use untagged_option::UntaggedOption;
use BufferFullError;
pub use self::spsc::{Consumer, Producer}; pub use self::spsc::{Consumer, Producer};
use BufferFullError;
mod spsc; mod spsc;
......
use core::ptr::{self, Shared};
use core::marker::{PhantomData, Unsize}; use core::marker::{PhantomData, Unsize};
use core::ptr::{self, Shared};
use BufferFullError; use BufferFullError;
use ring_buffer::RingBuffer; use ring_buffer::RingBuffer;
...@@ -89,6 +89,10 @@ where ...@@ -89,6 +89,10 @@ where
let buffer: &mut [T] = unsafe { rb.buffer.as_mut() }; let buffer: &mut [T] = unsafe { rb.buffer.as_mut() };
let tail = rb.tail.load_relaxed(); let tail = rb.tail.load_relaxed();
// NOTE we could replace this `load_acquire` with a `load_relaxed` and this method would be
// sound on most architectures but that change would result in UB according to the C++
// memory model, which is what Rust currently uses, so we err on the side of caution and
// stick to `load_acquire`. Check issue google#sanitizers#882 for more details.
let head = rb.head.load_acquire(); let head = rb.head.load_acquire();
let next_tail = (tail + 1) % n; let next_tail = (tail + 1) % n;
if next_tail != head { if next_tail != head {
......
...@@ -37,6 +37,11 @@ where ...@@ -37,6 +37,11 @@ where
buffer.len() buffer.len()
} }
/// Clears the vector, removing all values.
pub fn clear(&mut self) {
self.truncate(0);
}
/// Removes the last element from a vector and return it, or `None` if it's empty /// Removes the last element from a vector and return it, or `None` if it's empty
pub fn pop(&mut self) -> Option<T> { pub fn pop(&mut self) -> Option<T> {
let buffer: &[T] = unsafe { self.buffer.as_ref() }; let buffer: &[T] = unsafe { self.buffer.as_ref() };
...@@ -67,6 +72,20 @@ where ...@@ -67,6 +72,20 @@ where
Err(BufferFullError) Err(BufferFullError)
} }
} }
/// Shortens the vector, keeping the first `len` elements and dropping the rest.
pub fn truncate(&mut self, len: usize) {
unsafe {
// drop any extra elements
while len < self.len {
// decrement len before the drop_in_place(), so a panic on Drop
// doesn't re-drop the just-failed value.
self.len -= 1;
let len = self.len;
ptr::drop_in_place(self.get_unchecked_mut(len));
}
}
}
} }
impl<T, A> Drop for Vec<T, A> impl<T, A> Drop for Vec<T, A>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment