Skip to content

Commit

Permalink
Added Once::get_mut_unchecked and Once::into_inner_unchecked (#137)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericmcbride committed Feb 16, 2023
1 parent 5087c8d commit 4318cc9
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/once.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,23 @@ impl<T, R> Once<T, R> {
_ => None,
}
}

/// Returns a mutable reference to the inner value
///
/// # Safety
///
/// This is *extremely* unsafe if the `Once` has not already been initialized because a reference to uninitialized
/// memory will be returned, immediately triggering undefined behaviour (even if the reference goes unused).
/// However, this can be useful in some instances for exposing the `Once` to FFI or when the overhead of atomically
/// checking initialization is unacceptable and the `Once` has already been initialized.
pub unsafe fn get_mut_unchecked(&mut self) -> &mut T {
debug_assert_eq!(
self.status.load(Ordering::SeqCst),
Status::Complete,
"Attempted to access an unintialized Once. If this was to run without debug checks, this would be undefined behavior. This is a serious bug and you must fix it.",
);
self.force_get_mut()
}

/// Returns a the inner value if the [`Once`] has been initialized.
///
Expand All @@ -466,6 +483,22 @@ impl<T, R> Once<T, R> {
}
}

/// Returns a the inner value if the [`Once`] has been initialized.
/// # Safety
///
/// This is *extremely* unsafe if the `Once` has not already been initialized because a reference to uninitialized
/// memory will be returned, immediately triggering undefined behaviour (even if the reference goes unused)
/// This can be useful, if `Once` has already been initialized, and you want to bypass an
/// option check.
pub unsafe fn into_inner_unchecked(self) -> T {
debug_assert_eq!(
self.status.load(Ordering::SeqCst),
Status::Complete,
"Attempted to access an unintialized Once. If this was to run without debug checks, this would be undefined behavior. This is a serious bug and you must fix it.",
);
self.force_into_inner()
}

/// Checks whether the value has been initialized.
///
/// This is done using [`Acquire`](core::sync::atomic::Ordering::Acquire) ordering, and
Expand Down

0 comments on commit 4318cc9

Please sign in to comment.