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
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
#![doc(html_root_url = "https://docs.rs/singleton-cell/0.3.1")]
#![no_std]

use core::cell::UnsafeCell;
use core::marker::PhantomData;
use core::mem;
pub use singleton_trait::{Singleton, Exists, Erased};

/**
 * Macro-only code which must be public
 */
pub mod internal {
    pub use paste;
}

/**
 * SCell, or SingletonCell provides an interface of a
 * Ghost Cell, where the Key is allowed to be any singleton,
 * rather than a particular token type.
 *
 * As a result, the uniqueness for the key can be provided
 * by any means, and the key type / resulting cell may also
 * be 'static for long-lived data structures
 */
#[repr(transparent)]
pub struct SCell<Key: ?Sized, T: ?Sized> {
    _phantom: PhantomData<fn(Key)>,
    inner: UnsafeCell<T>,
}
/**
 * A more verbose alias for SCell
 */
pub type SingletonCell<Key, T> = SCell<Key, T>;
/**
 * An owned SCell is equivalent to its underlying value,
 * and can be converted between them, so SCell<Key, T> is Send
 * if and only if T is Send
 */
unsafe impl<Key, T: Send> Send for SCell<Key, T> {}

/**
 * A shared reference to SCell can access the underlying value
 * both via shared reference, and via mutable reference,
 * so it can be Sync only if T is both Sync and Send.
 *
 * SCell does not otherwise put any constraints on Sync
 * since all shared usages must use references to the Key,
 * which must be sent between threads as normal.
 */
unsafe impl<Key, T: Send + Sync> Sync for SCell<Key, T> {}

impl<Key: ?Sized, T: ?Sized> SCell<Key, T> {
    /**
     * Convert a unique reference to a value to a unique reference
     * to this cell type. These two types are equivalent when
     * accessed uniquely.
     */
    #[inline(always)]
    pub fn from_mut(t: &mut T) -> &mut Self {
        // Safety:
        // * The representations are transparent down to T
        // * unique access to T enables unique access to self
        unsafe { &mut *(t as *mut T as *mut Self) }
    }

    /**
     * Uniquely borrow this cell in order to access T mutably.
     *
     * This requires unique access to self, rather than using
     * a key. For shared access, see the `borrow_mut` method
     * instead.
     *
     * Because this requires unique access to self, and all
     * other borrows require at least a shared reference,
     * unique access to the underlying data is safe.
     */
    #[inline(always)]
    pub fn get_mut(&mut self) -> &mut T {
        self.inner.get_mut()
    }

    /**
     * Get a raw pointer to this cell's data.
     */
    #[inline(always)]
    pub fn as_ptr(&self) -> *mut T {
        self.inner.get()
    }
}

impl<Key: ?Sized, T> SCell<Key, T> {
    /**
     * Construct a new SCell from underlying data.
     *
     * See also `SCell::from_mut` which can be used when the
     * usage of SCell is only within the scope of mutable
     * borrows of the data.
     */
    #[inline(always)]
    pub fn new(t: T) -> Self {
        SCell {
            inner: UnsafeCell::new(t),
            _phantom: PhantomData,
        }
    }

    /**
     * Destruct the SCell and access the inner data.
     *
     * This requires ownership of the SCell and hence guarantees
     * no simultaneous access.
     */
    #[inline(always)]
    pub fn into_inner(self) -> T {
        self.inner.into_inner()
    }
}

impl<Key: ?Sized, T> SCell<Key, [T]> {
    /**
     * Returns a slice of cells from a cell of a slice.
     */
    #[inline(always)]
    pub fn as_slice_of_cells(&self) -> &[SCell<Key, T>] {
        // Safety:
        // * The representations are identical
        // * the output lifetime is constrained to the input lifetime
        unsafe { &*(self.as_ptr() as *mut [SCell<Key, T>]) }
    }
}

impl<Key: Singleton + ?Sized, T: ?Sized> SCell<Key, T> {
    /**
     * Borrow the data underlying this cell, using a reference to
     * the singleton Key type.
     *
     * This is safe because any mutable borrow must either come
     * from a mutable reference to this cell, or a mutable reference
     * to the key, which cannot exist since this takes a shared
     * borrow of both this cell and the key.
     */
    #[inline(always)]
    pub fn borrow<'a>(&'a self, _: impl Exists<&'a Key>) -> &'a T
    where
        Key: 'a,
    {
        // Safety:
        // By the contract for Singleton & Erased
        // the unique value of Key is borrowed immutably for 'a
        //
        // * Every borrow to T requires either &mut self or a &Key/&mut Key
        //   so the only other borrow available would be this method taking &Key,
        //   which is compatible with the shared reference output
        unsafe { &*self.inner.get() }
    }

