aboutsummaryrefslogtreecommitdiff
path: root/vendor/scopeguard/src/lib.rs
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2024-07-19 15:37:58 +0300
committerValentin Popov <valentin@popov.link>2024-07-19 15:37:58 +0300
commita990de90fe41456a23e58bd087d2f107d321f3a1 (patch)
tree15afc392522a9e85dc3332235e311b7d39352ea9 /vendor/scopeguard/src/lib.rs
parent3d48cd3f81164bbfc1a755dc1d4a9a02f98c8ddd (diff)
downloadfparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.tar.xz
fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.zip
Deleted vendor folder
Diffstat (limited to 'vendor/scopeguard/src/lib.rs')
-rw-r--r--vendor/scopeguard/src/lib.rs595
1 files changed, 0 insertions, 595 deletions
diff --git a/vendor/scopeguard/src/lib.rs b/vendor/scopeguard/src/lib.rs
deleted file mode 100644
index b5522c7..0000000
--- a/vendor/scopeguard/src/lib.rs
+++ /dev/null
@@ -1,595 +0,0 @@
-#![cfg_attr(not(any(test, feature = "use_std")), no_std)]
-#![doc(html_root_url = "https://docs.rs/scopeguard/1/")]
-
-//! A scope guard will run a given closure when it goes out of scope,
-//! even if the code between panics.
-//! (as long as panic doesn't abort)
-//!
-//! # Examples
-//!
-//! ## Hello World
-//!
-//! This example creates a scope guard with an example function:
-//!
-//! ```
-//! extern crate scopeguard;
-//!
-//! fn f() {
-//! let _guard = scopeguard::guard((), |_| {
-//! println!("Hello Scope Exit!");
-//! });
-//!
-//! // rest of the code here.
-//!
-//! // Here, at the end of `_guard`'s scope, the guard's closure is called.
-//! // It is also called if we exit this scope through unwinding instead.
-//! }
-//! # fn main() {
-//! # f();
-//! # }
-//! ```
-//!
-//! ## `defer!`
-//!
-//! Use the `defer` macro to run an operation at scope exit,
-//! either regular scope exit or during unwinding from a panic.
-//!
-//! ```
-//! #[macro_use(defer)] extern crate scopeguard;
-//!
-//! use std::cell::Cell;
-//!
-//! fn main() {
-//! // use a cell to observe drops during and after the scope guard is active
-//! let drop_counter = Cell::new(0);
-//! {
-//! // Create a scope guard using `defer!` for the current scope
-//! defer! {
-//! drop_counter.set(1 + drop_counter.get());
-//! }
-//!
-//! // Do regular operations here in the meantime.
-//!
-//! // Just before scope exit: it hasn't run yet.
-//! assert_eq!(drop_counter.get(), 0);
-//!
-//! // The following scope end is where the defer closure is called
-//! }
-//! assert_eq!(drop_counter.get(), 1);
-//! }
-//! ```
-//!
-//! ## Scope Guard with Value
-//!
-//! If the scope guard closure needs to access an outer value that is also
-//! mutated outside of the scope guard, then you may want to use the scope guard
-//! with a value. The guard works like a smart pointer, so the inner value can
-//! be accessed by reference or by mutable reference.
-//!
-//! ### 1. The guard owns a file
-//!
-//! In this example, the scope guard owns a file and ensures pending writes are
-//! synced at scope exit.
-//!
-//! ```
-//! extern crate scopeguard;
-//!
-//! use std::fs::*;
-//! use std::io::{self, Write};
-//! # // Mock file so that we don't actually write a file
-//! # struct MockFile;
-//! # impl MockFile {
-//! # fn create(_s: &str) -> io::Result<Self> { Ok(MockFile) }
-//! # fn write_all(&self, _b: &[u8]) -> io::Result<()> { Ok(()) }
-//! # fn sync_all(&self) -> io::Result<()> { Ok(()) }
-//! # }
-//! # use self::MockFile as File;
-//!
-//! fn try_main() -> io::Result<()> {
-//! let f = File::create("newfile.txt")?;
-//! let mut file = scopeguard::guard(f, |f| {
-//! // ensure we flush file at return or panic
-//! let _ = f.sync_all();
-//! });
-//! // Access the file through the scope guard itself
-//! file.write_all(b"test me\n").map(|_| ())
-//! }
-//!
-//! fn main() {
-//! try_main().unwrap();
-//! }
-//!
-//! ```
-//!
-//! ### 2. The guard restores an invariant on scope exit
-//!
-//! ```
-//! extern crate scopeguard;
-//!
-//! use std::mem::ManuallyDrop;
-//! use std::ptr;
-//!
-//! // This function, just for this example, takes the first element
-//! // and inserts it into the assumed sorted tail of the vector.
-//! //
-//! // For optimization purposes we temporarily violate an invariant of the
-//! // Vec, that it owns all of its elements.
-//! //
-//! // The safe approach is to use swap, which means two writes to memory,
-//! // the optimization is to use a “hole” which uses only one write of memory
-//! // for each position it moves.
-//! //
-//! // We *must* use a scope guard to run this code safely. We
-//! // are running arbitrary user code (comparison operators) that may panic.
-//! // The scope guard ensures we restore the invariant after successful
-//! // exit or during unwinding from panic.
-//! fn insertion_sort_first<T>(v: &mut Vec<T>)
-//! where T: PartialOrd
-//! {
-//! struct Hole<'a, T: 'a> {
-//! v: &'a mut Vec<T>,
-//! index: usize,
-//! value: ManuallyDrop<T>,
-//! }
-//!
-//! unsafe {
-//! // Create a moved-from location in the vector, a “hole”.
-//! let value = ptr::read(&v[0]);
-//! let mut hole = Hole { v: v, index: 0, value: ManuallyDrop::new(value) };
-//!
-//! // Use a scope guard with a value.
-//! // At scope exit, plug the hole so that the vector is fully
-//! // initialized again.
-//! // The scope guard owns the hole, but we can access it through the guard.
-//! let mut hole_guard = scopeguard::guard(hole, |hole| {
-//! // plug the hole in the vector with the value that was // taken out
-//! let index = hole.index;
-//! ptr::copy_nonoverlapping(&*hole.value, &mut hole.v[index], 1);
-//! });
-//!
-//! // run algorithm that moves the hole in the vector here
-//! // move the hole until it's in a sorted position
-//! for i in 1..hole_guard.v.len() {
-//! if *hole_guard.value >= hole_guard.v[i] {
-//! // move the element back and the hole forward
-//! let index = hole_guard.index;
-//! hole_guard.v.swap(index, index + 1);
-//! hole_guard.index += 1;
-//! } else {
-//! break;
-//! }
-//! }
-//!
-//! // When the scope exits here, the Vec becomes whole again!
-//! }
-//! }
-//!
-//! fn main() {
-//! let string = String::from;
-//! let mut data = vec![string("c"), string("a"), string("b"), string("d")];
-//! insertion_sort_first(&mut data);
-//! assert_eq!(data, vec!["a", "b", "c", "d"]);
-//! }
-//!
-//! ```
-//!
-//!
-//! # Crate Features
-//!
-//! - `use_std`
-//! + Enabled by default. Enables the `OnUnwind` and `OnSuccess` strategies.
-//! + Disable to use `no_std`.
-//!
-//! # Rust Version
-//!
-//! This version of the crate requires Rust 1.20 or later.
-//!
-//! The scopeguard 1.x release series will use a carefully considered version
-//! upgrade policy, where in a later 1.x version, we will raise the minimum
-//! required Rust version.
-
-#[cfg(not(any(test, feature = "use_std")))]
-extern crate core as std;
-
-use std::fmt;
-use std::marker::PhantomData;
-use std::mem::ManuallyDrop;
-use std::ops::{Deref, DerefMut};
-use std::ptr;
-
-/// Controls in which cases the associated code should be run
-pub trait Strategy {
- /// Return `true` if the guard’s associated code should run
- /// (in the context where this method is called).
- fn should_run() -> bool;
-}
-
-/// Always run on scope exit.
-///
-/// “Always” run: on regular exit from a scope or on unwinding from a panic.
-/// Can not run on abort, process exit, and other catastrophic events where
-/// destructors don’t run.
-#[derive(Debug)]
-pub enum Always {}
-
-/// Run on scope exit through unwinding.
-///
-/// Requires crate feature `use_std`.
-#[cfg(feature = "use_std")]
-#[derive(Debug)]
-pub enum OnUnwind {}
-
-/// Run on regular scope exit, when not unwinding.
-///
-/// Requires crate feature `use_std`.
-#[cfg(feature = "use_std")]
-#[derive(Debug)]
-pub enum OnSuccess {}
-
-impl Strategy for Always {
- #[inline(always)]
- fn should_run() -> bool {
- true
- }
-}
-
-#[cfg(feature = "use_std")]
-impl Strategy for OnUnwind {
- #[inline]
- fn should_run() -> bool {
- std::thread::panicking()
- }
-}
-
-#[cfg(feature = "use_std")]
-impl Strategy for OnSuccess {
- #[inline]
- fn should_run() -> bool {
- !std::thread::panicking()
- }
-}
-
-/// Macro to create a `ScopeGuard` (always run).
-///
-/// The macro takes statements, which are the body of a closure
-/// that will run when the scope is exited.
-#[macro_export]
-macro_rules! defer {
- ($($t:tt)*) => {
- let _guard = $crate::guard((), |()| { $($t)* });
- };
-}
-
-/// Macro to create a `ScopeGuard` (run on successful scope exit).
-///
-/// The macro takes statements, which are the body of a closure
-/// that will run when the scope is exited.
-///
-/// Requires crate feature `use_std`.
-#[cfg(feature = "use_std")]
-#[macro_export]
-macro_rules! defer_on_success {
- ($($t:tt)*) => {
- let _guard = $crate::guard_on_success((), |()| { $($t)* });
- };
-}
-
-/// Macro to create a `ScopeGuard` (run on unwinding from panic).
-///
-/// The macro takes statements, which are the body of a closure
-/// that will run when the scope is exited.
-///
-/// Requires crate feature `use_std`.
-#[cfg(feature = "use_std")]
-#[macro_export]
-macro_rules! defer_on_unwind {
- ($($t:tt)*) => {
- let _guard = $crate::guard_on_unwind((), |()| { $($t)* });
- };
-}
-
-/// `ScopeGuard` is a scope guard that may own a protected value.
-///
-/// If you place a guard in a local variable, the closure can
-/// run regardless how you leave the scope — through regular return or panic
-/// (except if panic or other code aborts; so as long as destructors run).
-/// It is run only once.
-///
-/// The `S` parameter for [`Strategy`](trait.Strategy.html) determines if
-/// the closure actually runs.
-///
-/// The guard's closure will be called with the held value in the destructor.
-///
-/// The `ScopeGuard` implements `Deref` so that you can access the inner value.
-pub struct ScopeGuard<T, F, S = Always>
-where
- F: FnOnce(T),
- S: Strategy,
-{
- value: ManuallyDrop<T>,
- dropfn: ManuallyDrop<F>,
- // fn(S) -> S is used, so that the S is not taken into account for auto traits.
- strategy: PhantomData<fn(S) -> S>,
-}
-
-impl<T, F, S> ScopeGuard<T, F, S>
-where
- F: FnOnce(T),
- S: Strategy,
-{
- /// Create a `ScopeGuard` that owns `v` (accessible through deref) and calls
- /// `dropfn` when its destructor runs.
- ///
- /// The `Strategy` decides whether the scope guard's closure should run.
- #[inline]
- #[must_use]
- pub fn with_strategy(v: T, dropfn: F) -> ScopeGuard<T, F, S> {
- ScopeGuard {
- value: ManuallyDrop::new(v),
- dropfn: ManuallyDrop::new(dropfn),
- strategy: PhantomData,
- }
- }
-
- /// “Defuse” the guard and extract the value without calling the closure.
- ///
- /// ```
- /// extern crate scopeguard;
- ///
- /// use scopeguard::{guard, ScopeGuard};
- ///
- /// fn conditional() -> bool { true }
- ///
- /// fn main() {
- /// let mut guard = guard(Vec::new(), |mut v| v.clear());
- /// guard.push(1);
- ///
- /// if conditional() {
- /// // a condition maybe makes us decide to
- /// // “defuse” the guard and get back its inner parts
- /// let value = ScopeGuard::into_inner(guard);
- /// } else {
- /// // guard still exists in this branch
- /// }
- /// }
- /// ```
- #[inline]
- pub fn into_inner(guard: Self) -> T {
- // Cannot move out of `Drop`-implementing types,
- // so `ptr::read` the value and forget the guard.
- let mut guard = ManuallyDrop::new(guard);
- unsafe {
- let value = ptr::read(&*guard.value);
- // Drop the closure after `value` has been read, so that if the
- // closure's `drop` function panics, unwinding still tries to drop
- // `value`.
- ManuallyDrop::drop(&mut guard.dropfn);
- value
- }
- }
-}
-
-/// Create a new `ScopeGuard` owning `v` and with deferred closure `dropfn`.
-#[inline]
-#[must_use]
-pub fn guard<T, F>(v: T, dropfn: F) -> ScopeGuard<T, F, Always>
-where
- F: FnOnce(T),
-{
- ScopeGuard::with_strategy(v, dropfn)
-}
-
-/// Create a new `ScopeGuard` owning `v` and with deferred closure `dropfn`.
-///
-/// Requires crate feature `use_std`.
-#[cfg(feature = "use_std")]
-#[inline]
-#[must_use]
-pub fn guard_on_success<T, F>(v: T, dropfn: F) -> ScopeGuard<T, F, OnSuccess>
-where
- F: FnOnce(T),
-{
- ScopeGuard::with_strategy(v, dropfn)
-}
-
-/// Create a new `ScopeGuard` owning `v` and with deferred closure `dropfn`.
-///
-/// Requires crate feature `use_std`.
-///
-/// ## Examples
-///
-/// For performance reasons, or to emulate “only run guard on unwind” in
-/// no-std environments, we can also use the default guard and simply manually
-/// defuse it at the end of scope like the following example. (The performance
-/// reason would be if the [`OnUnwind`]'s call to [std::thread::panicking()] is
-/// an issue.)
-///
-/// ```
-/// extern crate scopeguard;
-///
-/// use scopeguard::ScopeGuard;
-/// # fn main() {
-/// {
-/// let guard = scopeguard::guard((), |_| {});
-///
-/// // rest of the code here
-///
-/// // we reached the end of scope without unwinding - defuse it
-/// ScopeGuard::into_inner(guard);
-/// }
-/// # }
-/// ```
-#[cfg(feature = "use_std")]
-#[inline]
-#[must_use]
-pub fn guard_on_unwind<T, F>(v: T, dropfn: F) -> ScopeGuard<T, F, OnUnwind>
-where
- F: FnOnce(T),
-{
- ScopeGuard::with_strategy(v, dropfn)
-}
-
-// ScopeGuard can be Sync even if F isn't because the closure is
-// not accessible from references.
-// The guard does not store any instance of S, so it is also irrelevant.
-unsafe impl<T, F, S> Sync for ScopeGuard<T, F, S>
-where
- T: Sync,
- F: FnOnce(T),
- S: Strategy,
-{
-}
-
-impl<T, F, S> Deref for ScopeGuard<T, F, S>
-where
- F: FnOnce(T),
- S: Strategy,
-{
- type Target = T;
-
- fn deref(&self) -> &T {
- &*self.value
- }
-}
-
-impl<T, F, S> DerefMut for ScopeGuard<T, F, S>
-where
- F: FnOnce(T),
- S: Strategy,
-{
- fn deref_mut(&mut self) -> &mut T {
- &mut *self.value
- }
-}
-
-impl<T, F, S> Drop for ScopeGuard<T, F, S>
-where
- F: FnOnce(T),
- S: Strategy,
-{
- fn drop(&mut self) {
- // This is OK because the fields are `ManuallyDrop`s
- // which will not be dropped by the compiler.
- let (value, dropfn) = unsafe { (ptr::read(&*self.value), ptr::read(&*self.dropfn)) };
- if S::should_run() {
- dropfn(value);
- }
- }
-}
-
-impl<T, F, S> fmt::Debug for ScopeGuard<T, F, S>
-where
- T: fmt::Debug,
- F: FnOnce(T),
- S: Strategy,
-{
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct(stringify!(ScopeGuard))
- .field("value", &*self.value)
- .finish()
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use std::cell::Cell;
- use std::panic::catch_unwind;
- use std::panic::AssertUnwindSafe;
-
- #[test]
- fn test_defer() {
- let drops = Cell::new(0);
- defer!(drops.set(1000));
- assert_eq!(drops.get(), 0);
- }
-
- #[cfg(feature = "use_std")]
- #[test]
- fn test_defer_success_1() {
- let drops = Cell::new(0);
- {
- defer_on_success!(drops.set(1));
- assert_eq!(drops.get(), 0);
- }
- assert_eq!(drops.get(), 1);
- }
-
- #[cfg(feature = "use_std")]
- #[test]
- fn test_defer_success_2() {
- let drops = Cell::new(0);
- let _ = catch_unwind(AssertUnwindSafe(|| {
- defer_on_success!(drops.set(1));
- panic!("failure")
- }));
- assert_eq!(drops.get(), 0);
- }
-
- #[cfg(feature = "use_std")]
- #[test]
- fn test_defer_unwind_1() {
- let drops = Cell::new(0);
- let _ = catch_unwind(AssertUnwindSafe(|| {
- defer_on_unwind!(drops.set(1));
- assert_eq!(drops.get(), 0);
- panic!("failure")
- }));
- assert_eq!(drops.get(), 1);
- }
-
- #[cfg(feature = "use_std")]
- #[test]
- fn test_defer_unwind_2() {
- let drops = Cell::new(0);
- {
- defer_on_unwind!(drops.set(1));
- }
- assert_eq!(drops.get(), 0);
- }
-
- #[test]
- fn test_only_dropped_by_closure_when_run() {
- let value_drops = Cell::new(0);
- let value = guard((), |()| value_drops.set(1 + value_drops.get()));
- let closure_drops = Cell::new(0);
- let guard = guard(value, |_| closure_drops.set(1 + closure_drops.get()));
- assert_eq!(value_drops.get(), 0);
- assert_eq!(closure_drops.get(), 0);
- drop(guard);
- assert_eq!(value_drops.get(), 1);
- assert_eq!(closure_drops.get(), 1);
- }
-
- #[cfg(feature = "use_std")]
- #[test]
- fn test_dropped_once_when_not_run() {
- let value_drops = Cell::new(0);
- let value = guard((), |()| value_drops.set(1 + value_drops.get()));
- let captured_drops = Cell::new(0);
- let captured = guard((), |()| captured_drops.set(1 + captured_drops.get()));
- let closure_drops = Cell::new(0);
- let guard = guard_on_unwind(value, |value| {
- drop(value);
- drop(captured);
- closure_drops.set(1 + closure_drops.get())
- });
- assert_eq!(value_drops.get(), 0);
- assert_eq!(captured_drops.get(), 0);
- assert_eq!(closure_drops.get(), 0);
- drop(guard);
- assert_eq!(value_drops.get(), 1);
- assert_eq!(captured_drops.get(), 1);
- assert_eq!(closure_drops.get(), 0);
- }
-
- #[test]
- fn test_into_inner() {
- let dropped = Cell::new(false);
- let value = guard(42, |_| dropped.set(true));
- let guard = guard(value, |_| dropped.set(true));
- let inner = ScopeGuard::into_inner(guard);
- assert_eq!(dropped.get(), false);
- assert_eq!(*inner, 42);
- }
-}