use core::hint;
#[inline(always)]
pub unsafe fn unwrap_unchecked<T>(option: Option<T>) -> T {
match option {
Some(val) => val,
None => hint::unreachable_unchecked(),
}
}
#[derive(Clone)]
pub struct InplaceUpdatable<T> {
inner: Option<T>,
}
impl<T> InplaceUpdatable<T> {
#[inline(always)]
pub const fn new(value: T) -> InplaceUpdatable<T> {
InplaceUpdatable { inner: Some(value) }
}
#[inline(always)]
pub fn update(&mut self, updater: impl FnOnce(T) -> T) {
let new_val = updater(unsafe { unwrap_unchecked(self.inner.take()) });
self.inner = Some(new_val);
}
#[inline(always)]
pub fn update_with_result<R>(&mut self, updater: impl FnOnce(T) -> (T, R)) -> R {
let (new_val, r) = updater(unsafe { unwrap_unchecked(self.inner.take()) });
self.inner = Some(new_val);
r
}
#[inline(always)]
pub fn inplace_reduce(&mut self, right_value: T, reducer: impl FnOnce(T, T) -> T) {
let new_val = reducer(unsafe { unwrap_unchecked(self.inner.take()) }, right_value);
self.inner = Some(new_val);
}
#[inline(always)]
pub fn get_inner(self) -> T {
unsafe { unwrap_unchecked(self.inner) }
}
}
#[inline(always)]
pub fn set_some<T>(option: &mut Option<T>, value: T) -> &mut T {
*option = Some(value);
unsafe { unwrap_unchecked(option.as_mut()) }
}