    /**
     * Mutably borrow the data underlying this cell,
     * using a mutable reference to the singleton Key type.
     *
     * This is safe because it requires a unique borrow of the key,
     * and a shared borrow of self, which prevents all other borrows
     * into the data.
     */
    #[allow(clippy::mut_from_ref)] // Clippy can't see through the Exists
    #[inline(always)]
    pub fn borrow_mut<'a>(&'a self, _: impl Exists<&'a mut Key>) -> &'a mut T
    where
        Key: 'a,
    {
        // Safety:
        // By the contract for Singleton & Erased
        // the unique value of Key is borrowed mutably for 'a
        //
        // * Every borrow to T requires either &mut self or a &Key/&mut Key
        //   which are excluded by the borrows in the signature
        unsafe { &mut *self.inner.get() }
    }
}

impl<Key: Singleton + ?Sized, T> SCell<Key, T> {
    /**
     * Replace the value behind this cell with a new one.
     *
     * This mutates the data and hence requires unique access to the key
     * to ensure that no borrows are invalidated.
     */
    #[inline(always)]
    pub fn replace<'a>(&'a self, value: T, token: impl Exists<&'a mut Key>) -> T
    where
        Key: 'a,
    {
        mem::replace(self.borrow_mut(token), value)
    }

    /**
     * Replace the value behind this cell with the default one.
     *
     * This mutates the data and so requires unique access to the key
     * to ensure that no borrows are invalidated.
     */
    #[inline(always)]
    pub fn take<'a>(&'a self, token: impl Exists<&'a mut Key>) -> T
    where
        Key: 'a,
        T: Default,
    {
        mem::take(self.borrow_mut(token))
    }
}

/**
 * A temporary singleton token created by the with_token function.
 *
 * See the with_token function for details.
 */
pub struct Token<'brand>(PhantomData<fn(&'brand ()) -> &'brand ()>);
// SAFETY:
// We only construct this with a unique, invariant brand in with_token
// For everything else, we just defer to ghost cell's GhostToken
unsafe impl<'brand> Singleton for Token<'brand> {}
unsafe impl<'brand> Send for Token<'brand> {}
unsafe impl<'brand> Sync for Token<'brand> {}

/**
 * Generate a local token type which is guaranteed to be a singleton via
 * a unique lifetime brand. SCells can be created within this scope via
 * SCell::new or SCell::from_mut and used via this token.
 *
 * Because the 'brand lifetime is unique to this scope, neither this
 * token, nor any SCell's created with it as the key may escape the scope.
 *
 * It is most likely useful when cells are created with SCell::from_mut,
 * which means that cells can be used for data structures that don't
 * mention SCell or the 'brand.
 *
 * For a token type which does not have this restriction, see new_singleton
 * for one implementation.
 *
 * ```
 *  use singleton_cell::*;
 *
 *  let mut x = 0;
 *  with_token(|mut tok| {
 *      let cell_borrow = &*SCell::from_mut(&mut x);
 *      *cell_borrow.borrow_mut(&mut tok) += 2;
 *
 *      let cell_one = SCell::new(0);
 *      *cell_one.borrow_mut(&mut tok) += 1;
 *      cell_one.into_inner()
 *  });
 *  assert_eq!(2, x);
 * ```
 */
#[inline(always)]
pub fn with_token<R>(f: impl for<'brand> FnOnce(Token<'brand>) -> R) -> R {
    // SAFETY: 'brand can't leak as f is polymorphic over it
    let token = Token(PhantomData);
    f(token)
}

