Skip to main content

polka/
value.rs

1use core::fmt;
2
3#[derive(Clone, Copy, PartialEq, Eq, Hash)]
4pub struct Value(pub u64);
5
6pub const HANDLE_NONE: u64 = u64::MAX;
7
8const HANDLE_SLOT_BITS: u32 = 24;
9const HANDLE_SLOT_MASK: u64 = (1u64 << HANDLE_SLOT_BITS) - 1;
10const HANDLE_GEN_MASK:  u64 = (1u64 << HANDLE_SLOT_BITS) - 1;
11pub const HANDLE_SLOT_MAX: u32 = (1u32 << HANDLE_SLOT_BITS) - 2;
12
13impl Value {
14    pub const ZERO: Value = Value(0);
15    pub const NONE: Value = Value(HANDLE_NONE);
16    pub const UNIT:  Value = Value(0);
17    pub const FALSE: Value = Value(0);
18    pub const TRUE:  Value = Value(1);
19
20    #[inline(always)]
21    pub fn raw(self) -> u64 { self.0 }
22
23    #[inline(always)]
24    pub fn from_raw(n: u64) -> Value { Value(n) }
25
26    #[inline(always)]
27    pub fn from_int(n: i64) -> Value { Value(n as u64) }
28
29    #[inline(always)]
30    pub fn from_float(f: f64) -> Value { Value(f.to_bits()) }
31
32    #[inline(always)]
33    pub fn from_float_f32(f: f64) -> Value { Value((f as f32).to_bits() as u64) }
34
35    #[inline(always)]
36    pub fn from_bool(b: bool) -> Value { Value(if b { 1 } else { 0 }) }
37
38    #[inline(always)]
39    pub fn from_char(c: char) -> Value { Value(c as u64) }
40
41    #[inline(always)]
42    pub fn from_handle(slot: u32, generation: u32) -> Value {
43        let s = (slot as u64) & HANDLE_SLOT_MASK;
44        let g = (generation as u64) & HANDLE_GEN_MASK;
45        Value((s << HANDLE_SLOT_BITS) | g)
46    }
47
48    #[inline(always)]
49    pub fn is_handle_none(self) -> bool { self.0 == HANDLE_NONE }
50
51    #[inline(always)]
52    pub fn as_int(self) -> i64 { self.0 as i64 }
53
54    #[inline(always)]
55    pub fn as_float(self) -> f64 { f64::from_bits(self.0) }
56
57    #[inline(always)]
58    pub fn as_bool(self) -> bool { self.0 != 0 }
59
60    #[inline(always)]
61    pub fn as_char(self) -> Option<char> { char::from_u32(self.0 as u32) }
62
63    #[inline(always)]
64    pub fn as_handle(self) -> (u32, u32) {
65        let slot = ((self.0 >> HANDLE_SLOT_BITS) & HANDLE_SLOT_MASK) as u32;
66        let gen_ = (self.0 & HANDLE_GEN_MASK) as u32;
67        (slot, gen_)
68    }
69}
70
71impl fmt::Debug for Value {
72    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73        if self.is_handle_none() { return write!(f, "None"); }
74        write!(f, "Value({:#018x})", self.0)
75    }
76}
77