add UIntInRange[Inclusive][Type]
This commit is contained in:
		
							parent
							
								
									57aae7b7fb
								
							
						
					
					
						commit
						3afab89c2a
					
				
					 3 changed files with 536 additions and 15 deletions
				
			
		| 
						 | 
					@ -7,6 +7,7 @@ use crate::{
 | 
				
			||||||
        target::{GetTarget, Target},
 | 
					        target::{GetTarget, Target},
 | 
				
			||||||
        Expr, NotALiteralExpr, ToExpr, ToLiteralBits,
 | 
					        Expr, NotALiteralExpr, ToExpr, ToLiteralBits,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    hdl,
 | 
				
			||||||
    intern::{Intern, Interned, Memoize},
 | 
					    intern::{Intern, Interned, Memoize},
 | 
				
			||||||
    sim::value::{SimValue, ToSimValueWithType},
 | 
					    sim::value::{SimValue, ToSimValueWithType},
 | 
				
			||||||
    source_location::SourceLocation,
 | 
					    source_location::SourceLocation,
 | 
				
			||||||
| 
						 | 
					@ -30,6 +31,23 @@ use std::{
 | 
				
			||||||
    sync::Arc,
 | 
					    sync::Arc,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mod uint_in_range;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[hdl]
 | 
				
			||||||
 | 
					pub type UIntInRangeType<Start: Size, End: Size> = uint_in_range::UIntInRangeType<Start, End>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[hdl]
 | 
				
			||||||
 | 
					pub type UIntInRange<const START: usize, const END: usize> =
 | 
				
			||||||
 | 
					    UIntInRangeType<ConstUsize<START>, ConstUsize<END>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[hdl]
 | 
				
			||||||
 | 
					pub type UIntInRangeInclusiveType<Start: Size, End: Size> =
 | 
				
			||||||
 | 
					    uint_in_range::UIntInRangeInclusiveType<Start, End>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[hdl]
 | 
				
			||||||
 | 
					pub type UIntInRangeInclusive<const START: usize, const END: usize> =
 | 
				
			||||||
 | 
					    UIntInRangeInclusiveType<ConstUsize<START>, ConstUsize<END>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod sealed {
 | 
					mod sealed {
 | 
				
			||||||
    pub trait BoolOrIntTypeSealed {}
 | 
					    pub trait BoolOrIntTypeSealed {}
 | 
				
			||||||
    pub trait SizeSealed {}
 | 
					    pub trait SizeSealed {}
 | 
				
			||||||
| 
						 | 
					@ -536,19 +554,14 @@ macro_rules! impl_int {
 | 
				
			||||||
        pub const $name: $generic_name = $generic_name;
 | 
					        pub const $name: $generic_name = $generic_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        impl<Width: Size> $name<Width> {
 | 
					        impl<Width: Size> $name<Width> {
 | 
				
			||||||
            pub fn new(width: Width::SizeType) -> Self {
 | 
					            pub const fn new(width: Width::SizeType) -> Self {
 | 
				
			||||||
                Self { width }
 | 
					                Self { width }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            pub fn width(self) -> usize {
 | 
					            pub fn width(self) -> usize {
 | 
				
			||||||
                Width::as_usize(self.width)
 | 
					                Width::as_usize(self.width)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            pub fn type_properties(self) -> TypeProperties {
 | 
					            pub fn type_properties(self) -> TypeProperties {
 | 
				
			||||||
                TypeProperties {
 | 
					                self.as_dyn_int().type_properties_dyn()
 | 
				
			||||||
                    is_passive: true,
 | 
					 | 
				
			||||||
                    is_storable: true,
 | 
					 | 
				
			||||||
                    is_castable_from_bits: true,
 | 
					 | 
				
			||||||
                    bit_width: self.width(),
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            pub fn bits_from_bigint_wrapping(self, v: &BigInt) -> BitVec {
 | 
					            pub fn bits_from_bigint_wrapping(self, v: &BigInt) -> BitVec {
 | 
				
			||||||
                BoolOrIntType::bits_from_bigint_wrapping(self, v)
 | 
					                BoolOrIntType::bits_from_bigint_wrapping(self, v)
 | 
				
			||||||
| 
						 | 
					@ -624,12 +637,20 @@ macro_rules! impl_int {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        impl $name {
 | 
					        impl $name {
 | 
				
			||||||
            pub fn new_dyn(width: usize) -> Self {
 | 
					            pub const fn new_dyn(width: usize) -> Self {
 | 
				
			||||||
                Self { width }
 | 
					                Self { width }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            pub fn bits_to_bigint(bits: &BitSlice) -> BigInt {
 | 
					            pub fn bits_to_bigint(bits: &BitSlice) -> BigInt {
 | 
				
			||||||
                <Self as BoolOrIntType>::bits_to_bigint(bits)
 | 
					                <Self as BoolOrIntType>::bits_to_bigint(bits)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            pub const fn type_properties_dyn(self) -> TypeProperties {
 | 
				
			||||||
 | 
					                TypeProperties {
 | 
				
			||||||
 | 
					                    is_passive: true,
 | 
				
			||||||
 | 
					                    is_storable: true,
 | 
				
			||||||
 | 
					                    is_castable_from_bits: true,
 | 
				
			||||||
 | 
					                    bit_width: self.width,
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        impl<Width: KnownSize> $name<Width> {
 | 
					        impl<Width: KnownSize> $name<Width> {
 | 
				
			||||||
| 
						 | 
					@ -686,12 +707,10 @@ macro_rules! impl_int {
 | 
				
			||||||
        impl<Width: KnownSize> StaticType for $name<Width> {
 | 
					        impl<Width: KnownSize> StaticType for $name<Width> {
 | 
				
			||||||
            const TYPE: Self = Self { width: Width::SIZE };
 | 
					            const TYPE: Self = Self { width: Width::SIZE };
 | 
				
			||||||
            const MASK_TYPE: Self::MaskType = Bool;
 | 
					            const MASK_TYPE: Self::MaskType = Bool;
 | 
				
			||||||
            const TYPE_PROPERTIES: TypeProperties = TypeProperties {
 | 
					            const TYPE_PROPERTIES: TypeProperties = $name {
 | 
				
			||||||
                is_passive: true,
 | 
					                width: Width::VALUE,
 | 
				
			||||||
                is_storable: true,
 | 
					            }
 | 
				
			||||||
                is_castable_from_bits: true,
 | 
					            .type_properties_dyn();
 | 
				
			||||||
                bit_width: Width::VALUE,
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            const MASK_TYPE_PROPERTIES: TypeProperties = Bool::TYPE_PROPERTIES;
 | 
					            const MASK_TYPE_PROPERTIES: TypeProperties = Bool::TYPE_PROPERTIES;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -905,6 +924,10 @@ impl UInt {
 | 
				
			||||||
        let v: BigUint = v.into();
 | 
					        let v: BigUint = v.into();
 | 
				
			||||||
        Self::new(v.bits().try_into().expect("too big"))
 | 
					        Self::new(v.bits().try_into().expect("too big"))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    /// gets the smallest `UInt` that fits `v` losslessly
 | 
				
			||||||
 | 
					    pub const fn for_value_usize(v: usize) -> Self {
 | 
				
			||||||
 | 
					        Self::new(v.next_power_of_two().ilog2() as usize)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    /// gets the smallest `UInt` that fits `r` losslessly, panics if `r` is empty
 | 
					    /// gets the smallest `UInt` that fits `r` losslessly, panics if `r` is empty
 | 
				
			||||||
    #[track_caller]
 | 
					    #[track_caller]
 | 
				
			||||||
    pub fn range(r: Range<impl Into<BigUint>>) -> Self {
 | 
					    pub fn range(r: Range<impl Into<BigUint>>) -> Self {
 | 
				
			||||||
| 
						 | 
					@ -915,6 +938,12 @@ impl UInt {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /// gets the smallest `UInt` that fits `r` losslessly, panics if `r` is empty
 | 
					    /// gets the smallest `UInt` that fits `r` losslessly, panics if `r` is empty
 | 
				
			||||||
    #[track_caller]
 | 
					    #[track_caller]
 | 
				
			||||||
 | 
					    pub const fn range_usize(r: Range<usize>) -> Self {
 | 
				
			||||||
 | 
					        assert!(r.end != 0, "empty range");
 | 
				
			||||||
 | 
					        Self::range_inclusive_usize(r.start..=(r.end - 1))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /// gets the smallest `UInt` that fits `r` losslessly, panics if `r` is empty
 | 
				
			||||||
 | 
					    #[track_caller]
 | 
				
			||||||
    pub fn range_inclusive(r: RangeInclusive<impl Into<BigUint>>) -> Self {
 | 
					    pub fn range_inclusive(r: RangeInclusive<impl Into<BigUint>>) -> Self {
 | 
				
			||||||
        let (start, end) = r.into_inner();
 | 
					        let (start, end) = r.into_inner();
 | 
				
			||||||
        let start: BigUint = start.into();
 | 
					        let start: BigUint = start.into();
 | 
				
			||||||
| 
						 | 
					@ -924,6 +953,16 @@ impl UInt {
 | 
				
			||||||
        // so must not take more bits than `end`
 | 
					        // so must not take more bits than `end`
 | 
				
			||||||
        Self::for_value(end)
 | 
					        Self::for_value(end)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    /// gets the smallest `UInt` that fits `r` losslessly, panics if `r` is empty
 | 
				
			||||||
 | 
					    #[track_caller]
 | 
				
			||||||
 | 
					    pub const fn range_inclusive_usize(r: RangeInclusive<usize>) -> Self {
 | 
				
			||||||
 | 
					        let start = *r.start();
 | 
				
			||||||
 | 
					        let end = *r.end();
 | 
				
			||||||
 | 
					        assert!(start <= end, "empty range");
 | 
				
			||||||
 | 
					        // no need to check `start`` since it's no larger than `end`
 | 
				
			||||||
 | 
					        // so must not take more bits than `end`
 | 
				
			||||||
 | 
					        Self::for_value_usize(end)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl SInt {
 | 
					impl SInt {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										477
									
								
								crates/fayalite/src/int/uint_in_range.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										477
									
								
								crates/fayalite/src/int/uint_in_range.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,477 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: LGPL-3.0-or-later
 | 
				
			||||||
 | 
					// See Notices.txt for copyright information
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::{
 | 
				
			||||||
 | 
					    bundle::{Bundle, BundleField, BundleType, BundleTypePropertiesBuilder, NoBuilder},
 | 
				
			||||||
 | 
					    expr::{
 | 
				
			||||||
 | 
					        ops::{ExprCastTo, ExprPartialEq, ExprPartialOrd},
 | 
				
			||||||
 | 
					        CastBitsTo, CastTo, CastToBits, Expr, HdlPartialEq, HdlPartialOrd,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    int::{Bool, DynSize, KnownSize, Size, SizeType, UInt, UIntType},
 | 
				
			||||||
 | 
					    intern::{Intern, Interned},
 | 
				
			||||||
 | 
					    phantom_const::PhantomConst,
 | 
				
			||||||
 | 
					    sim::value::{SimValue, SimValuePartialEq, ToSimValueWithType},
 | 
				
			||||||
 | 
					    source_location::SourceLocation,
 | 
				
			||||||
 | 
					    ty::{impl_match_variant_as_self, CanonicalType, StaticType, Type, TypeProperties},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					use bitvec::{order::Lsb0, slice::BitSlice, view::BitView};
 | 
				
			||||||
 | 
					use std::{fmt, ops::Index};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const UINT_IN_RANGE_TYPE_FIELD_NAMES: [&'static str; 2] = ["value", "range"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)]
 | 
				
			||||||
 | 
					pub struct UIntInRangeMaskType {
 | 
				
			||||||
 | 
					    value: Bool,
 | 
				
			||||||
 | 
					    range: PhantomConstRangeMaskType,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Type for UIntInRangeMaskType {
 | 
				
			||||||
 | 
					    type BaseType = Bundle;
 | 
				
			||||||
 | 
					    type MaskType = Self;
 | 
				
			||||||
 | 
					    type SimValue = bool;
 | 
				
			||||||
 | 
					    impl_match_variant_as_self!();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn mask_type(&self) -> Self::MaskType {
 | 
				
			||||||
 | 
					        *self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn canonical(&self) -> CanonicalType {
 | 
				
			||||||
 | 
					        CanonicalType::Bundle(Bundle::new(self.fields()))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn from_canonical(canonical_type: CanonicalType) -> Self {
 | 
				
			||||||
 | 
					        let fields = Bundle::from_canonical(canonical_type).fields();
 | 
				
			||||||
 | 
					        let [BundleField {
 | 
				
			||||||
 | 
					            name: value_name,
 | 
				
			||||||
 | 
					            flipped: false,
 | 
				
			||||||
 | 
					            ty: value,
 | 
				
			||||||
 | 
					        }, BundleField {
 | 
				
			||||||
 | 
					            name: range_name,
 | 
				
			||||||
 | 
					            flipped: false,
 | 
				
			||||||
 | 
					            ty: range,
 | 
				
			||||||
 | 
					        }] = *fields
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            panic!("expected UIntInRangeMaskType");
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        assert_eq!([&*value_name, &*range_name], UINT_IN_RANGE_TYPE_FIELD_NAMES);
 | 
				
			||||||
 | 
					        let value = Bool::from_canonical(value);
 | 
				
			||||||
 | 
					        let range = PhantomConstRangeMaskType::from_canonical(range);
 | 
				
			||||||
 | 
					        Self { value, range }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn source_location() -> SourceLocation {
 | 
				
			||||||
 | 
					        SourceLocation::builtin()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue {
 | 
				
			||||||
 | 
					        Bool.sim_value_from_bits(bits)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice) {
 | 
				
			||||||
 | 
					        Bool.sim_value_clone_from_bits(value, bits);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice) {
 | 
				
			||||||
 | 
					        Bool.sim_value_to_bits(value, bits);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl BundleType for UIntInRangeMaskType {
 | 
				
			||||||
 | 
					    type Builder = NoBuilder;
 | 
				
			||||||
 | 
					    type FilledBuilder = Expr<UIntInRangeMaskType>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn fields(&self) -> Interned<[BundleField]> {
 | 
				
			||||||
 | 
					        let [value_name, range_name] = UINT_IN_RANGE_TYPE_FIELD_NAMES;
 | 
				
			||||||
 | 
					        let Self { value, range } = self;
 | 
				
			||||||
 | 
					        [
 | 
				
			||||||
 | 
					            BundleField {
 | 
				
			||||||
 | 
					                name: value_name.intern(),
 | 
				
			||||||
 | 
					                flipped: false,
 | 
				
			||||||
 | 
					                ty: value.canonical(),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            BundleField {
 | 
				
			||||||
 | 
					                name: range_name.intern(),
 | 
				
			||||||
 | 
					                flipped: false,
 | 
				
			||||||
 | 
					                ty: range.canonical(),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        ][..]
 | 
				
			||||||
 | 
					            .intern()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl StaticType for UIntInRangeMaskType {
 | 
				
			||||||
 | 
					    const TYPE: Self = Self {
 | 
				
			||||||
 | 
					        value: Bool,
 | 
				
			||||||
 | 
					        range: PhantomConstRangeMaskType::TYPE,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    const MASK_TYPE: Self::MaskType = Self::TYPE;
 | 
				
			||||||
 | 
					    const TYPE_PROPERTIES: TypeProperties = BundleTypePropertiesBuilder::new()
 | 
				
			||||||
 | 
					        .field(false, Bool::TYPE_PROPERTIES)
 | 
				
			||||||
 | 
					        .field(false, PhantomConstRangeMaskType::TYPE_PROPERTIES)
 | 
				
			||||||
 | 
					        .finish();
 | 
				
			||||||
 | 
					    const MASK_TYPE_PROPERTIES: TypeProperties = Self::TYPE_PROPERTIES;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl ToSimValueWithType<UIntInRangeMaskType> for bool {
 | 
				
			||||||
 | 
					    fn to_sim_value_with_type(&self, ty: UIntInRangeMaskType) -> SimValue<UIntInRangeMaskType> {
 | 
				
			||||||
 | 
					        SimValue::from_value(ty, *self)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl ExprCastTo<Bool> for UIntInRangeMaskType {
 | 
				
			||||||
 | 
					    fn cast_to(src: Expr<Self>, to_type: Bool) -> Expr<Bool> {
 | 
				
			||||||
 | 
					        src.cast_to_bits().cast_to(to_type)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl ExprCastTo<UIntInRangeMaskType> for Bool {
 | 
				
			||||||
 | 
					    fn cast_to(src: Expr<Self>, to_type: UIntInRangeMaskType) -> Expr<UIntInRangeMaskType> {
 | 
				
			||||||
 | 
					        src.cast_to_static::<UInt<1>>().cast_bits_to(to_type)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl ExprPartialEq<Self> for UIntInRangeMaskType {
 | 
				
			||||||
 | 
					    fn cmp_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
 | 
				
			||||||
 | 
					        lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    fn cmp_ne(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
 | 
				
			||||||
 | 
					        lhs.cast_to_bits().cmp_ne(rhs.cast_to_bits())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl SimValuePartialEq<Self> for UIntInRangeMaskType {
 | 
				
			||||||
 | 
					    fn sim_value_eq(this: &SimValue<Self>, other: &SimValue<Self>) -> bool {
 | 
				
			||||||
 | 
					        **this == **other
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type PhantomConstRange<Start = DynSize, End = DynSize> =
 | 
				
			||||||
 | 
					    PhantomConst<(<Start as Size>::SizeType, <End as Size>::SizeType)>;
 | 
				
			||||||
 | 
					type PhantomConstRangeMaskType = <PhantomConstRange as Type>::MaskType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					macro_rules! define_uint_in_range_type {
 | 
				
			||||||
 | 
					    (
 | 
				
			||||||
 | 
					        $UIntInRangeType:ident,
 | 
				
			||||||
 | 
					        $UIntInRangeTypeWithoutGenerics:ident,
 | 
				
			||||||
 | 
					        $UIntInRangeTypeWithStart:ident,
 | 
				
			||||||
 | 
					        |$uint_range_usize_start:ident, $uint_range_usize_end:ident| $uint_range_usize:expr,
 | 
				
			||||||
 | 
					    ) => {
 | 
				
			||||||
 | 
					        #[derive(Copy, Clone, PartialEq, Eq, Hash)]
 | 
				
			||||||
 | 
					        pub struct $UIntInRangeType<Start: Size, End: Size> {
 | 
				
			||||||
 | 
					            value: UInt,
 | 
				
			||||||
 | 
					            range: PhantomConstRange<Start, End>,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<Start: Size, End: Size> $UIntInRangeType<Start, End> {
 | 
				
			||||||
 | 
					            fn from_phantom_const_range(range: PhantomConstRange<Start, End>) -> Self {
 | 
				
			||||||
 | 
					                let (start, end) = *range.get();
 | 
				
			||||||
 | 
					                let $uint_range_usize_start = Start::as_usize(start);
 | 
				
			||||||
 | 
					                let $uint_range_usize_end = End::as_usize(end);
 | 
				
			||||||
 | 
					                Self {
 | 
				
			||||||
 | 
					                    value: $uint_range_usize,
 | 
				
			||||||
 | 
					                    range,
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            pub fn new(start: Start::SizeType, end: End::SizeType) -> Self {
 | 
				
			||||||
 | 
					                Self::from_phantom_const_range(PhantomConst::new((start, end).intern_sized()))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<Start: Size, End: Size> fmt::Debug for $UIntInRangeType<Start, End> {
 | 
				
			||||||
 | 
					            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
				
			||||||
 | 
					                let Self { value, range } = self;
 | 
				
			||||||
 | 
					                let (start, end) = *range.get();
 | 
				
			||||||
 | 
					                f.debug_struct(&format!(
 | 
				
			||||||
 | 
					                    "UIntInRange<{}, {}>",
 | 
				
			||||||
 | 
					                    Start::as_usize(start),
 | 
				
			||||||
 | 
					                    End::as_usize(end),
 | 
				
			||||||
 | 
					                ))
 | 
				
			||||||
 | 
					                .field("value", value)
 | 
				
			||||||
 | 
					                .finish_non_exhaustive()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<Start: Size, End: Size> Type for $UIntInRangeType<Start, End> {
 | 
				
			||||||
 | 
					            type BaseType = Bundle;
 | 
				
			||||||
 | 
					            type MaskType = UIntInRangeMaskType;
 | 
				
			||||||
 | 
					            type SimValue = usize;
 | 
				
			||||||
 | 
					            impl_match_variant_as_self!();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fn mask_type(&self) -> Self::MaskType {
 | 
				
			||||||
 | 
					                UIntInRangeMaskType::TYPE
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fn canonical(&self) -> CanonicalType {
 | 
				
			||||||
 | 
					                CanonicalType::Bundle(Bundle::new(self.fields()))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fn from_canonical(canonical_type: CanonicalType) -> Self {
 | 
				
			||||||
 | 
					                let fields = Bundle::from_canonical(canonical_type).fields();
 | 
				
			||||||
 | 
					                let [BundleField {
 | 
				
			||||||
 | 
					                    name: value_name,
 | 
				
			||||||
 | 
					                    flipped: false,
 | 
				
			||||||
 | 
					                    ty: value,
 | 
				
			||||||
 | 
					                }, BundleField {
 | 
				
			||||||
 | 
					                    name: range_name,
 | 
				
			||||||
 | 
					                    flipped: false,
 | 
				
			||||||
 | 
					                    ty: range,
 | 
				
			||||||
 | 
					                }] = *fields
 | 
				
			||||||
 | 
					                else {
 | 
				
			||||||
 | 
					                    panic!("expected UIntInRange");
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                assert_eq!([&*value_name, &*range_name], UINT_IN_RANGE_TYPE_FIELD_NAMES);
 | 
				
			||||||
 | 
					                let value = UInt::from_canonical(value);
 | 
				
			||||||
 | 
					                let range = PhantomConstRange::<Start, End>::from_canonical(range);
 | 
				
			||||||
 | 
					                let retval = Self::from_phantom_const_range(range);
 | 
				
			||||||
 | 
					                assert_eq!(retval, Self { value, range });
 | 
				
			||||||
 | 
					                retval
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fn source_location() -> SourceLocation {
 | 
				
			||||||
 | 
					                SourceLocation::builtin()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fn sim_value_from_bits(&self, bits: &BitSlice) -> Self::SimValue {
 | 
				
			||||||
 | 
					                let mut retval = 0usize;
 | 
				
			||||||
 | 
					                retval.view_bits_mut::<Lsb0>()[..bits.len()].clone_from_bitslice(bits);
 | 
				
			||||||
 | 
					                retval
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fn sim_value_clone_from_bits(&self, value: &mut Self::SimValue, bits: &BitSlice) {
 | 
				
			||||||
 | 
					                *value = self.sim_value_from_bits(bits);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fn sim_value_to_bits(&self, value: &Self::SimValue, bits: &mut BitSlice) {
 | 
				
			||||||
 | 
					                bits.clone_from_bitslice(&value.view_bits::<Lsb0>()[..bits.len()]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<Start: Size, End: Size> BundleType for $UIntInRangeType<Start, End> {
 | 
				
			||||||
 | 
					            type Builder = NoBuilder;
 | 
				
			||||||
 | 
					            type FilledBuilder = Expr<Self>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fn fields(&self) -> Interned<[BundleField]> {
 | 
				
			||||||
 | 
					                let [value_name, range_name] = UINT_IN_RANGE_TYPE_FIELD_NAMES;
 | 
				
			||||||
 | 
					                let Self { value, range } = self;
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    BundleField {
 | 
				
			||||||
 | 
					                        name: value_name.intern(),
 | 
				
			||||||
 | 
					                        flipped: false,
 | 
				
			||||||
 | 
					                        ty: value.canonical(),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    BundleField {
 | 
				
			||||||
 | 
					                        name: range_name.intern(),
 | 
				
			||||||
 | 
					                        flipped: false,
 | 
				
			||||||
 | 
					                        ty: range.canonical(),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                ][..]
 | 
				
			||||||
 | 
					                    .intern()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<Start: KnownSize, End: KnownSize> Default for $UIntInRangeType<Start, End> {
 | 
				
			||||||
 | 
					            fn default() -> Self {
 | 
				
			||||||
 | 
					                Self::TYPE
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<Start: KnownSize, End: KnownSize> StaticType for $UIntInRangeType<Start, End> {
 | 
				
			||||||
 | 
					            const TYPE: Self = {
 | 
				
			||||||
 | 
					                let $uint_range_usize_start = Start::VALUE;
 | 
				
			||||||
 | 
					                let $uint_range_usize_end = End::VALUE;
 | 
				
			||||||
 | 
					                Self {
 | 
				
			||||||
 | 
					                    value: $uint_range_usize,
 | 
				
			||||||
 | 
					                    range: PhantomConstRange::<Start, End>::TYPE,
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            const MASK_TYPE: Self::MaskType = UIntInRangeMaskType::TYPE;
 | 
				
			||||||
 | 
					            const TYPE_PROPERTIES: TypeProperties = BundleTypePropertiesBuilder::new()
 | 
				
			||||||
 | 
					                .field(false, Self::TYPE.value.type_properties_dyn())
 | 
				
			||||||
 | 
					                .field(false, PhantomConstRange::<Start, End>::TYPE_PROPERTIES)
 | 
				
			||||||
 | 
					                .finish();
 | 
				
			||||||
 | 
					            const MASK_TYPE_PROPERTIES: TypeProperties = UIntInRangeMaskType::TYPE_PROPERTIES;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<Start: Size, End: Size> ToSimValueWithType<$UIntInRangeType<Start, End>> for usize {
 | 
				
			||||||
 | 
					            fn to_sim_value_with_type(
 | 
				
			||||||
 | 
					                &self,
 | 
				
			||||||
 | 
					                ty: $UIntInRangeType<Start, End>,
 | 
				
			||||||
 | 
					            ) -> SimValue<$UIntInRangeType<Start, End>> {
 | 
				
			||||||
 | 
					                SimValue::from_value(ty, *self)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)]
 | 
				
			||||||
 | 
					        pub struct $UIntInRangeTypeWithoutGenerics;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[allow(non_upper_case_globals)]
 | 
				
			||||||
 | 
					        pub const $UIntInRangeType: $UIntInRangeTypeWithoutGenerics =
 | 
				
			||||||
 | 
					            $UIntInRangeTypeWithoutGenerics;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<StartSize: SizeType> Index<StartSize> for $UIntInRangeTypeWithoutGenerics {
 | 
				
			||||||
 | 
					            type Output = $UIntInRangeTypeWithStart<StartSize::Size>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fn index(&self, start: StartSize) -> &Self::Output {
 | 
				
			||||||
 | 
					                Interned::into_inner($UIntInRangeTypeWithStart(start).intern_sized())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 | 
				
			||||||
 | 
					        pub struct $UIntInRangeTypeWithStart<Start: Size>(Start::SizeType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<Start: Size, EndSize: SizeType<Size = End>, End: Size<SizeType = EndSize>>
 | 
				
			||||||
 | 
					            Index<EndSize> for $UIntInRangeTypeWithStart<Start>
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            type Output = $UIntInRangeType<Start, End>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fn index(&self, end: EndSize) -> &Self::Output {
 | 
				
			||||||
 | 
					                Interned::into_inner($UIntInRangeType::new(self.0, end).intern_sized())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<Start: Size, End: Size> ExprCastTo<UInt> for $UIntInRangeType<Start, End> {
 | 
				
			||||||
 | 
					            fn cast_to(src: Expr<Self>, to_type: UInt) -> Expr<UInt> {
 | 
				
			||||||
 | 
					                src.cast_to_bits().cast_to(to_type)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<Start: Size, End: Size> ExprCastTo<$UIntInRangeType<Start, End>> for UInt {
 | 
				
			||||||
 | 
					            fn cast_to(
 | 
				
			||||||
 | 
					                src: Expr<Self>,
 | 
				
			||||||
 | 
					                to_type: $UIntInRangeType<Start, End>,
 | 
				
			||||||
 | 
					            ) -> Expr<$UIntInRangeType<Start, End>> {
 | 
				
			||||||
 | 
					                src.cast_bits_to(to_type)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<LhsStart: Size, LhsEnd: Size, RhsStart: Size, RhsEnd: Size>
 | 
				
			||||||
 | 
					            ExprPartialEq<$UIntInRangeType<RhsStart, RhsEnd>>
 | 
				
			||||||
 | 
					            for $UIntInRangeType<LhsStart, LhsEnd>
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fn cmp_eq(
 | 
				
			||||||
 | 
					                lhs: Expr<Self>,
 | 
				
			||||||
 | 
					                rhs: Expr<$UIntInRangeType<RhsStart, RhsEnd>>,
 | 
				
			||||||
 | 
					            ) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            fn cmp_ne(
 | 
				
			||||||
 | 
					                lhs: Expr<Self>,
 | 
				
			||||||
 | 
					                rhs: Expr<$UIntInRangeType<RhsStart, RhsEnd>>,
 | 
				
			||||||
 | 
					            ) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cast_to_bits().cmp_ne(rhs.cast_to_bits())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<LhsStart: Size, LhsEnd: Size, RhsStart: Size, RhsEnd: Size>
 | 
				
			||||||
 | 
					            ExprPartialOrd<$UIntInRangeType<RhsStart, RhsEnd>>
 | 
				
			||||||
 | 
					            for $UIntInRangeType<LhsStart, LhsEnd>
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fn cmp_lt(
 | 
				
			||||||
 | 
					                lhs: Expr<Self>,
 | 
				
			||||||
 | 
					                rhs: Expr<$UIntInRangeType<RhsStart, RhsEnd>>,
 | 
				
			||||||
 | 
					            ) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cast_to_bits().cmp_lt(rhs.cast_to_bits())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            fn cmp_le(
 | 
				
			||||||
 | 
					                lhs: Expr<Self>,
 | 
				
			||||||
 | 
					                rhs: Expr<$UIntInRangeType<RhsStart, RhsEnd>>,
 | 
				
			||||||
 | 
					            ) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cast_to_bits().cmp_le(rhs.cast_to_bits())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            fn cmp_gt(
 | 
				
			||||||
 | 
					                lhs: Expr<Self>,
 | 
				
			||||||
 | 
					                rhs: Expr<$UIntInRangeType<RhsStart, RhsEnd>>,
 | 
				
			||||||
 | 
					            ) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cast_to_bits().cmp_gt(rhs.cast_to_bits())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            fn cmp_ge(
 | 
				
			||||||
 | 
					                lhs: Expr<Self>,
 | 
				
			||||||
 | 
					                rhs: Expr<$UIntInRangeType<RhsStart, RhsEnd>>,
 | 
				
			||||||
 | 
					            ) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cast_to_bits().cmp_ge(rhs.cast_to_bits())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<LhsStart: Size, LhsEnd: Size, RhsStart: Size, RhsEnd: Size>
 | 
				
			||||||
 | 
					            SimValuePartialEq<$UIntInRangeType<RhsStart, RhsEnd>>
 | 
				
			||||||
 | 
					            for $UIntInRangeType<LhsStart, LhsEnd>
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fn sim_value_eq(
 | 
				
			||||||
 | 
					                this: &SimValue<Self>,
 | 
				
			||||||
 | 
					                other: &SimValue<$UIntInRangeType<RhsStart, RhsEnd>>,
 | 
				
			||||||
 | 
					            ) -> bool {
 | 
				
			||||||
 | 
					                **this == **other
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<Start: Size, End: Size, Width: Size> ExprPartialEq<UIntType<Width>>
 | 
				
			||||||
 | 
					            for $UIntInRangeType<Start, End>
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fn cmp_eq(lhs: Expr<Self>, rhs: Expr<UIntType<Width>>) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cast_to_bits().cmp_eq(rhs)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            fn cmp_ne(lhs: Expr<Self>, rhs: Expr<UIntType<Width>>) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cast_to_bits().cmp_ne(rhs)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<Start: Size, End: Size, Width: Size> ExprPartialEq<$UIntInRangeType<Start, End>>
 | 
				
			||||||
 | 
					            for UIntType<Width>
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fn cmp_eq(lhs: Expr<Self>, rhs: Expr<$UIntInRangeType<Start, End>>) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cmp_eq(rhs.cast_to_bits())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            fn cmp_ne(lhs: Expr<Self>, rhs: Expr<$UIntInRangeType<Start, End>>) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cmp_ne(rhs.cast_to_bits())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<Start: Size, End: Size, Width: Size> ExprPartialOrd<UIntType<Width>>
 | 
				
			||||||
 | 
					            for $UIntInRangeType<Start, End>
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fn cmp_lt(lhs: Expr<Self>, rhs: Expr<UIntType<Width>>) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cast_to_bits().cmp_lt(rhs)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            fn cmp_le(lhs: Expr<Self>, rhs: Expr<UIntType<Width>>) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cast_to_bits().cmp_le(rhs)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            fn cmp_gt(lhs: Expr<Self>, rhs: Expr<UIntType<Width>>) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cast_to_bits().cmp_gt(rhs)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            fn cmp_ge(lhs: Expr<Self>, rhs: Expr<UIntType<Width>>) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cast_to_bits().cmp_ge(rhs)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<Start: Size, End: Size, Width: Size> ExprPartialOrd<$UIntInRangeType<Start, End>>
 | 
				
			||||||
 | 
					            for UIntType<Width>
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fn cmp_lt(lhs: Expr<Self>, rhs: Expr<$UIntInRangeType<Start, End>>) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cmp_lt(rhs.cast_to_bits())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            fn cmp_le(lhs: Expr<Self>, rhs: Expr<$UIntInRangeType<Start, End>>) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cmp_le(rhs.cast_to_bits())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            fn cmp_gt(lhs: Expr<Self>, rhs: Expr<$UIntInRangeType<Start, End>>) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cmp_gt(rhs.cast_to_bits())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            fn cmp_ge(lhs: Expr<Self>, rhs: Expr<$UIntInRangeType<Start, End>>) -> Expr<Bool> {
 | 
				
			||||||
 | 
					                lhs.cmp_ge(rhs.cast_to_bits())
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					define_uint_in_range_type! {
 | 
				
			||||||
 | 
					    UIntInRangeType,
 | 
				
			||||||
 | 
					    UIntInRangeTypeWithoutGenerics,
 | 
				
			||||||
 | 
					    UIntInRangeTypeWithStart,
 | 
				
			||||||
 | 
					    |start, end| UInt::range_usize(start..end),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					define_uint_in_range_type! {
 | 
				
			||||||
 | 
					    UIntInRangeInclusiveType,
 | 
				
			||||||
 | 
					    UIntInRangeInclusiveTypeWithoutGenerics,
 | 
				
			||||||
 | 
					    UIntInRangeInclusiveTypeWithStart,
 | 
				
			||||||
 | 
					    |start, end| UInt::range_inclusive_usize(start..=end),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,7 @@ use crate::{
 | 
				
			||||||
        Expr, ToExpr,
 | 
					        Expr, ToExpr,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    int::Bool,
 | 
					    int::Bool,
 | 
				
			||||||
    intern::{Intern, Interned, InternedCompare, LazyInterned, Memoize},
 | 
					    intern::{Intern, Interned, InternedCompare, LazyInterned, LazyInternedTrait, Memoize},
 | 
				
			||||||
    sim::value::{SimValue, SimValuePartialEq, ToSimValue, ToSimValueWithType},
 | 
					    sim::value::{SimValue, SimValuePartialEq, ToSimValue, ToSimValueWithType},
 | 
				
			||||||
    source_location::SourceLocation,
 | 
					    source_location::SourceLocation,
 | 
				
			||||||
    ty::{
 | 
					    ty::{
 | 
				
			||||||
| 
						 | 
					@ -228,6 +228,11 @@ impl<T: ?Sized + PhantomConstValue> PhantomConst<T> {
 | 
				
			||||||
            value: LazyInterned::Interned(value),
 | 
					            value: LazyInterned::Interned(value),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    pub const fn new_lazy(v: &'static dyn LazyInternedTrait<T>) -> Self {
 | 
				
			||||||
 | 
					        Self {
 | 
				
			||||||
 | 
					            value: LazyInterned::new_lazy(v),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    pub fn get(self) -> Interned<T> {
 | 
					    pub fn get(self) -> Interned<T> {
 | 
				
			||||||
        self.value.interned()
 | 
					        self.value.interned()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue