Make newtype_index methods const

This commit is contained in:
Dylan MacKenzie 2020-03-10 13:44:40 -07:00
parent 59f4ba9504
commit 429b16e907

View file

@ -120,10 +120,10 @@ macro_rules! newtype_index {
impl $type {
$v const MAX_AS_U32: u32 = $max;
$v const MAX: Self = Self::from_u32_const($max);
$v const MAX: Self = Self::from_u32($max);
#[inline]
$v fn from_usize(value: usize) -> Self {
$v const fn from_usize(value: usize) -> Self {
assert!(value <= ($max as usize));
unsafe {
Self::from_u32_unchecked(value as u32)
@ -131,31 +131,13 @@ macro_rules! newtype_index {
}
#[inline]
$v fn from_u32(value: u32) -> Self {
$v const fn from_u32(value: u32) -> Self {
assert!(value <= $max);
unsafe {
Self::from_u32_unchecked(value)
}
}
/// Hacky variant of `from_u32` for use in constants.
/// This version checks the "max" constraint by using an
/// invalid array dereference.
#[inline]
$v const fn from_u32_const(value: u32) -> Self {
// This will fail at const eval time unless `value <=
// max` is true (in which case we get the index 0).
// It will also fail at runtime, of course, but in a
// kind of wacky way.
let _ = ["out of range value used"][
!(value <= $max) as usize
];
unsafe {
Self { private: value }
}
}
#[inline]
$v const unsafe fn from_u32_unchecked(value: u32) -> Self {
Self { private: value }
@ -163,19 +145,19 @@ macro_rules! newtype_index {
/// Extracts the value of this index as an integer.
#[inline]
$v fn index(self) -> usize {
$v const fn index(self) -> usize {
self.as_usize()
}
/// Extracts the value of this index as a `u32`.
#[inline]
$v fn as_u32(self) -> u32 {
$v const fn as_u32(self) -> u32 {
self.private
}
/// Extracts the value of this index as a `usize`.
#[inline]
$v fn as_usize(self) -> usize {
$v const fn as_usize(self) -> usize {
self.as_u32() as usize
}
}