1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
use ;
/// ;;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> = ;
/// ;;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> = ;