[−][src]Trait counting_sort::TryIntoIndex
The interface for converting values into an index.
Index is always usize
. Unfortunatelly
TryInto
for
usize
is not sufficient since signed
integers overflow when calculating max_value - min_value
. Therefore this trait was added to
implement an non-overflowing conversion to usize
.
You can implement this trait yourself as long as there is a natural conversion from your type to
usize
. However it must hold for your type that if
t_1 <= t_2
then YourType::try_into_index(t_1, min_value)? <= YourType::try_into_index(t_2, min_value)?
.
Also consider that the size Vec
that holds the
frequency of all elements in the collection is calculated like this
let length = YourType::try_into_index(max_value,min_value)? + 1;
It is not highly recommended to do this if your type's order is not simply dependent on one integer value of your struct.
Example
use core::cmp::{Ord, Ordering}; use counting_sort::TryIntoIndex; #[derive(Copy, Clone)] struct Person { name: &'static str, id: usize } impl Ord for Person { fn cmp(&self, other: &Self) -> Ordering { self.id.cmp(&other.id) } } impl PartialOrd for Person { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) } } impl PartialEq for Person { fn eq(&self, other: &Self) -> bool { self.id == other.id } } impl Eq for Person {} impl TryIntoIndex for Person { type Error = &'static str; fn try_into_index(value: &Self, min_value: &Self) -> Result<usize, Self::Error> { Ok(value.id - min_value.id) } } let john = Person { name: "John", id: 1234 }; let min_value = Person { name: "Jim", id: 234 }; let index_result = Person::try_into_index(&john, &min_value); assert!(index_result.is_ok()); assert_eq!(1000, index_result.unwrap_or(0));
Associated Types
type Error
The type returned whenever the conversion into an index failed.
Required methods
fn try_into_index(value: &Self, min_value: &Self) -> Result<usize, Self::Error>
Tries to convert the value into an index.
The min_value
parameter is for calculating the offset between the actual value
and the minimum value. This concept is used in order to only allocate a
Vec
that only covers the
distance between the maximum value and the minimum value of the collection.