Skip to content
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
.#*
Cargo.lock
target/
.idea
Copy link
Member

Choose a reason for hiding this comment

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

Remove this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed aca4aa9

1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Added `Deque::{swap, swap_unchecked, swap_remove_front, swap_remove_back}`.
- Make `String::from_utf8_unchecked` const.
- Implemented `PartialEq` and `Eq` for `Deque`.
- Implemented `TryFrom` for `Deque` from slice.

### Changed

Expand Down
65 changes: 64 additions & 1 deletion src/deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use core::cmp::Ordering;
use core::fmt;
use core::iter::FusedIterator;
use core::marker::PhantomData;
use core::mem::MaybeUninit;
use core::mem::{ManuallyDrop, MaybeUninit};
use core::{ptr, slice};

use crate::vec::{OwnedVecStorage, VecStorage, VecStorageInner, ViewVecStorage};
Expand Down Expand Up @@ -998,6 +998,50 @@ impl<T: PartialEq, const N: usize> PartialEq for Deque<T, N> {

impl<T: Eq, const N: usize> Eq for Deque<T, N> {}

impl<T, const NS: usize, const ND: usize> TryFrom<[T; NS]> for Deque<T, ND> {
/// Converts a `[T; NS]` into a `Deque<T, ND>`.
///
/// ```
/// use heapless::Deque;
///
/// let deq1 = Deque::<u8, 4>::try_from([1, 2, 3, 4]).unwrap();
Copy link
Member

Choose a reason for hiding this comment

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

Might make more sense to use different NS/ND in the example.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this what you mean? 2dfeabe

/// let mut deq2 = Deque::<u8, 4>::new();
/// deq2.push_back(1).unwrap();
/// deq2.push_back(2).unwrap();
/// deq2.push_back(3).unwrap();
/// deq2.push_back(4).unwrap();
///
/// assert_eq!(deq1, deq2);
/// ```
type Error = ();
Copy link
Member

Choose a reason for hiding this comment

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

Should use CapacityError.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed here aca4aa9


fn try_from(value: [T; NS]) -> Result<Self, Self::Error> {
if NS > ND {
return Err(());
}

let mut deq = Self::default();
let value = ManuallyDrop::new(value);

if size_of::<T>() != 0 {
// SAFETY: We already ensured that value fits in deq.
unsafe {
ptr::copy_nonoverlapping(
value.as_ptr(),
deq.buffer.buffer.as_mut_ptr() as *mut T,
NS,
);
}
}

deq.front = 0;
deq.back = NS;
deq.full = NS == ND;

Ok(deq)
}
}

#[cfg(test)]
mod tests {
use static_assertions::assert_not_impl_any;
Expand Down Expand Up @@ -1544,4 +1588,23 @@ mod tests {

assert_eq!(a, b);
}

#[test]
fn try_from_array() {
// Array is too big error.
assert!(Deque::<u8, 3>::try_from([1, 2, 3, 4]).is_err());

// Array is at limit.
assert!(Deque::<u8, 3>::try_from([1, 2, 3]).unwrap().is_full());

// Array is under limit.
let deq1 = Deque::<u8, 8>::try_from([1, 2, 3, 4]).unwrap();
let mut deq2 = Deque::<u8, 8>::new();
deq2.push_back(1).unwrap();
deq2.push_back(2).unwrap();
deq2.push_back(3).unwrap();
deq2.push_back(4).unwrap();

assert_eq!(deq1, deq2);
}
}