use serde::{Deserialize, Serialize};
use slotmap::new_key_type;
use std::ops::{Add, AddAssign, Sub, SubAssign};
new_key_type! {
pub struct InstId;
}
#[repr(transparent)]
#[derive(
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Serialize, Deserialize,
)]
pub struct CycleId(pub u64);
#[repr(transparent)]
#[derive(
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Serialize, Deserialize,
)]
pub struct CycleIndex(pub u64);
impl CycleId {
pub const fn new(id: u64) -> Self {
Self(id)
}
pub const fn get(self) -> u64 {
self.0
}
}
impl CycleIndex {
pub const fn new(index: u64) -> Self {
Self(index)
}
pub const fn get(self) -> u64 {
self.0
}
}
impl From<u64> for CycleId {
#[inline(always)]
fn from(value: u64) -> Self {
Self(value)
}
}
impl From<CycleId> for u64 {
#[inline(always)]
fn from(id: CycleId) -> Self {
id.0
}
}
impl From<usize> for CycleId {
#[inline(always)]
fn from(value: usize) -> Self {
Self(value as u64)
}
}
impl From<CycleId> for usize {
#[inline(always)]
fn from(id: CycleId) -> Self {
id.0 as usize
}
}
impl From<u64> for CycleIndex {
#[inline(always)]
fn from(value: u64) -> Self {
Self(value)
}
}
impl From<CycleIndex> for u64 {
#[inline(always)]
fn from(index: CycleIndex) -> Self {
index.0
}
}
impl From<usize> for CycleIndex {
#[inline(always)]
fn from(value: usize) -> Self {
Self(value as u64)
}
}
impl From<CycleIndex> for usize {
#[inline(always)]
fn from(index: CycleIndex) -> Self {
index.0 as usize
}
}
impl<T: Into<CycleIndex>> Add<T> for CycleIndex {
type Output = CycleIndex;
fn add(self, rhs: T) -> Self::Output {
let rhs_index = rhs.into();
CycleIndex(self.0 + rhs_index.0)
}
}
impl<T: Into<CycleIndex>> Sub<T> for CycleIndex {
type Output = CycleIndex;
fn sub(self, rhs: T) -> Self::Output {
let rhs_index = rhs.into();
CycleIndex(self.0 - rhs_index.0)
}
}
impl<T: Into<CycleIndex>> AddAssign<T> for CycleIndex {
fn add_assign(&mut self, rhs: T) {
let rhs_index = rhs.into();
self.0 += rhs_index.0;
}
}
impl<T: Into<CycleIndex>> SubAssign<T> for CycleIndex {
fn sub_assign(&mut self, rhs: T) {
let rhs_index = rhs.into();
self.0 -= rhs_index.0;
}
}
impl PartialEq<u64> for CycleIndex {
fn eq(&self, other: &u64) -> bool {
self.0 == *other
}
}
impl PartialEq<usize> for CycleIndex {
fn eq(&self, other: &usize) -> bool {
self.0 as usize == *other
}
}
impl PartialEq<i32> for CycleIndex {
fn eq(&self, other: &i32) -> bool {
if *other < 0 {
return false;
}
self.0 == *other as u64
}
}
#[cfg(feature = "python")]
mod python {
use super::*;
use pyo3::prelude::*;
use pyo3_stub_gen::impl_stub_type;
use slotmap::{Key, KeyData};
impl_stub_type!(CycleId = u64);
impl_stub_type!(CycleIndex = u64);
impl_stub_type!(InstId = u64);
impl<'py> IntoPyObject<'py> for InstId {
type Target = <u64 as IntoPyObject<'py>>::Target;
type Output = <u64 as IntoPyObject<'py>>::Output;
type Error = <u64 as IntoPyObject<'py>>::Error;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
self.data().as_ffi().into_pyobject(py)
}
}
impl<'a, 'py> FromPyObject<'a, 'py> for InstId {
type Error = PyErr;
fn extract(obj: Borrowed<'a, 'py, PyAny>) -> PyResult<Self> {
let value: u64 = obj.extract()?;
Ok(InstId::from(KeyData::from_ffi(value)))
}
}
impl<'py> IntoPyObject<'py> for CycleId {
type Target = <u64 as IntoPyObject<'py>>::Target;
type Output = <u64 as IntoPyObject<'py>>::Output;
type Error = <u64 as IntoPyObject<'py>>::Error;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
self.0.into_pyobject(py)
}
}
impl<'a, 'py> FromPyObject<'a, 'py> for CycleId {
type Error = PyErr;
fn extract(obj: Borrowed<'a, 'py, PyAny>) -> PyResult<Self> {
let value: u64 = obj.extract()?;
Ok(CycleId(value))
}
}
impl<'py> IntoPyObject<'py> for CycleIndex {
type Target = <u64 as IntoPyObject<'py>>::Target;
type Output = <u64 as IntoPyObject<'py>>::Output;
type Error = <u64 as IntoPyObject<'py>>::Error;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
self.0.into_pyobject(py)
}
}
impl<'a, 'py> FromPyObject<'a, 'py> for CycleIndex {
type Error = PyErr;
fn extract(obj: Borrowed<'a, 'py, PyAny>) -> PyResult<Self> {
let value: u64 = obj.extract()?;
Ok(CycleIndex(value))
}
}
}