iset/
ix.rs

1//! Wrapper around integer types, used as indices within `IntervalMap` and `IntervalSet`.
2
3use core::fmt::Display;
4
5/// Trait for index types: used in the inner representation of [IntervalMap](../struct.IntervalMap.html) and
6/// [IntervalSet](../set/struct.IntervalSet.html).
7///
8/// Implemented for `u8`, `u16`, `u32` and `u64`,
9/// `u32` is used by default ([DefaultIx](type.DefaultIx.html)).
10///
11/// `IntervalMap` or `IntervalSet` can store up to `Ix::MAX - 1` elements
12/// (for example `IntervalMap<_, _, u8>` can store up to 255 items).
13///
14/// Using smaller index types saves memory and slightly reduces running time.
15pub trait IndexType: Copy + Display + Sized + Eq + Ord {
16    /// Undefined index. There can be no indices higher than MAX.
17    const MAX: Self;
18
19    /// Converts index into `usize`.
20    fn get(self) -> usize;
21
22    /// Creates a new index. Returns error if the `elemen_num` is too big.
23    fn new(element_num: usize) -> Result<Self, &'static str>;
24
25    /// Returns `true` if the index is defined.
26    #[inline(always)]
27    fn defined(self) -> bool {
28        self != Self::MAX
29    }
30}
31
32macro_rules! index_error {
33    (u64) => {
34        "Failed to insert a new element into IntervalMap/Set: number of elements is too large for u64."
35    };
36    ($name:ident) => {
37        concat!(
38            "Failed to insert a new element into IntervalMap/Set: number of elements is too large for ",
39            stringify!($name),
40            ", try using u64.")
41    };
42}
43
44macro_rules! impl_index {
45    ($type:ident) => {
46        impl IndexType for $type {
47            const MAX: Self = core::$type::MAX;
48
49            #[inline(always)]
50            fn get(self) -> usize {
51                self as usize
52            }
53
54            #[inline]
55            fn new(element_num: usize) -> Result<Self, &'static str> {
56                let element_num = element_num as $type;
57                if element_num == core::$type::MAX {
58                    Err(index_error!($type))
59                } else {
60                    Ok(element_num as $type)
61                }
62            }
63        }
64    };
65}
66
67impl_index!(u8);
68impl_index!(u16);
69impl_index!(u32);
70impl_index!(u64);
71/// Default index type.
72pub type DefaultIx = u32;