///
/// Generates a new global singleton type with a fallible constructor.
/// This is intended for cases where a single instance is created early
/// in the program and passed throughout.
///
/// This is one way to create a Singleton which is 'static and Send/Sync
///
/// ```
/// #[macro_use] extern crate singleton_cell;
/// new_singleton!(pub Token);
/// fn main() {
///     let tok = Token::new().expect("Main called only once");
///
///     // possibly combine with Erased borrows
///     use singleton_trait::Erased;
///     let tok = Erased::new(tok);
///
/// }
///
/// ```
///
/// This method will return Some the first time it is called, and None
/// any time thereafter. This does not establish any ordering between
/// multiple threads if they access at the same time.
///
// Credit to Yandros for significant help with the idea / designing
// the original macro using std::sync::Once instead of AtomicBool.
//
// We use AtomicBool here instead to remain no-std and simplify the
// resulting code given that we don't need most features of Once.
#[macro_export]
macro_rules! new_singleton {
    ( $pub:vis $Name:ident ) => {
        $crate::internal::paste::paste! {
            $pub use [< __ $Name _help__ >]::$Name;
            #[allow(nonstandard_style)]
            mod [< __ $Name _help__ >] {

                pub
                struct $Name(());

                impl $Name {

                    pub
                    fn new () -> Option<Self> {
                        let first_run = {
                            static ONCE: ::core::sync::atomic::AtomicBool =
                                ::core::sync::atomic::AtomicBool::new(false);
                            &ONCE
                        };
                        if first_run
                            // We don't need any ordering guarantees between accesses, only atomicity
                            .compare_exchange(false, true,
                                ::core::sync::atomic::Ordering::Relaxed,
                                ::core::sync::atomic::Ordering::Relaxed)
                            .is_ok()
                        {
                            // Safety:
                            // * ONCE is a static, hence it is a single memory location which is false at
                            // program start.
                            // * The program start happens before all reads
                            // * Only one CAS from false to true can succeed since it will never become
                            // false again
                            Some( $Name(()) )
                        } else {
                            None
                        }
                    }

                    #[inline(always)]
                    pub
                    fn new_erased() -> Option<$crate::Erased<Self>> {
                        Self::new().map(|x| $crate::Erased::new(x))
                    }
                }

                // Safety: construction is guarded by the CAS on a static above
                // So only one instance can be created per program
                unsafe
                impl $crate::Singleton for $Name {}
            }
        }
    };
}

#[cfg(test)]
mod tests {
    extern crate alloc;
    extern crate std;
    use crate as singleton_cell;
    use super::*;
    use alloc::string::String;

    #[test]
    fn ghost_trivial() {
        let mut i = String::new();

        with_token(|mut tok| {
            let i = SCell::from_mut(&mut i);
            i.get_mut().push_str("A");

            i.borrow_mut(&mut tok).push_str("B");
            let first = i.borrow(&tok).clone();

            i.borrow_mut(&mut tok).push_str("C");
            let last = i.borrow(&tok);

            assert_eq!("AB", &*first);
            assert_eq!("ABC", &*last);
        });

        assert_eq!("ABC", &*i);
    }

    #[inline(never)]
    fn write_to<Key: Singleton>(sc: &SCell<Key, String>, k: &mut Key) {
        sc.borrow_mut(k).push_str("!");
    }

    #[test]
    fn ghost_read_after_write() {
        let result = with_token(|mut tok| {
            let mut s = String::from("A");
            let s = SCell::from_mut(&mut s);

            let borrow = &*s;
            write_to(&*s, &mut tok);
            write_to(&*s, &mut tok);

            borrow.borrow(&tok).clone()
        });
        assert_eq!("A!!", &*result);
    }

    #[test]
    fn local_type_round_trip() {
        let local = ();
        let mut tok = {
            struct Local<'a>(&'a ());
            unsafe impl<'a> Singleton for Local<'a> {}
            Local(&local)
        };

        let mut s = String::from("A");
        let s_mut = &mut s;
        let s_cell = SCell::from_mut(s_mut);
        let s_cell2 = &*s_cell;

        write_to(s_cell2, &mut tok);

        assert_eq!("A!", s_cell.borrow_mut(&mut tok));
        write_to(s_cell2, &mut tok);
        assert_eq!("A!!", s_cell.borrow(&tok));
        assert_eq!("A!!", s_cell.get_mut());
        s_cell.get_mut().push_str("C");
        assert_eq!("A!!C", s_mut);
    }

    #[test]
    fn global_singleton_unique() {
        new_singleton!(pub A);
        let _ = A::new();
        assert!(A::new().is_none(), "Second call to A::new() should be None");
    }

    #[test]
    fn global_singleton_distinct() {
        new_singleton!(pub A);
        new_singleton!(pub B);
        let a: Option<A> = A::new();
        let b: Option<B> = B::new();

        assert!(a.is_some(), "A should be Some");
        assert!(b.is_some(), "B should be Some");
    }
}