[go: up one dir, main page]

sid/
lib.rs

1#![no_std]
2
3extern crate alloc;
4extern crate num_traits;
5
6use num_traits::{One, Zero};
7use core::cmp;
8use core::ops::{Add, Sub};
9
10mod id;
11mod id_list;
12mod id_range;
13mod id_vector;
14
15pub use id::Id;
16pub use id_list::{IdFreeList, NoneAsNullId, NullId};
17pub use id_range::{IdRange, ReverseIdRange};
18pub use id_vector::{IdSlice, IdVec, MutIdSlice};
19
20pub trait FromUsize {
21    fn from_usize(idx: usize) -> Self;
22}
23
24pub trait ToUsize {
25    fn to_usize(&self) -> usize;
26}
27
28pub trait IntegerHandle:
29    Copy
30    + Clone
31    + Add<Output = Self>
32    + Sub<Output = Self>
33    + cmp::Ord
34    + PartialEq
35    + PartialOrd
36    + FromUsize
37    + ToUsize
38    + Zero
39    + One
40{
41}
42
43pub trait Identifier: Copy + FromUsize + ToUsize + PartialEq {
44    type Handle: IntegerHandle;
45    type Tag;
46}
47
48impl Identifier for u8 {
49    type Handle = u8;
50    type Tag = ();
51}
52impl Identifier for u16 {
53    type Handle = u16;
54    type Tag = ();
55}
56impl Identifier for u32 {
57    type Handle = u32;
58    type Tag = ();
59}
60impl Identifier for u64 {
61    type Handle = u64;
62    type Tag = ();
63}
64impl Identifier for i8 {
65    type Handle = i8;
66    type Tag = ();
67}
68impl Identifier for i16 {
69    type Handle = i16;
70    type Tag = ();
71}
72impl Identifier for i32 {
73    type Handle = i32;
74    type Tag = ();
75}
76impl Identifier for i64 {
77    type Handle = i64;
78    type Tag = ();
79}
80
81impl ToUsize for u8 {
82    #[inline]
83    fn to_usize(&self) -> usize {
84        *self as usize
85    }
86}
87impl ToUsize for u16 {
88    #[inline]
89    fn to_usize(&self) -> usize {
90        *self as usize
91    }
92}
93impl ToUsize for u32 {
94    #[inline]
95    fn to_usize(&self) -> usize {
96        *self as usize
97    }
98}
99impl ToUsize for u64 {
100    #[inline]
101    fn to_usize(&self) -> usize {
102        *self as usize
103    }
104}
105impl ToUsize for usize {
106    #[inline]
107    fn to_usize(&self) -> usize {
108        *self
109    }
110}
111impl ToUsize for i8 {
112    #[inline]
113    fn to_usize(&self) -> usize {
114        debug_assert!(*self >= 0);
115        *self as usize
116    }
117}
118impl ToUsize for i16 {
119    #[inline]
120    fn to_usize(&self) -> usize {
121        debug_assert!(*self >= 0);
122        *self as usize
123    }
124}
125impl ToUsize for i32 {
126    #[inline]
127    fn to_usize(&self) -> usize {
128        debug_assert!(*self >= 0);
129        *self as usize
130    }
131}
132impl ToUsize for i64 {
133    #[inline]
134    fn to_usize(&self) -> usize {
135        debug_assert!(*self >= 0);
136        *self as usize
137    }
138}
139impl ToUsize for isize {
140    #[inline]
141    fn to_usize(&self) -> usize {
142        debug_assert!(*self >= 0);
143        *self as usize
144    }
145}
146
147impl FromUsize for u8 {
148    #[inline]
149    fn from_usize(idx: usize) -> u8 {
150        idx as u8
151    }
152}
153impl FromUsize for u16 {
154    #[inline]
155    fn from_usize(idx: usize) -> u16 {
156        idx as u16
157    }
158}
159impl FromUsize for u32 {
160    #[inline]
161    fn from_usize(idx: usize) -> u32 {
162        idx as u32
163    }
164}
165impl FromUsize for u64 {
166    #[inline]
167    fn from_usize(idx: usize) -> u64 {
168        idx as u64
169    }
170}
171impl FromUsize for usize {
172    #[inline]
173    fn from_usize(idx: usize) -> usize {
174        idx
175    }
176}
177impl FromUsize for i8 {
178    #[inline]
179    fn from_usize(idx: usize) -> i8 {
180        idx as i8
181    }
182}
183impl FromUsize for i16 {
184    #[inline]
185    fn from_usize(idx: usize) -> i16 {
186        idx as i16
187    }
188}
189impl FromUsize for i32 {
190    #[inline]
191    fn from_usize(idx: usize) -> i32 {
192        idx as i32
193    }
194}
195impl FromUsize for i64 {
196    #[inline]
197    fn from_usize(idx: usize) -> i64 {
198        idx as i64
199    }
200}
201impl FromUsize for isize {
202    #[inline]
203    fn from_usize(idx: usize) -> isize {
204        idx as isize
205    }
206}
207
208impl IntegerHandle for u8 {}
209impl IntegerHandle for u16 {}
210impl IntegerHandle for u32 {}
211impl IntegerHandle for u64 {}
212impl IntegerHandle for usize {}
213impl IntegerHandle for i8 {}
214impl IntegerHandle for i16 {}
215impl IntegerHandle for i32 {}
216impl IntegerHandle for i64 {}
217impl IntegerHandle for isize {}
218
219/*
220// TODO: remove it or implement traits manually
221
222pub trait Generation {
223    fn get_gen(&self) -> u32;
224}
225
226#[derive(Copy, Clone)]
227pub struct GenId<T, H: Copy, G> {
228    pub id: Id<T, H>,
229    pub gen: G,
230}
231
232impl<T, H: Copy + core::fmt::Display, G: core::fmt::Display> core::fmt::Debug for GenId<T, H, G> {
233    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
234        write!(f, "GenId#{}({})", self.id.handle, self.gen)
235    }
236}
237
238impl<T, H: IntegerHandle, G: PartialEq> PartialEq for GenId<T, H, G> {
239    fn eq(&self, other: &GenId<T, H, G>) -> bool {
240        self.id == other.id && self.gen == other.gen
241    }
242}
243
244impl<T, H: IntegerHandle, G> ToUsize for GenId<T, H, G> {
245    fn to_usize(&self) -> usize {
246        self.id.to_usize()
247    }
248}
249
250impl Generation for u8 {
251    fn get_gen(&self) -> u32 {
252        *self as u32
253    }
254}
255impl Generation for u16 {
256    fn get_gen(&self) -> u32 {
257        *self as u32
258    }
259}
260impl Generation for u32 {
261    fn get_gen(&self) -> u32 {
262        *self as u32
263    }
264}
265impl Generation for u64 {
266    fn get_gen(&self) -> u32 {
267        *self as u32
268    }
269}
270
271impl<T, H: Copy, G: Generation> Generation for GenId<T, H, G> {
272    fn get_gen(&self) -> u32 {
273        self.gen.get_gen()
274    }
275}
276*/
277
278#[test]
279fn test_copy_id() {
280    #[derive(Debug)]
281    struct Foo;
282
283    // check that Id is Copy
284    let a: Id<Foo, u32> = Id::new(0);
285    let b = a;
286    let c = a;
287    assert_eq!(b, c);
288
289    // check that IdRange is Copy
290    let r1: IdRange<Foo, u32> = IdRange::new(0..10);
291
292    let r2 = r1;
293    let r3 = r1;
294    assert_eq!(r2, r3);
295}
296
297#[test]
298fn test_reverese_id_range() {
299    fn range(first: u16, count: u16) -> IdRange<u16, u16> {
300        IdRange::new(first..(first + count))
301    }
302    let mut iter = ReverseIdRange::new(range(1, 5));
303    assert_eq!(iter.next(), Some(Id::new(5)));
304    assert_eq!(iter.next(), Some(Id::new(4)));
305    assert_eq!(iter.next(), Some(Id::new(3)));
306    assert_eq!(iter.next(), Some(Id::new(2)));
307    assert_eq!(iter.next(), Some(Id::new(1)));
308    assert_eq!(iter.next(), None);
309    assert_eq!(iter.next(), None);
310}