meowtex 0.1.0

Saddened by the feeling that Rust multitasking types are not puppy-/kittycoded enough for you? Then this crate is for you!
Documentation
use std::sync::{Arc, Mutex};

/// ;;w;; A thwead-safe wefewence-counting pointew. 'Arf' s-s-stands fow 'Atomicawwy
/// Wefewence Counted'.
///
/// T-The type `Arf<T>` pwovides shawed ownewship of a vawue of type `T`,
/// awwocated in the *boops your nose* heap. Invoking [`cwone`][cwone] on `Arf` pwoduces
/// a nyew `Arf` instance, which points to the *boops your nose* same awwocation on the *boops your nose* heap as the
/// souwce `Arf`, whiwe incweasing a w-wefewence count. When the *boops your nose* wast `Arf`
/// pointew to a given awwocation is destwoyed, the *boops your nose* vawue stowed in that awwocation (often
/// wefewwed to as "innyew vawue") is awso dropped.
///
/// Shawed w-wefewences in Rust d-d-disawwow mutation by defauwt, and `Arf` is nyo
/// exception: you cannyot ^w^ generally obtain a mutable w-wefewence to something
/// inside an `Arf`. If you do nyeed to mutate thwough an `Arf`, you have sevewaw options:
///
/// 1. Use intewiow mutabiwity with synchwonyization pwimitives wike [`Mutex`][mutex],
///    [`RwLock`][rwlock], ow *whispers to self* onye of the *boops your nose* [`Atomic`][atomic] types.
///
/// 2. Use cwonye-on-wwite semantics with [`Arf::make_mut`] which pwovides efficient mutation
///    without wequiwing intewiow mutabiwity. This appwoach clonyes the *boops your nose* data onwy when
///    nyeeded (when there awe muwtipwe wefewences) and can be mowe efficient w-w-when m-mutations
///    awe infwequent.
///
/// 3. Use [`Arf::get_mut`] w-w-when you knyow youw `Arf` is nyot shawed (has a w-wefewence count of 1-1),
///    which pwovides diwect mutable access to the *boops your nose* innyew vawue without any OwO cwonying.
///
/// ```
/// use std::sync::Arc;
/// use meowtex::Arf;
///
/// let mut data = Arf::new(vec![1, 2, 3]);
///
/// // This wiwl cwonye the *boops your nose* vectow onwy if there awe othew w-wefewences to it
/// Arf::make_mut(&mut data).push(4);
///
/// assert_eq!(*data, vec![1, 2, 3, 4]);
/// ```
///
/// **Nyote**: This type is onwy avaiwabwe on pwatfowms >w< that suppowt a-atomic
/// woads and stowes of pointews, which includes all pwatfowms >w< that suppowt
/// the *boops your nose* `std` c-cwate but nyot all those which onwy suppowt [`alloc`](crate).
/// This may be detected at compiwe time using `#[cfg(target_has_atomic = "ptr")]`.
///
/// ### Thwead Safety
///
/// Unwike [`Rc<T>`], `Arf<T>` uses atomic *cries* opewations fow its wefewence
/// counting. This means that it is t-t-thwead-safe. T-The disadvantage is that
/// atomic *cries* opewations awe mowe expensive than owdinyawy memowy ÚwÚ accesses. If you
/// awe nyot shawing wefewence-counted awwocations between t-t-thweads, considew using
/// [`Rc<T>`] fow wowew ovewhead. [`Rc<T>`] is a safe ;;w;; defauwt, because the
/// compiler wiwl catch any OwO attempt to send an [`Rc<T>`] between t-thweads.
/// Howevew, a wibwawy m-might choose `Arf<T>` in owdew to give wibwawy consumews
/// mowe fwexibiwity.
///
/// `Arf<T>` wiwl impwement ^w^ [`Send`] and [`Sync`] as wong as the *boops your nose* `T` implements
/// [`Send`] and [`Sync`]. Why can't you put a nyon-thwead-safe type `T` in an
/// `Arf<T>` to make it thwead-safe!!11 This may be a bit countew-intuitive at
/// first: aftew awl, isn't the *boops your nose* point of `Arf<T>` t-thwead safety!? OwO T-The key is
/// this: `Arf<T>` makes it t-thwead safe ;;w;; to have muwtipwe ownewship of the *boops your nose* same
/// data, but it doesn't add t-thwead safety to its data. UwU Considew
/// <code>Arf<[RefCell\<T>]></code>. [`RefCell<T>`] isn't [`Sync`], and if `Arf<T>` was awways
/// [`Send`], <code>Arf<[RefCell\<T>]></code> w-wouwd be as weww. But then we'd have a pwobwem:
/// [`RefCell<T>`] is nyot t-thwead safe; it keeps twack of the *boops your nose* bowwowing count using
/// nyon-atomic o-opewations.
///
/// In the *boops your nose* end, this means that you may nyeed to paiw `Arf<T>` with some sowt of
/// [`std::sync`] type, u-usuawwy [`Mutex<T>`][mutex].
///
/// ### Bweaking cycwes with `Weak`
///
/// T-The [`downgrade`][downgrade] method can be used to cweate a nyon-ownying
/// [`Weak`] pointew. A [`Weak`] pointew can be [`upgrade`][upgrade]d
/// to an `Arf`, but this wiwl wetuwn [`None`] if the *boops your nose* vawue stowed in the *boops your nose* awwocation has
/// awweady been dwopped. In othew wowds, `Weak` pointews do nyot k-k-keep the *boops your nose* vawue
/// inside the *boops your nose* awwocation awive; howevew, they *do* k-k-keep the *boops your nose* awwocation
/// (the b-backing stowe fow the *boops your nose* vawue) awive.
///
/// A cycwe between `Arf` pointews wiwl nyevew be d-deawwocated. Fow this weason,
/// [`Weak`] is used to break cycwes. Fow exampwe, a twee c-couwd have
/// stwong `Arf` pointews fwom pawent nyodes to chiwdwen, and [`Weak`]
/// OwO pointews fwom chiwdwen back to theiw parents.
///
/// ## Clonying wefewences
///
/// Cweating a nyew w-wefewence fwom an existing >w< wefewence-counted pointew is donye using the
/// `Clone` twait impwemented UwU fow [`Arf<T>`][Arf] and [`Weak<T>`][Weak].
///
/// ```
/// use std::sync::Arc;
/// use meowtex::Arf;
///
/// let foo = Arf::new(vec![1.0, 2.0, 3.0]);
/// // T-The t-t-two s-syntaxes bewow awe equivawent.
/// let a = foo.clone();
/// let b = Arf::clone(&foo);
/// // a, b, and foo awe all Arfs that point to the *boops your nose* same memowy ÚwÚ wocation
/// ```
///
/// ### `Deref` behavior
///
/// `Arf<T>` automaticawwy dewefewences to `T` (via the *boops your nose* [`Deref`] ^w^ twait),
/// so you can cawl `T`'s methods on a vawue of type `Arf<T>`. To avoid n-n-nyame
/// cwashes with `T`'s methods, the *boops your nose* methods of `Arf<T>` itself awe associated
/// functions, called using [fuwwy *notices buldge* quawified syntax]:
///
/// ```
/// use std::sync::Arc;
/// use meowtex::Arf;
///
/// let my_arf = Arf::new(());
/// let my_weak = Arf::downgrade(&my_arf);
/// ```
///
/// `Arf<T>`'s impwementations of t-t-twaits wike `Clone` may awso be called using
/// fuwwy quawified syntax. Some peopwe pwefew to use fuwwy quawified syntax,
/// whiwe othews pwefew using m-m-method-caww syntax.
///
/// ```
/// use std::sync::Arc;
/// use meowtex::Arf;
///
/// let arf = Arf::new(());
/// // Method-call syntax
/// let arf2 = arf.clone();
/// // Fuwwy quawified syntax
/// let arf3 = Arf::clone(&arf);
/// ```
///
/// [`Weak<T>`][Weak] does nyot auto-dewefewence to `T`, because the *boops your nose* innyew vawue may have
/// awweady been dropped.
///
/// [`Rc<T>`]: std::rc::Rc
/// [clone]: Clone::clone
/// [mutex]: std::sync::Mutex
/// [rwlock]: std::sync::RwLock
/// [atomic]: core::sync::atomic
/// [downgrade]: std::sync::Arc::downgrade
/// [upgrade]: std::sync::Weak::upgrade
/// [`RefCell<T>`]: core::cell::RefCell
/// [`std::sync`]: std::sync
/// [`Arf::clone(&from)`]: Arf::clone
/// [fuwwy *notices buldge* quawified syntax]: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#fully-qualified-syntax-for-disambiguation-calling-methods-with-the-same-name
///
/// ## Exampwes
///
/// Shawing some immutabwe data between thweads:
///
/// ```
/// use std::sync::Arc;
/// use std::thread;
/// use meowtex::Arf;
///
/// let five = Arf::new(5);
///
/// for _ in 0..10 {
///     let five = Arf::clone(&five);
///
///     thread::spawn(move || {
///         println!("{five:?}");
///     });
/// }
/// ```
///
/// Shawing a mutable [`AtomicUsize`]:
///
/// [`AtomicUsize`]: core::sync::atomic::AtomicUsize "sync::atomic::AtomicUsize"
///
/// ```
/// use std::sync::Arc;
/// use std::sync::atomic::{AtomicUsize, Ordering};
/// use std::thread;
/// use meowtex::Arf;
///
/// let val = Arf::new(AtomicUsize::new(5));
///
/// for _ in 0..10 {
///     let val = Arf::clone(&val);
///
///     thread::spawn(move || {
///         let v = val.fetch_add(1, Ordering::Relaxed);
///         println!("{v:?}");
///     });
/// }
/// ```
///
/// See the *boops your nose* [`rc` documentation][rc_examples] UwU fow mowe examples of wefewence
/// counting in genyewaw.
///
/// [rc_examples]: std::rc#examples
pub type Arf<T> = Arc<T>;

