1use core::cmp;
4use core::fmt;
5
6use crate::flavor::Flavor;
7
8mod sealed {
9 pub trait Sealed {}
10
11 impl Sealed for u32 {}
12 impl Sealed for usize {}
13 impl Sealed for crate::empty::Empty {}
14}
15
16pub trait Index: Sized + Copy + cmp::Ord + cmp::Eq + self::sealed::Sealed {
24 #[doc(hidden)]
25 const EMPTY: Self;
26
27 #[doc(hidden)]
28 type Length: Length;
29
30 #[doc(hidden)]
31 fn is_empty(&self) -> bool;
32
33 #[doc(hidden)]
34 fn as_usize(self) -> usize;
35
36 #[doc(hidden)]
37 fn checked_add_len(self, other: Self::Length) -> Option<Self>;
38
39 #[doc(hidden)]
40 fn len_to(self, other: Self) -> Self::Length;
41
42 #[doc(hidden)]
43 fn from_usize(value: usize) -> Option<Self>;
44}
45
46#[doc(hidden)]
47pub trait Length: Copy + self::sealed::Sealed {
48 #[doc(hidden)]
49 const EMPTY: Self;
50
51 #[doc(hidden)]
52 fn is_empty(&self) -> bool;
53}
54
55impl Length for usize {
56 const EMPTY: Self = 0;
57
58 #[inline]
59 fn is_empty(&self) -> bool {
60 *self == 0
61 }
62}
63
64const _: () = assert!(core::mem::size_of::<u32>() <= core::mem::size_of::<usize>());
66
67impl Index for u32 {
68 const EMPTY: Self = 0;
69
70 type Length = usize;
71
72 #[inline]
73 fn is_empty(&self) -> bool {
74 *self == 0
75 }
76
77 #[inline]
78 fn as_usize(self) -> usize {
79 self as usize
80 }
81
82 #[inline]
83 fn checked_add_len(self, other: Self::Length) -> Option<Self> {
84 u32::checked_add(self, u32::try_from(other).ok()?)
85 }
86
87 #[inline]
88 fn len_to(self, other: Self) -> Self::Length {
89 other.saturating_sub(self) as usize
90 }
91
92 #[inline]
93 fn from_usize(value: usize) -> Option<Self> {
94 u32::try_from(value).ok()
95 }
96}
97
98impl Index for usize {
99 const EMPTY: Self = 0;
100
101 type Length = usize;
102
103 #[inline]
104 fn is_empty(&self) -> bool {
105 *self == 0
106 }
107
108 #[inline]
109 fn as_usize(self) -> usize {
110 self
111 }
112
113 #[inline]
114 fn checked_add_len(self, other: Self::Length) -> Option<Self> {
115 usize::checked_add(self, other)
116 }
117
118 #[inline]
119 fn len_to(self, other: Self) -> Self::Length {
120 other.saturating_sub(self)
121 }
122
123 #[inline]
124 fn from_usize(value: usize) -> Option<Self> {
125 Some(value)
126 }
127}
128
129#[doc(hidden)]
131pub struct TreeIndex<F>
132where
133 F: ?Sized + Flavor,
134{
135 pub(crate) index: F::Index,
136 pub(crate) id: F::Pointer,
137}
138
139impl<F> Clone for TreeIndex<F>
142where
143 F: ?Sized + Flavor,
144{
145 #[inline]
146 fn clone(&self) -> Self {
147 *self
148 }
149}
150
151impl<F> Copy for TreeIndex<F> where F: ?Sized + Flavor {}
152
153impl<F> fmt::Debug for TreeIndex<F>
154where
155 F: ?Sized + Flavor<Index: fmt::Debug>,
156{
157 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158 f.debug_struct("TreeIndex")
159 .field("index", &self.index)
160 .field("id", &self.id)
161 .finish()
162 }
163}