//! `Cell` — a type-erased 64-bit word holding one scalar value with its kind //! stripped away (C7). The type lives in the schema / column / port, never in //! the value, so a cell is read back only by naming its type via a typed //! accessor. `Scalar` is built on top of this; `Cell` itself knows nothing of //! `Scalar` or `ScalarKind`. use crate::scalar::Timestamp; /// A type-erased 64-bit cell: the raw storage of one scalar value with its kind /// stripped away. The bits are meaningless on their own — the type lives in the /// schema/column/port, not in the value (C7), so the word is recovered **only** /// by naming the type at the call site via a typed accessor ([`Cell::i64`], /// [`Cell::f64`], [`Cell::bool`], [`Cell::ts`]). Each reinterprets the word with /// no tag to check and therefore no branch — the caller's choice of accessor /// *is* the type context the hot path already holds. The inner word is private; /// there is no kind-free way to read it. /// /// All four base types fit one 64-bit word: `i64`/`Timestamp`/`bool` reuse the /// same integer word, `f64` via its IEEE-754 bit pattern. `Eq`/`Hash` are /// bit-exact (so `+0.0`/`-0.0` differ and a `NaN` bit pattern equals itself) — /// the semantics of a raw word, not of a number. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Cell(u64); impl Cell { /// Store an `i64` (identity bit-cast). pub fn from_i64(v: i64) -> Self { Cell(v as u64) } /// Store an `f64` as its IEEE-754 bit pattern. pub fn from_f64(v: f64) -> Self { Cell(v.to_bits()) } /// Store a `bool` as `0`/`1`. pub fn from_bool(v: bool) -> Self { Cell(v as u64) } /// Store a [`Timestamp`] (its `i64` epoch-ns, bit-cast). pub fn from_ts(v: Timestamp) -> Self { Cell(v.0 as u64) } /// Read the word as `i64` (identity bit-cast). The caller asserts the type /// by choosing this accessor; there is no tag to check, hence no branch. pub fn i64(self) -> i64 { self.0 as i64 } /// Read the word as `f64` from its IEEE-754 bit pattern. Branch-free. pub fn f64(self) -> f64 { f64::from_bits(self.0) } /// Read the word as `bool` (any non-zero word is `true`). Branch-free. pub fn bool(self) -> bool { self.0 != 0 } /// Read the word as a [`Timestamp`] (identity bit-cast). Branch-free. pub fn ts(self) -> Timestamp { Timestamp(self.0 as i64) } }