/// Division of integers, rounding the resulting value towards negative infinity.
macro_rules! div_floor {
($a:expr, $b:expr) => {{ let _a = $a; let _b = $b;
// Cascade an out-of-bounds value from "from" to "to".
($from:ident in $min:literal.. $max:expr => $to:tt) => { #[allow(unused_comparisons, unused_assignments)] let min = $min; let max = $max; if $from >= max {
$from -= max - min;
$to += 1;
} elseif $from < min {
$from += max - min;
$to -= 1;
}
};
// Special case the ordinal-to-year cascade, as it has different behavior.
($ordinal:ident => $year:ident) => { // We need to actually capture the idents. Without this, macro hygiene causes errors.
cascade!(@ordinal $ordinal);
cascade!(@year $year); #[allow(unused_assignments)] if $ordinal > crate::util::days_in_year($year) as i16 {
$ordinal -= crate::util::days_in_year($year) as i16;
$year += 1;
} elseif $ordinal < 1 {
$year -= 1;
$ordinal += crate::util::days_in_year($year) as i16;
}
};
}
/// Constructs a ranged integer, returning a `ComponentRange` error if the value is out of range.
macro_rules! ensure_ranged {
($type:ident : $value:ident) => { match $type::new($value) {
Some(val) => val,
None => { #[allow(trivial_numeric_casts)] return Err(crate::error::ComponentRange {
name: stringify!($value),
minimum: $type::MIN.get() as _,
maximum: $type::MAX.get() as _,
value: $value as _,
conditional_range: false,
});
}
}
};
($type:ident : $value:ident $(as $as_type:ident)? * $factor:expr) => { match ($value $(as $as_type)?).checked_mul($factor) {
Some(val) => match $type::new(val) {
Some(val) => val,
None => { #[allow(trivial_numeric_casts)] return Err(crate::error::ComponentRange {
name: stringify!($value),
minimum: $type::MIN.get() as i64 / $factor as i64,
maximum: $type::MAX.get() as i64 / $factor as i64,
value: $value as _,
conditional_range: false,
});
}
},
None => { return Err(crate::error::ComponentRange {
name: stringify!($value),
minimum: $type::MIN.get() as i64 / $factor as i64,
maximum: $type::MAX.get() as i64 / $factor as i64,
value: $value as _,
conditional_range: false,
});
}
}
};
}
/// Try to unwrap an expression, returning if not possible. /// /// This is similar to the `?` operator, but does not perform `.into()`. Because of this, it is /// usable in `const` contexts.
macro_rules! const_try {
($e:expr) => { match $e {
Ok(value) => value,
Err(error) => return Err(error),
}
};
}
/// Try to unwrap an expression, returning if not possible. /// /// This is similar to the `?` operator, but is usable in `const` contexts.
macro_rules! const_try_opt {
($e:expr) => { match $e {
Some(value) => value,
None => return None,
}
};
}
/// Try to unwrap an expression, panicking if not possible. /// /// This is similar to `$e.expect($message)`, but is usable in `const` contexts.
macro_rules! expect_opt {
($e:expr, $message:literal) => { match $e {
Some(value) => value,
None => crate::expect_failed($message),
}
};
}
/// `unreachable!()`, but better. #[cfg(any(feature = "formatting", feature = "parsing"))]
macro_rules! bug {
() => { compile_error!("provide an error message to help fix a possible bug") };
($descr:literal $($rest:tt)?) => {
panic!(concat!("internal error: ", $descr) $($rest)?)
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.