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
//! [`ThreadLocalToken`] — a brand confined to its originating thread.
use PhantomData;
use crate;
brand_owner_token!
/// Open a thread-confined branding scope.
///
/// The token handed to `f` is `!Send`, so neither it nor any cell it governs
/// can be moved to another thread—confinement is proven at compile time.
///
/// # Examples
///
/// ```
/// use melinoe::{sync::thread_local_scope, MelinoeCell};
///
/// let total = thread_local_scope(|mut token| {
/// let counter = MelinoeCell::new(0_usize);
/// for _ in 0..5 {
/// *counter.borrow_mut(&mut token) += 1;
/// }
/// *counter.borrow(&token)
/// });
/// assert_eq!(total, 5);
/// ```
///
/// The token is `!Send`, so the compiler forbids moving the capability—or any
/// cell governed by it—onto another thread:
///
/// ```compile_fail
/// use melinoe::sync::thread_local_scope;
/// fn require_send<T: Send>(_: &T) {}
/// thread_local_scope(|token| {
/// require_send(&token); // ERROR: `ThreadLocalToken` is not `Send`
/// });
/// ```