1#![allow(clippy::precedence)]
10
11use crate::cast::{Cast, Conv};
12use hash_hasher::{HashBuildHasher, HashedMap};
13use std::cell::RefCell;
14use std::cmp::Ordering;
15use std::collections::hash_map::Entry;
16use std::hash::{DefaultHasher, Hash, Hasher};
17use std::iter::once;
18use std::marker::PhantomData;
19use std::mem::size_of;
20use std::num::NonZeroU64;
21use std::rc::Rc;
22use std::{fmt, slice};
23
24thread_local! {
25 static DB: RefCell<HashedMap<u64, *mut usize>> = const { RefCell::new(HashedMap::with_hasher(HashBuildHasher::new())) };
27}
28
29const INVALID: u64 = !0;
31
32const USE_MASK: u64 = 0x3;
34const USE_BITS: u64 = 0x01;
36const USE_PTR: u64 = 0x02;
38
39const MASK_LEN: u64 = 0xF0;
40const SHIFT_LEN: u8 = 4;
41const BLOCKS: u8 = 14;
42const MASK_BITS: u64 = 0xFFFF_FFFF_FFFF_FF00;
43
44const MASK_PTR: u64 = 0xFFFF_FFFF_FFFF_FFFC;
45
46const LEN_MASK: usize = 0xF_FFFF;
47const LEN_INCR: usize = LEN_MASK + 1;
48
49struct IntOrPtr(NonZeroU64, PhantomData<Rc<()>>);
60
61#[derive(Clone, Debug, PartialEq, Eq)]
62enum Variant<'a> {
63 Invalid,
64 Int(u64),
65 Slice(&'a [usize]),
66}
67
68fn hash(path: &[usize]) -> u64 {
69 let mut hasher = DefaultHasher::new();
70 path.hash(&mut hasher);
71 hasher.finish()
72}
73
74impl IntOrPtr {
75 const ROOT: Self = IntOrPtr(NonZeroU64::new(USE_BITS).unwrap(), PhantomData);
76 const INVALID: Self = IntOrPtr(NonZeroU64::new(INVALID).unwrap(), PhantomData);
77
78 #[inline]
79 fn get_ptr(&self) -> Option<*mut usize> {
80 if self.0.get() & USE_MASK == USE_PTR {
81 let p = usize::conv(self.0.get() & MASK_PTR);
82 Some(p as *mut usize)
83 } else {
84 None
85 }
86 }
87
88 fn get_slice(&self) -> Option<&[usize]> {
89 self.get_ptr().map(|p| unsafe {
90 let len = *p.offset(1) & LEN_MASK;
91 let p = p.offset(2);
92 slice::from_raw_parts(p, len)
93 })
94 }
95
96 fn new_int(x: u64) -> Self {
100 assert!(x & USE_MASK == USE_BITS);
101 let x = NonZeroU64::new(x).unwrap();
102 let u = IntOrPtr(x, PhantomData);
103 assert!(u.get_ptr().is_none());
104 u
105 }
106
107 fn new_iter<I: Clone + Iterator<Item = usize>>(iter: I) -> Self {
109 let ref_count = 1;
110 let len = iter.clone().count();
111 let mut v: Vec<usize> = once(ref_count).chain(once(len)).chain(iter).collect();
112
113 let mut p: Option<*mut usize> = None;
114 let pp = &mut p;
115 DB.with_borrow_mut(move |db| {
116 loop {
117 let x = hash(&v);
118 match db.entry(x) {
119 Entry::Occupied(entry) => {
120 let p = *entry.get();
121 let slice = unsafe { slice::from_raw_parts(p.offset(2), *p.offset(1)) };
122 if slice == &v[2..] {
123 unsafe { increment_rc(p) };
124 *pp = Some(p);
125 break;
126 } else {
127 v[1] = v[1].wrapping_add(LEN_INCR);
129 }
130 }
131 Entry::Vacant(entry) => {
132 let p = Box::leak(v.into_boxed_slice()) as *mut [usize] as *mut usize;
133 *pp = Some(p);
134 entry.insert(p);
135 break;
136 }
137 }
138 }
139 });
140
141 let p: u64 = (p.expect("failed to access Id DB") as usize).cast();
142 debug_assert_eq!(p & 3, 0);
143 let p = p | USE_PTR;
144 let u = IntOrPtr(NonZeroU64::new(p).unwrap(), PhantomData);
145 assert!(u.get_ptr().is_some());
146 u
147 }
148
149 fn get(&self) -> Variant<'_> {
150 if let Some(slice) = self.get_slice() {
151 Variant::Slice(slice)
152 } else if self.0.get() == INVALID {
153 Variant::Invalid
154 } else {
155 Variant::Int(self.0.get())
156 }
157 }
158
159 fn to_nzu64(&self) -> NonZeroU64 {
160 if let Some(slice) = self.get_slice() {
161 let x = hash(slice) & MASK_PTR;
162 NonZeroU64::new(x | USE_PTR).unwrap()
163 } else {
164 self.0
165 }
166 }
167
168 fn try_from_u64(n: u64) -> Option<IntOrPtr> {
169 match n & USE_MASK {
170 USE_BITS => {
171 Some(IntOrPtr(NonZeroU64::new(n).unwrap(), PhantomData))
173 }
174 USE_PTR => {
175 let mut result = None;
176 let r = &mut result;
177 DB.with_borrow(|db| {
178 if let Some(p) = db.get(&n) {
179 unsafe { increment_rc(*p) };
180 let p: u64 = (*p as usize).cast();
181 *r = Some(IntOrPtr(NonZeroU64::new(p).unwrap(), PhantomData))
182 }
183 });
184 result
185 }
186 _ if n == !0 => Some(IntOrPtr::INVALID),
187 _ => None,
188 }
189 }
190}
191
192unsafe fn increment_rc(p: *mut usize) {
196 unsafe {
197 let ref_count = *p;
198
199 if ref_count == 0 || ref_count == usize::MAX {
201 std::process::abort();
202 }
203
204 *p = ref_count + 1;
205 }
206}
207
208impl Clone for IntOrPtr {
209 fn clone(&self) -> Self {
210 if let Some(p) = self.get_ptr() {
211 unsafe { increment_rc(p) };
212 }
213 IntOrPtr(self.0, PhantomData)
214 }
215}
216
217impl Drop for IntOrPtr {
218 fn drop(&mut self) {
219 if let Some(p) = self.get_ptr() {
220 unsafe {
221 let ref_count = *p;
222 if ref_count > 1 {
223 *p = ref_count - 1;
224 } else {
225 let len = (*p.offset(1) & LEN_MASK) + 2;
227 let slice = slice::from_raw_parts_mut(p, len);
228
229 let x = hash(slice);
230 DB.with_borrow_mut(|db| db.remove(&x));
231
232 let _ = Box::<[usize]>::from_raw(slice);
233 }
234 }
235 }
236 }
237}
238
239enum PathIter<'a> {
240 Bits(BitsIter),
241 Slice(std::iter::Cloned<std::slice::Iter<'a, usize>>),
242}
243
244impl<'a> Iterator for PathIter<'a> {
245 type Item = usize;
246
247 #[inline]
248 fn next(&mut self) -> Option<usize> {
249 match self {
250 PathIter::Bits(bits) => bits.next(),
251 PathIter::Slice(slice) => slice.next(),
252 }
253 }
254
255 #[inline]
256 fn size_hint(&self) -> (usize, Option<usize>) {
257 match self {
258 PathIter::Bits(bits) => bits.size_hint(),
259 PathIter::Slice(slice) => slice.size_hint(),
260 }
261 }
262}
263
264pub struct WidgetPathIter<'a>(PathIter<'a>);
266impl<'a> Iterator for WidgetPathIter<'a> {
267 type Item = usize;
268
269 #[inline]
270 fn next(&mut self) -> Option<usize> {
271 self.0.next()
272 }
273
274 #[inline]
275 fn size_hint(&self) -> (usize, Option<usize>) {
276 self.0.size_hint()
277 }
278}
279
280#[allow(clippy::assigning_clones)]
319#[derive(Clone)]
320pub struct Id(IntOrPtr);
321
322fn encode(key: usize) -> (u64, u8) {
324 debug_assert!(8 * size_of::<usize>() as u32 - key.leading_zeros() <= 64);
325 let mut x = key as u64 & 0x0000_FFFF_FFFF_FFFF;
326 let mut y = x & 7;
327 x >>= 3;
328 let mut shift = 4;
329 while x != 0 {
330 y |= (8 | (x & 7)) << shift;
331 x >>= 3;
332 shift += 4;
333 }
334 (y, shift)
335}
336
337#[inline]
338fn block_len(x: u64) -> u8 {
339 ((x & MASK_LEN) >> SHIFT_LEN) as u8
340}
341
342fn next_from_bits(mut x: u64) -> (usize, u8) {
344 const TAKE: u64 = 0x7000_0000_0000_0000;
345 const HIGH: u64 = 0x8000_0000_0000_0000;
346 let mut y = (x & TAKE) >> 60;
347 let mut c = 1;
348 while (x & HIGH) != 0 {
349 x <<= 4;
350 y = (y << 3) | ((x & TAKE) >> 60);
351 c += 1;
352 }
353 (y.cast(), c)
354}
355
356#[derive(Clone, Debug)]
357struct BitsIter(u8, u64);
358impl BitsIter {
359 fn new(bits: u64) -> Self {
360 assert!((bits & USE_MASK) == USE_BITS);
361 let len = block_len(bits);
362 BitsIter(len, bits & MASK_BITS)
363 }
364}
365impl Iterator for BitsIter {
366 type Item = usize;
367 fn next(&mut self) -> Option<usize> {
368 if self.0 == 0 {
369 return None;
370 }
371 let (next, blocks) = next_from_bits(self.1);
372 self.0 -= blocks;
373 self.1 <<= 4 * blocks;
374 Some(next)
375 }
376 fn size_hint(&self) -> (usize, Option<usize>) {
377 ((self.0 != 0) as usize, Some(self.0 as usize))
378 }
379}
380
381impl Id {
382 pub(crate) const ROOT: Self = Id(IntOrPtr::ROOT);
384
385 const INVALID: Self = Id(IntOrPtr::INVALID);
386
387 pub fn is_valid(&self) -> bool {
393 self.0.get() != Variant::Invalid
394 }
395
396 pub fn iter(&self) -> WidgetPathIter<'_> {
398 match self.0.get() {
399 Variant::Invalid => panic!("Id::iter: invalid"),
400 Variant::Int(x) => WidgetPathIter(PathIter::Bits(BitsIter::new(x))),
401 Variant::Slice(path) => WidgetPathIter(PathIter::Slice(path.iter().cloned())),
402 }
403 }
404
405 pub fn path_len(&self) -> usize {
407 match self.0.get() {
408 Variant::Invalid => panic!("Id::path_len: invalid"),
409 Variant::Int(x) => BitsIter::new(x).count(),
410 Variant::Slice(path) => path.len(),
411 }
412 }
413
414 pub fn is_ancestor_of(&self, id: &Self) -> bool {
416 match (self.0.get(), id.0.get()) {
417 (Variant::Invalid, _) | (_, Variant::Invalid) => {
418 panic!("Id::is_ancestor_of: invalid")
419 }
420 (Variant::Slice(_), Variant::Int(_)) => {
421 false
423 }
424 (Variant::Int(self_x), Variant::Int(child_x)) => {
425 let self_blocks = block_len(self_x);
426 let child_blocks = block_len(child_x);
427 if self_blocks > child_blocks {
428 return false;
429 }
430
431 let shift = 4 * (BLOCKS - self_blocks) + 8;
433 shift == 64 || self_x >> shift == child_x >> shift
434 }
435 (Variant::Int(self_x), Variant::Slice(child)) => {
436 let iter = BitsIter::new(self_x);
437 iter.zip(child.iter()).all(|(a, b)| a == *b)
438 }
439 (Variant::Slice(self_path), Variant::Slice(child)) => child.starts_with(self_path),
440 }
441 }
442
443 pub fn common_ancestor(&self, id: &Self) -> Self {
445 let mut r = Id::ROOT;
446 for (a, b) in self.iter().zip(id.iter()) {
447 if a != b {
448 break;
449 }
450 r = r.make_child(a);
451 }
452 r
453 }
454
455 pub fn iter_keys_after(&self, id: &Self) -> WidgetPathIter<'_> {
456 let mut self_iter = self.iter();
457 for v in id.iter() {
458 if self_iter.next() != Some(v) {
459 return WidgetPathIter(PathIter::Bits(BitsIter(0, 0)));
460 }
461 }
462 self_iter
463 }
464
465 pub fn next_key_after(&self, id: &Self) -> Option<usize> {
471 match (id.0.get(), self.0.get()) {
472 (Variant::Invalid, _) | (_, Variant::Invalid) => {
473 panic!("Id::next_key_after: invalid")
474 }
475 (Variant::Slice(_), Variant::Int(_)) => None,
476 (Variant::Int(parent_x), Variant::Int(child_x)) => {
477 let parent_blocks = block_len(parent_x);
478 let child_blocks = block_len(child_x);
479 if parent_blocks >= child_blocks {
480 return None;
481 }
482
483 let shift = 4 * (BLOCKS - parent_blocks) + 8;
485 if shift != 64 && parent_x >> shift != child_x >> shift {
486 return None;
487 }
488
489 debug_assert!(child_blocks > 0);
490 let next_bits = (child_x & MASK_BITS) << (4 * parent_blocks);
491 Some(next_from_bits(next_bits).0)
492 }
493 (Variant::Int(parent_x), Variant::Slice(child_path)) => {
494 let iter = BitsIter::new(parent_x);
495 let mut child_iter = child_path.iter();
496 if iter.zip(&mut child_iter).all(|(a, b)| a == *b) {
497 child_iter.next().cloned()
498 } else {
499 None
500 }
501 }
502 (Variant::Slice(parent_path), Variant::Slice(child_path)) => {
503 if child_path.starts_with(parent_path) {
504 child_path[parent_path.len()..].iter().next().cloned()
505 } else {
506 None
507 }
508 }
509 }
510 }
511
512 pub fn parent(&self) -> Option<Id> {
514 match self.0.get() {
515 Variant::Invalid => None,
516 Variant::Int(x) => {
517 let mut bit_len = 4 * block_len(x);
518 while bit_len > 0 {
519 bit_len -= 4;
520 if bit_len > 0 && (x >> (64 - bit_len)) & 8 != 0 {
521 continue;
522 }
523
524 let len = ((bit_len / 4) as u64) << SHIFT_LEN;
525 let mask = MASK_BITS << (56 - bit_len);
526 let id = (x & mask) | len | USE_BITS;
527 return Some(Id(IntOrPtr::new_int(id)));
528 }
529 None
530 }
531 Variant::Slice(path) => {
532 if path.is_empty() {
533 return None;
534 }
535
536 let len = path.len();
537 let path = &path[0..len - 1];
538
539 if len > BLOCKS as usize {
540 Some(Id(IntOrPtr::new_iter(path.iter().cloned())))
541 } else {
542 Some(make_id(path))
543 }
544 }
545 }
546 }
547
548 #[must_use]
553 pub fn make_child(&self, key: usize) -> Self {
554 match self.0.get() {
555 Variant::Invalid => panic!("Id::make_child: invalid"),
556 Variant::Int(self_x) => {
557 let block_len = block_len(self_x);
560 let avail_blocks = BLOCKS - block_len;
561 let req_bits = (8 * size_of::<usize>() as u8 - key.leading_zeros() as u8).max(1);
563 if req_bits <= 3 * avail_blocks {
564 let (bits, bit_len) = encode(key);
565 let used_blocks = bit_len / 4;
566 debug_assert_eq!(used_blocks, req_bits.div_ceil(3));
567 let len = (block_len as u64 + used_blocks as u64) << SHIFT_LEN;
568 let rest = bits << 4 * avail_blocks - bit_len + 8;
569 let id = (self_x & MASK_BITS) | rest | len | USE_BITS;
570 Id(IntOrPtr::new_int(id))
571 } else {
572 Id(IntOrPtr::new_iter(BitsIter::new(self_x).chain(once(key))))
573 }
574 }
575 Variant::Slice(path) => Id(IntOrPtr::new_iter(path.iter().cloned().chain(once(key)))),
576 }
577 }
578
579 pub fn to_nzu64(&self) -> NonZeroU64 {
587 self.0.to_nzu64()
588 }
589
590 pub fn try_from_u64(n: u64) -> Option<Id> {
616 IntOrPtr::try_from_u64(n).map(Id)
617 }
618}
619
620impl PartialEq for Id {
621 fn eq(&self, rhs: &Self) -> bool {
622 match (self.0.get(), rhs.0.get()) {
623 (Variant::Invalid, _) | (_, Variant::Invalid) => panic!("Id::eq: invalid id"),
624 (Variant::Int(x), Variant::Int(y)) => x == y,
625 _ => self.iter().eq(rhs.iter()),
626 }
627 }
628}
629impl Eq for Id {}
630
631impl PartialEq<str> for Id {
632 fn eq(&self, rhs: &str) -> bool {
633 let formatted = format!("{self}");
635 formatted == rhs
636 }
637}
638impl PartialEq<&str> for Id {
639 fn eq(&self, rhs: &&str) -> bool {
640 self == *rhs
641 }
642}
643
644impl PartialOrd for Id {
645 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
646 Some(self.cmp(rhs))
647 }
648}
649
650impl Ord for Id {
651 fn cmp(&self, rhs: &Self) -> Ordering {
652 match (self.0.get(), rhs.0.get()) {
653 (Variant::Invalid, _) | (_, Variant::Invalid) => panic!("Id::cmp: invalid id"),
654 (Variant::Int(x), Variant::Int(y)) => x.cmp(&y),
655 _ => self.iter().cmp(rhs.iter()),
656 }
657 }
658}
659
660impl Hash for Id {
661 fn hash<H: Hasher>(&self, state: &mut H) {
662 match self.0.get() {
663 Variant::Invalid => (),
664 Variant::Int(x) => {
665 x.hash(state);
666 }
667 Variant::Slice(path) => {
668 path.hash(state);
669 }
670 }
671 }
672}
673
674impl PartialEq<Option<Id>> for Id {
675 #[inline]
676 fn eq(&self, rhs: &Option<Id>) -> bool {
677 rhs.as_ref().map(|id| id == self).unwrap_or(false)
678 }
679}
680
681impl<'a> PartialEq<Option<&'a Id>> for Id {
682 #[inline]
683 fn eq(&self, rhs: &Option<&'a Id>) -> bool {
684 rhs.map(|id| id == self).unwrap_or(false)
685 }
686}
687
688impl<'a> PartialEq<&'a Id> for Id {
689 #[inline]
690 fn eq(&self, rhs: &&Id) -> bool {
691 self == *rhs
692 }
693}
694
695impl<'a> PartialEq<&'a Option<Id>> for Id {
696 #[inline]
697 fn eq(&self, rhs: &&Option<Id>) -> bool {
698 self == *rhs
699 }
700}
701
702impl Default for Id {
703 fn default() -> Self {
704 Id::INVALID
705 }
706}
707
708impl fmt::Debug for Id {
709 #[inline]
710 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
711 write!(f, "Id({self})")
712 }
713}
714
715impl fmt::Display for Id {
716 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
717 match self.0.get() {
718 Variant::Invalid => write!(f, "#INVALID"),
719 Variant::Int(x) => {
720 let len = block_len(x);
721 if len == 0 {
722 write!(f, "#")
723 } else {
724 let bits = x >> (4 * (BLOCKS - len) + 8);
725 write!(f, "#{1:0>0$x}", len as usize, bits)
726 }
727 }
728 Variant::Slice(path) => {
729 write!(f, "#")?;
730 for key in path {
731 let (bits, bit_len) = encode(*key);
732 write!(f, "{1:0>0$x}", bit_len as usize / 4, bits)?;
733 }
734 Ok(())
735 }
736 }
737 }
738}
739
740#[cfg(feature = "accesskit")]
744impl From<Id> for accesskit::NodeId {
745 #[inline]
746 fn from(id: Id) -> Self {
747 accesskit::NodeId(id.to_nzu64().get())
748 }
749}
750
751#[cfg(feature = "accesskit")]
755impl From<&Id> for accesskit::NodeId {
756 #[inline]
757 fn from(id: &Id) -> Self {
758 accesskit::NodeId(id.to_nzu64().get())
759 }
760}
761
762pub trait HasId {
771 fn has_id(self) -> Id;
772}
773
774impl HasId for Id {
775 #[inline]
776 fn has_id(self) -> Id {
777 self
778 }
779}
780
781impl HasId for &Id {
782 #[inline]
783 fn has_id(self) -> Id {
784 self.clone()
785 }
786}
787
788impl HasId for &mut Id {
789 #[inline]
790 fn has_id(self) -> Id {
791 self.clone()
792 }
793}
794
795fn make_id(seq: &[usize]) -> Id {
796 let mut id = Id::ROOT;
797 for x in seq {
798 id = id.make_child(*x);
799 }
800 id
801}
802
803#[cfg(test)]
804mod test {
805 use super::*;
806
807 #[test]
808 fn size_of_option_widget_id() {
809 use std::mem::size_of;
810 assert_eq!(size_of::<Id>(), 8);
811 assert_eq!(size_of::<Id>(), size_of::<Option<Id>>());
812 }
813
814 #[test]
815 fn test_partial_eq() {
816 assert_eq!(Id::ROOT, Id::ROOT);
817 let c1 = Id::ROOT.make_child(0).make_child(15);
818 let c2 = Id::ROOT.make_child(1).make_child(15);
819 let c3 = Id::ROOT.make_child(0).make_child(14);
820 let c4 = Id::ROOT.make_child(0).make_child(15);
821 assert!(c1 != c2);
822 assert!(c1 != c3);
823 assert!(c2 != c3);
824 assert_eq!(c1, c4);
825 assert!(c1 != Id::ROOT);
826
827 let d1 = Id(IntOrPtr::new_iter([0, 15].iter().cloned()));
828 let d2 = Id(IntOrPtr::new_iter([1, 15].iter().cloned()));
829 assert_eq!(c1, d1);
830 assert_eq!(c2, d2);
831 assert!(d1 != d2);
832 assert!(d1 != Id::ROOT);
833 }
834
835 #[test]
836 #[should_panic]
837 fn test_partial_eq_invalid_1() {
838 let _ = Id::INVALID == Id::INVALID;
839 }
840
841 #[test]
842 #[should_panic]
843 fn test_partial_eq_invalid_2() {
844 let _ = Id::ROOT == Id::INVALID;
845 }
846
847 #[test]
848 #[should_panic]
849 fn test_partial_eq_invalid_3() {
850 let _ = Id::INVALID == Id::ROOT;
851 }
852
853 #[test]
854 fn test_partial_eq_str() {
855 assert_eq!(Id::ROOT, "#");
856 assert!(Id::ROOT != "#0");
857 assert_eq!(Id::ROOT.make_child(0).make_child(15), "#097");
858 assert_eq!(Id::ROOT.make_child(1).make_child(15), "#197");
859 let c3 = Id::ROOT.make_child(0).make_child(14);
860 assert_eq!(c3, "#096");
861 assert!(c3 != "#097");
862 }
863
864 #[test]
865 fn test_ord() {
866 let root = Id::ROOT;
867 let c_0 = root.make_child(0);
868 let c_0_0 = c_0.make_child(0);
869 assert!(root < c_0);
870 assert!(c_0 < c_0_0);
871
872 let c_1 = root.make_child(1);
873 assert!(c_0_0 < c_1);
874 assert!(c_1 < root.make_child(8));
875
876 let d_0 = Id(IntOrPtr::new_iter([0].iter().cloned()));
877 let d_0_0 = Id(IntOrPtr::new_iter([0, 0].iter().cloned()));
878 let d_1 = Id(IntOrPtr::new_iter([1].iter().cloned()));
879 assert_eq!(d_0.cmp(&c_0), Ordering::Equal);
880 assert_eq!(d_0_0.cmp(&c_0_0), Ordering::Equal);
881 assert_eq!(d_1.cmp(&c_1), Ordering::Equal);
882 assert!(d_0 < d_0_0);
883 assert!(d_0_0 < d_1);
884 }
885
886 #[test]
887 #[should_panic]
888 fn test_ord_invalid() {
889 let _ = Id::INVALID < Id::ROOT;
890 }
891
892 #[test]
893 fn test_next_from_bits() {
894 const REST: u64 = 0x0FFF_FFFF_FFFF_FFFF;
895 assert_eq!(next_from_bits(0), (0, 1));
896 assert_eq!(next_from_bits(REST), (0, 1));
897 assert_eq!(next_from_bits((7 << 60) | REST), (7, 1));
898 assert_eq!(next_from_bits((0xB << 60) | (3 << 56)), (27, 2));
899 assert_eq!(
900 next_from_bits(0xC9A4_F300_0000_0000),
901 ((4 << 9) + (1 << 6) + (2 << 3) + 4, 4)
902 );
903 }
904
905 #[test]
906 fn text_bits_iter() {
907 fn as_vec(x: u64) -> Vec<usize> {
908 BitsIter::new(x).collect()
909 }
910 assert_eq!(as_vec(USE_BITS), Vec::<usize>::new());
911 assert_eq!(as_vec(0x3100_0000_0000_0011), vec![3]);
912 assert_eq!(as_vec(0x1A93_007F_0000_0071), vec![1, 139, 0, 0, 7]);
913 }
914
915 #[test]
916 fn test_parent() {
917 fn test(seq: &[usize]) {
918 let len = seq.len();
919 let id = make_id(&seq[..len - 1]);
920
921 if len == 0 {
922 assert_eq!(id.parent(), None);
923 } else {
924 let id2 = id.make_child(seq[len - 1]);
925 assert_eq!(id2.parent(), Some(id));
926 }
927 }
928
929 test(&[4]);
930 test(&[4, 0]);
931 test(&[0, 0, 0]);
932 test(&[0, 1, 0]);
933 test(&[9, 0, 1, 300]);
934 test(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0]);
935 test(&[313553, 13513, 13511631]);
936 }
937
938 #[test]
939 fn test_make_child() {
940 fn test(seq: &[usize], x: u64) {
941 let id = make_id(seq);
942 let v = id.to_nzu64().get();
943 if v != x {
944 panic!("test({seq:?}, {x:x}): found {v:x}");
945 }
946
947 assert!(id.is_ancestor_of(&id));
949 }
950
951 test(&[], USE_BITS);
952 test(&[0, 0, 0], (3 << 4) | USE_BITS);
953 test(&[0, 1, 0], (3 << 4) | (1 << 56) | USE_BITS);
954 test(&[9, 0, 1, 300], 0x9101cd4000000071);
955 test(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0], 0x12345679091920e1);
956 }
957
958 #[test]
959 fn test_display() {
960 fn from_seq(seq: &[usize]) -> String {
961 format!("{}", make_id(seq))
962 }
963
964 assert_eq!(from_seq(&[]), "#");
965 assert_eq!(from_seq(&[0]), "#0");
966 assert_eq!(from_seq(&[1, 2, 3]), "#123");
967 assert_eq!(from_seq(&[5, 9, 13]), "#59195");
968 assert_eq!(from_seq(&[321]), "#d81");
969 assert_eq!(
970 from_seq(&[313553, 13513, 13511631]),
971 "#99ccba1bab91ebcadf97"
972 )
973 }
974
975 #[test]
976 fn test_is_ancestor() {
977 fn test(seq: &[usize], seq2: &[usize]) {
978 let id = make_id(seq);
979 let mut id2 = id.clone();
980 for x in seq2 {
981 id2 = id2.make_child(*x);
982 }
983 let next = seq2.iter().next().cloned();
984 assert_eq!(id.is_ancestor_of(&id2), next.is_some() || id == id2);
985 assert_eq!(id2.next_key_after(&id), next);
986 }
987
988 test(&[], &[]);
989 test(&[], &[1]);
990 test(&[], &[51930, 2, 18]);
991 test(&[5, 6, 0, 1, 1], &[]);
992 test(&[5, 6, 0, 1, 1], &[1, 1]);
993 test(&[8, 26], &[0]);
994 test(&[9, 9, 9, 9, 9, 9, 9], &[]);
995 test(&[9, 9, 9, 9, 9, 9, 9], &[6]);
996 test(&[9, 9, 9, 9, 9, 9, 9, 9], &[3]);
997 test(&[0, 2, 2, 0, 17], &[0]);
998 }
999
1000 #[test]
1001 fn test_not_ancestor() {
1002 fn test(seq: &[usize], seq2: &[usize]) {
1003 let id = make_id(seq);
1004 let id2 = make_id(seq2);
1005 assert_eq!(id.is_ancestor_of(&id2), false);
1006 assert_eq!(id2.next_key_after(&id), None);
1007 }
1008
1009 test(&[0], &[]);
1010 test(&[0], &[1]);
1011 test(&[2, 10, 1], &[2, 10]);
1012 test(&[0, 5, 2], &[0, 1, 5]);
1013 }
1014
1015 #[test]
1016 fn common_ancestor() {
1017 fn test(seq: &[usize], seq2: &[usize], seq3: &[usize]) {
1018 let id = make_id(seq);
1019 let id2 = make_id(seq2);
1020 assert_eq!(id.common_ancestor(&id2), make_id(seq3));
1021 }
1022
1023 test(&[0], &[], &[]);
1024 test(&[0], &[1, 2], &[]);
1025 test(&[0], &[0, 2], &[0]);
1026 test(&[2, 10, 1], &[2, 10], &[2, 10]);
1027 test(&[0, 5, 2], &[0, 5, 1], &[0, 5]);
1028 }
1029
1030 #[test]
1031 fn deduplicate_allocations() {
1032 let id1 = make_id(&[2, 6, 1, 1, 0, 13, 0, 100, 1000]);
1033 let id2 = make_id(&[2, 6, 1, 1, 0, 13, 0, 100, 1000]);
1034 assert_eq!(id1.0.0, id2.0.0);
1035 }
1036}