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;