#[macro_export]
macro_rules! ensure_eof {
($input:ident) => {
if $input.is_empty() {
Ok(())
} else {
Err(syn::Error::new($input.span(), "Unexpected token."))
}
};
}
#[macro_export]
macro_rules! combine_results {
($($result:expr),*$(,)?) => {
{
let mut final_result: syn::Result<()> = Ok(());
$(
if let Err(err) = $result {
if let Err(ref mut final_result) = final_result {
final_result.combine(err);
} else {
final_result = Err(err);
}
}
)*
final_result
}
};
}
#[macro_export]
macro_rules! const_binary_search_fn {
(Ok($result:expr) for Result) => {
Ok($result)
};
(Ok($result:expr) for Option) => {
Some($result)
};
(Ok($result:expr) for usize) => {
$result
};
(Err($lo:expr) for Result) => {
Err($lo)
};
(Err($lo:expr) for Option) => {
None
};
(Err($lo:expr) for usize) => {
$lo
};
(Err($lo:expr) for usize panic) => {
panic!("Not found.")
};
(return type for Result) => { ::core::result::Result<usize, usize> };
(return type for Option) => { ::core::option::Option<usize> };
(return type for usize) => { usize };
(@reffed ref $expr:expr) => { &$expr };
(@reffed static $expr:expr) => { $expr };
(@reffed_ty ref $type:ty) => { &$type };
(@reffed_ty static $type:ty) => { $type };
(
use $cmp:path;
$(
#[$attr:meta]
)*
$vis:vis const fn $name:ident(
$search_ref:ident $search_ty:ty,
$item_ref:ident $item_ty:ty
$(, $context_name:ident: $ctx_ty:ty)?$(,)?
) -> $ret:ident $($not_found:ident!)?
) => {
$(
#[$attr]
)*
$vis const fn $name(
find: $crate::const_binary_search_fn!(@reffed_ty $search_ref $search_ty),
sorted: &[$item_ty],
$($context_name: $ctx_ty,)?
) -> $crate::const_binary_search_fn!(return type for $ret) {
let mut lo = 0usize;
let mut hi = sorted.len();
while lo < hi {
let mid = (hi - lo) / 2 + lo;
match $cmp(
find,
$crate::const_binary_search_fn!(@reffed $item_ref sorted[mid]),
$($context_name)?
) {
::core::cmp::Ordering::Less => hi = mid,
::core::cmp::Ordering::Equal => return $crate::const_binary_search_fn!(Ok(mid) for $ret),
::core::cmp::Ordering::Greater => lo = mid + 1,
}
}
$crate::const_binary_search_fn!(Err(lo) for $ret $($not_found)?)
}
};
}