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
#![doc(html_root_url = "https://docs.rs/singleton-cell/0.1.1")]
#![no_std]

use core::cell::UnsafeCell;
use core::marker::PhantomData;
use core::mem;
use singleton_trait::Exists;
pub use singleton_trait::Singleton;

/**
 * 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]
    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.
     *
     * Unique access to this cell guarantees that no other accesses
     * to it can be performed simultaneously.
     */
    #[inline]
    pub fn get_mut(&mut self) -> &mut T {
        self.inner.get_mut()
    }

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

impl<Key: ?Sized, T> SCell<Key, T> {
    /**
     * Construct a new SCell from underlying data.
     */
    #[inline]
    pub fn new(t: T) -> Self {
        SCell {
            inner: UnsafeCell::new(t),
            _phantom: PhantomData,
        }
    }

    /**
     * Destruct the SCell and access the inner data.
     */
    #[inline]
    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]
    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.
     *
     * Safety to borrow is guaranteed by the immutable borrow to the
     * singleton key for this cell.
     */
    #[inline]
    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.
     *
     * Safety to borrow mutably is guaranteed by the mutable borrow to the
     * singleton key for this cell.
     */
    #[inline]
    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 requires unique access to the token in order to ensure there
     * are no other active borrows we could be invalidating.
     */
    #[inline]
    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 requires unique access to the token in order to ensure there
     * are no other active borrows we could be invalidating.
     */
    #[inline]
    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 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.
 *
 * This token and all borrows and cells based off of it cannot escape the scope.
 *
 * ```
 *  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)
}


#[cfg(test)]
mod tests {
    extern crate alloc;
    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);
    }

}