pecos_core/sets/
element.rs

1// Copyright 2024 The PECOS Developers
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4// in compliance with the License.You may obtain a copy of the License at
5//
6//     https://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software distributed under the License
9// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10// or implied. See the License for the specific language governing permissions and limitations under
11// the License.
12
13use core::fmt::Debug;
14use core::hash::Hash;
15
16pub trait Element: Debug + Clone + Ord + Copy + Hash {}
17
18// blanket implementation should allow for integers, char, etc.
19impl<T: Debug + Clone + Ord + Copy + Hash> Element for T {}
20
21#[allow(clippy::module_name_repetitions)]
22pub trait IndexableElement: Element {
23    fn to_usize(&self) -> usize;
24    fn from_usize(value: usize) -> Self;
25}
26
27macro_rules! impl_indexable_element_safe {
28    ($t:ty) => {
29        impl IndexableElement for $t {
30            #[allow(clippy::as_conversions, clippy::cast_possible_truncation)]
31            #[inline(always)]
32            fn to_usize(&self) -> usize {
33                *self as usize
34            }
35
36            #[allow(clippy::as_conversions, clippy::cast_possible_truncation)]
37            #[inline(always)]
38            fn from_usize(value: usize) -> Self {
39                value as $t
40            }
41        }
42    };
43}
44
45// Safe implementations for types that are always smaller than or equal to usize
46impl_indexable_element_safe!(u8);
47impl_indexable_element_safe!(u16);
48impl_indexable_element_safe!(u32);
49impl_indexable_element_safe!(usize);
50
51// Conditional implementation for u64
52#[cfg(target_pointer_width = "64")]
53impl_indexable_element_safe!(u64);
54
55#[cfg(target_pointer_width = "32")]
56impl IndexableElement for u64 {
57    #[inline(always)]
58    fn to_usize(&self) -> usize {
59        usize::try_from(*self).expect("u64 value too large for 32-bit usize")
60    }
61
62    #[allow(clippy::as_conversions)]
63    #[inline(always)]
64    fn from_usize(value: usize) -> Self {
65        value as u64
66    }
67}
68
69// u128 is always problematic for current architectures, so we'll implement it to always panic
70impl IndexableElement for u128 {
71    #[inline(always)]
72    fn to_usize(&self) -> usize {
73        panic!("u128 cannot be safely converted to usize without potential data loss")
74    }
75
76    #[inline(always)]
77    fn from_usize(_value: usize) -> Self {
78        panic!("usize cannot be safely converted to u128 on all platforms")
79    }
80}