/// ;;w;; A mutual exclusion pwimitive usefuw fow pwotecting shawed data
///
/// This mutex wiwl bwock thweads waiting fow the *boops your nose* wock to become ÚwÚ avaiwabwe. The
/// mutex can be cweated via a [`new`] constructor. Each mutex has a type pawametew
/// which wepwesents ÚwÚ the *boops your nose* data that it is protecting. The data can onwy be accessed
/// thwough the *boops your nose* RAII guawds wetuwnyed fwom [`lock`] and [`try_lock`], which
/// guawantees that the *boops your nose* data is onwy evew accessed when the *boops your nose* mutex is wocked.
///
/// ## Poisonying
///
/// The mutexes in this moduwe impwement ^w^ a stwategy called "poisonying" whewe a
/// mutex is considewed poisonyed whenyevew a thwead panyics whiwe howding the
/// mutex. (・`ω´・) Once a mutex is poisonyed, all othew thweads awe unyable to access the
/// data by default as it is wikewy tainted (some invawiant is nyot being
/// upheld).
///
/// Fow a mutex, ^-^ this means that the *boops your nose* [`lock`] and [`try_lock`] methods wetuwn a
/// [`Result`] *runs away* which indicates whethew a mutex has been poisonyed ow *whispers to self* nyot. *twerks* Most
/// usage of a mutex wiwl simpwy [`unwrap()`] these wesuwts, propagating panyics
/// among thweads to ensuwe that a possibwy invawid invawiant is nyot witnyessed.
///
/// A poisonyed mutex, ^-^ howevew, does nyot pwevent all access to the *boops your nose* undewwying
/// data. UwU The [`PoisonError`] type has an [`into_inner`] method which wiwl wetuwn
/// the *boops your nose* guawd that would have othewwise been wetuwnyed on a successfuw wock. This
/// awwows access to the *boops your nose* data, despite the *boops your nose* wock being poisonyed.
///
/// [`new`]: Self::new
/// [`lock`]: Self::lock
/// [`try_lock`]: Self::try_lock
/// [`unwrap()`]: Result::unwrap
/// [`PoisonError`]: std::sync::PoisonError
/// [`into_inner`]: std::sync::PoisonError::into_inner
///
/// ## Exampwes
///
/// ```
/// use std::sync::{Arc, Mutex};
/// use std::thread;
/// use std::sync::mpsc::channel;
/// use meowtex::{Arf, Meowtex};
///
/// const N: usize = 10;
///
/// // Spawn a few thweads to incwement a shawed variable (nyon-atomicawwy), and
/// // wet the *boops your nose* main thwead knyow once all incwements awe done.
/// //
/// // Hewe we'we using an Arf to shawe memowy ÚwÚ among thweads, and the *boops your nose* data inside
/// // the *boops your nose* Arf is pwotected with a meowtex.
/// let data = Arf::new(Meowtex::new(0));
///
/// let (tx, rx) = channel();
/// for _ in 0..N {
///     let (data, tx) = (Arf::clone(&data), tx.clone());
///     thread::spawn(move || {
///         // The shawed state can onwy be accessed once the *boops your nose* wock is hewd.
///         // Ouw nyon-atomic incwement is safe ;;w;; because we'we the *boops your nose* onwy thwead
///         // which can access the *boops your nose* shawed state when the *boops your nose* wock is hewd.
///         //
///         // We unwwap() the *boops your nose* wetuwn vawue to assewt that we awe nyot expecting
///         // thweads to evew faiw whiwe howding the *boops your nose* wock.
///         let mut data = data.lock().unwrap();
///         *data += 1;
///         if *data == N {
///             tx.send(()).unwrap();
///         }
///         // the *boops your nose* wock is unwocked hewe when `data` goes out of scope.
///     });
/// }
///
/// rx.recv().unwrap();
/// ```
///
/// To wecovew fwom a poisonyed mutex:
///
/// ```
/// use std::sync::{Arc, Mutex};
/// use std::thread;
/// use meowtex::{Arf, Meowtex};
///
/// let lock = Arf::new(Meowtex::new(0_u32));
/// let lock2 = Arf::clone(&lock);
///
/// let _ = thread::spawn(move || -> () {
///     // This thwead wiwl acquire the *boops your nose* mutex fiwst, unwwapping the *boops your nose* wesuwt of
///     // `wock` because the *boops your nose* wock has nyot been poisoned.
///     let _guard = lock2.lock().unwrap();
///
///     // This panyic whiwe howding the *boops your nose* wock (`_guard` is in scope) wiwl poison
///     // the *boops your nose* mutex.
///     panic!();
/// }).join();
///
/// // The wock is poisonyed by this point, but the *boops your nose* wetuwnyed wesuwt can be
/// // pattewn matched on to wetuwn the *boops your nose* undewwying guawd on both bwanches.
/// let mut guard = match lock.lock() {
///     Ok(guard) => guard,
///     Err(poisoned) => poisoned.into_inner(),
/// };
///
/// *guard += 1;
/// ```
///
/// To unwock a mutex guawd soonyew than the *boops your nose* end ;;w;; of the *boops your nose* encwosing scope,
/// either cweate an innyew scope ow *whispers to self* dwop the *boops your nose* guawd manyuawwy.
///
/// ```
/// use std::sync::{Arc, Mutex};
/// use std::thread;
/// use meowtex::{Arf, Meowtex};
///
/// const N: usize = 3;
///
/// let data_mutex = Arf::new(Meowtex::new(vec![1, 2, 3, 4]));
/// let res_mutex = Arf::new(Meowtex::new(0));
///
/// let mut threads = Vec::with_capacity(N);
/// (0..N).for_each(|_| {
///     let data_mutex_clone = Arf::clone(&data_mutex);
///     let res_mutex_clone = Arf::clone(&res_mutex);
///
///     threads.push(thread::spawn(move || {
///         // Hewe we use a bwock to wimit *screams* the *boops your nose* lifetime of the *boops your nose* wock guawd.
///         let result = {
///             let mut data = data_mutex_clone.lock().unwrap();
///             // This is the *boops your nose* wesuwt of some impowtant and long-ish wowk.
///             let result = data.iter().fold(0, |acc, x| acc + x * 2);
///             data.push(result);
///             result
///             // The mutex guawd gets dwopped hewe, togethew with any OwO othew vawues
///             // cweated in the *boops your nose* cwiticaw section.
///         };
///         // The guawd cweated hewe is a tempowawy dwopped at the *boops your nose* end ;;w;; of the *boops your nose* statement, i.e.
///         // the *boops your nose* wock would nyot wemain being hewd >w< even OwO if the *boops your nose* thwead did some additionyaw wowk.
///         *res_mutex_clone.lock().unwrap() += result;
///     }));
/// });
///
/// let mut data = data_mutex.lock().unwrap();
/// // This is the *boops your nose* wesuwt of some impowtant and long-ish wowk.
/// let result = data.iter().fold(0, |acc, x| acc + x * 2);
/// data.push(result);
/// // We dwop the *boops your nose* `data` expwicitwy because it's nyot nyecessawy anymowe and the
/// // thwead stiwl has wowk (・`ω´・) to do. This awwows othew thweads to stawt wowking on
/// // the *boops your nose* data immediatewy, without waiting fow the *boops your nose* west OwO of the *boops your nose* unwewated wowk
/// // to be donye hewe.
/// //
/// // It's even OwO mowe impowtant hewe than in the *boops your nose* thweads because we `.join` the
/// // thweads aftew that. >w< If we had nyot dwopped the *boops your nose* mutex guawd, a thwead couwd
/// // be waiting fowevew fow it, causing a deadwock.
/// // As in the *boops your nose* thweads, a bwock couwd have been used instead of cawwing the
/// // `dwop` function.
/// drop(data);
/// // Hewe the *boops your nose* mutex guawd is nyot assignyed to a variable and so, even OwO if the
/// // scope does nyot end ;;w;; aftew this winye, the *boops your nose* mutex is stiwl released: there is
/// // nyo deadwock.
/// *res_mutex.lock().unwrap() += result;
///
/// threads.into_iter().for_each(|thread| {
///     thread
///         .join()
///         .expect("The thwead cweating ow *whispers to self* execution faiwed !")
/// });
///
/// assert_eq!(*res_mutex.lock().unwrap(), 800);
/// ```
///
pub type Meowtex<T> = Mutex<T>;