use core::{fmt, num::NonZeroU8};
use super::*;
#[derive(Copy, Clone)]
pub struct ValueOrAlias {
value: ValueRef,
value_id: ValueId,
alias_id: u8,
stack_size: u8,
}
impl ValueOrAlias {
pub fn new(value: ValueRef) -> Self {
let borrowed = value.borrow();
let value_id = borrowed.id();
let stack_size = borrowed.ty().size_in_felts() as u8;
drop(borrowed);
Self {
value,
value_id,
stack_size,
alias_id: 0,
}
}
#[inline(always)]
pub fn stack_size(&self) -> usize {
self.stack_size as usize
}
pub fn copy(mut self, id: NonZeroU8) -> Self {
self.alias_id = id.get();
self
}
pub fn unaliased(mut self) -> Self {
self.alias_id = 0;
self
}
pub fn set_alias(&mut self, id: NonZeroU8) {
self.alias_id = id.get();
}
pub fn value(self) -> ValueRef {
self.value
}
pub fn borrow_value(&self) -> EntityRef<'_, dyn Value> {
self.value.borrow()
}
pub fn alias(self) -> Option<NonZeroU8> {
NonZeroU8::new(self.alias_id)
}
pub fn unwrap_alias(self) -> NonZeroU8 {
NonZeroU8::new(self.alias_id).unwrap_or_else(|| panic!("expected {self:?} to be an alias"))
}
pub fn is_alias(&self) -> bool {
self.alias_id != 0
}
}
impl core::borrow::Borrow<ValueRef> for ValueOrAlias {
#[inline(always)]
fn borrow(&self) -> &ValueRef {
&self.value
}
}
impl core::borrow::Borrow<ValueRef> for &ValueOrAlias {
#[inline(always)]
fn borrow(&self) -> &ValueRef {
&self.value
}
}
impl core::borrow::Borrow<ValueRef> for &mut ValueOrAlias {
#[inline(always)]
fn borrow(&self) -> &ValueRef {
&self.value
}
}
impl Eq for ValueOrAlias {}
impl PartialEq for ValueOrAlias {
fn eq(&self, other: &Self) -> bool {
self.value_id == other.value_id && self.alias_id == other.alias_id
}
}
impl core::hash::Hash for ValueOrAlias {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.value_id.hash(state);
self.alias_id.hash(state);
}
}
impl Ord for ValueOrAlias {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
self.value_id.cmp(&other.value_id).then(self.alias_id.cmp(&other.alias_id))
}
}
impl PartialEq<ValueRef> for ValueOrAlias {
fn eq(&self, other: &ValueRef) -> bool {
&self.value == other
}
}
impl PartialOrd for ValueOrAlias {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl From<ValueRef> for ValueOrAlias {
#[inline]
fn from(value: ValueRef) -> Self {
Self::new(value)
}
}
impl From<ValueOrAlias> for ValueRef {
#[inline]
fn from(value: ValueOrAlias) -> Self {
value.value
}
}
impl fmt::Display for ValueOrAlias {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.alias() {
None => write!(f, "{}", &self.value_id),
Some(alias) => write!(f, "{}.{alias}", &self.value_id),
}
}
}
impl fmt::Debug for ValueOrAlias {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}