loopcell 1.0.0

cell for multiple routes of access that are only used one-at-a-time in sequence
Documentation
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
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
//! [qcell]: https://docs.rs/qcell/latest/qcell/
//! [ghost_cell]: https://docs.rs/ghost-cell/latest/ghost_cell/
//!
//! 
//! [LoopCell]: `LoopCell`
//! [LoopSyncCell]: `LoopSyncCell`
#![doc = include_str!("../README.md")]
#![cfg_attr(not(test), no_std)]

use core::{
    cell::Cell,
    fmt::Debug,
    mem,
    ops::{Deref, DerefMut},
};

use option_lock::OptionLock;

/// Specialized cell for building iterators that handle a value (such as a shared buffer), make it
/// available for processing, modification, etc., and then it needs to be available for the next
/// iteration. Access is performed by [`LoopCell::access`].
///
/// Because [`Cell`] is not [`Sync`], the [`LoopCellAccess`] for [`LoopCell`]s are not [`Send`].
/// This is particularly important when writing [`core::future::Future`]s and asynchronous code,
/// which is often a place where you'd want this (e.g. handling streams of events). In that case,
/// you want [`LoopSyncCell`].
///
/// Unlike the internal cell data (which uses an [`Option`]), this cell type only implements [`Default`]
/// if the type parameter implements [`Default`], and contains the relevant default value.
///
/// If you access the [`LoopCell`] while something else is holding on to the [`LoopCell`] value,
/// then you will not be able to obtain a value. You can also
/// [create an empty `LoopCell` that cannot provide any access][LoopCell::new_empty]
#[repr(transparent)]
pub struct LoopCell<T>(Cell<Option<T>>);

impl<T> LoopCell<T> {
    /// Create a new [`LoopCell`] with the given value
    #[inline]
    pub const fn new(initial_value: T) -> Self {
        Self(Cell::new(Some(initial_value)))
    }

    /// Create a new [`LoopCell`] using the default value of the type it holds
    #[inline]
    pub fn new_default() -> Self
    where
        T: Default,
    {
        Self::default()
    }

    /// Create a new, empty [`LoopCell`] that can never provide a value.
    #[inline]
    pub const fn new_empty() -> Self {
        Self(Cell::new(None))
    }

    /// Attempt to access the loop cell, producing an accessor that will write back any changes to
    /// the cell once it is dropped (unless it's manually disarmed).
    ///
    /// Only produces [`Some`] if no other accessors are using this [`LoopCell`]
    #[inline]
    pub fn access(&self) -> Option<LoopCellAccess<'_, T>> {
        let maybe_available = self.0.replace(None);
        maybe_available.map(|value| LoopCellAccess::new(self, value))
    }
}

impl<T: Copy + Debug> Debug for LoopCell<T> {
    #[inline]
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        f.debug_tuple("LoopCell").field(&self.0).finish()
    }
}

impl<T> From<T> for LoopCell<T> {
    #[inline]
    fn from(value: T) -> Self {
        Self(Cell::new(Some(value)))
    }
}

impl<T: Default> Default for LoopCell<T> {
    #[inline]
    fn default() -> Self {
        Self::new(Default::default())
    }
}

/// Accessor for a [`LoopCell`], that will automatically write back any modifications to `T`
/// when dropped (or manually committed), unless you deliberately disarm it with
/// [`LoopCellAccess::consume`] to make it so the [`LoopCell`] is "used up".
///
/// The [`Send`]-equivalent form is [`LoopSyncCellAccess`]
#[clippy::has_significant_drop]
pub struct LoopCellAccess<'cell, T> {
    /// The actual loop cell. When creating this structure, this should now have [`None`] in it, as
    /// the loop accessor (self) holds the `T`.
    loop_cell: &'cell LoopCell<T>,
    /// The value of the cell, directly.
    ///
    /// This is **always [`Some`] except during drop or discard/consume**.
    value: Option<T>,
}

impl<'cell, T> LoopCellAccess<'cell, T> {
    /// Build a new [`LoopCellAccess`] from the cell, and the value that was extracted from it.
    ///
    /// This is an internal function.
    #[inline]
    const fn new(cell: &'cell LoopCell<T>, value: T) -> Self {
        Self {
            loop_cell: cell,
            value: Some(value),
        }
    }

    /// Consume the accessor and commit the changes made to the [`LoopCell`]'s value, making the
    /// value available once again to anyone trying to get it via [`LoopCell::access`]. Equivalent
    /// to [`mem::drop`]
    #[inline]
    pub fn commit(self) {
        mem::drop(self)
    }

    /// Consume the accessor, but do not write the value to the [`LoopCell`]. This will leave the
    /// [`LoopCell`] in such a state that it can no longer ever provide values.
    ///
    /// This returns the value itself as-per it's modifications.
    #[inline]
    pub fn consume(mut self) -> T {
        self.value
            .take()
            .expect("value inside loop cell accessor should always be Some")
    }

    /// Get a version of this capable of being mapped.
    #[inline]
    pub fn into_mapped_access(self) -> LoopCellMappedAccess<'cell, T, ()> {
        self.into()
    }

    /// Directly map this bare [`LoopCellAccess`] into one that is "mapped" to another value.
    #[inline]
    pub fn map_loopcell_access<O>(
        mut self,
        f: impl FnOnce(&mut T) -> O,
    ) -> LoopCellMappedAccess<'cell, T, O> {
        let o = f(&mut self);
        LoopCellMappedAccess {
            bare_access: self,
            value: o,
        }
    }

    /// Get the value of the loopcell from the access
    #[inline]
    pub fn as_loopcell_value(&self) -> &T {
        self
    }

    /// Get the value of the loopcell from the access, mutably.
    #[inline]
    pub fn as_loopcell_value_mut(&mut self) -> &mut T {
        self
    }
}

impl<'cell, T: Debug> Debug for LoopCellAccess<'cell, T> {
    #[inline]
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        f.debug_struct("LoopCellAccess")
            .field("loop_cell", &"<opaque>")
            .field("value", &self.value)
            .finish()
    }
}

impl<'cell, T> Deref for LoopCellAccess<'cell, T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &T {
        self.value
            .as_ref()
            .expect("value should always be Some inside loopcell accessor")
    }
}

impl<'cell, T> DerefMut for LoopCellAccess<'cell, T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut T {
        self.value
            .as_mut()
            .expect("value should always be Some inside loopcell accessor")
    }
}

impl<'cell, T> AsRef<T> for LoopCellAccess<'cell, T> {
    #[inline]
    fn as_ref(&self) -> &T {
        self
    }
}

impl<'cell, T> AsMut<T> for LoopCellAccess<'cell, T> {
    #[inline]
    fn as_mut(&mut self) -> &mut T {
        self
    }
}

impl<'cell, T> Drop for LoopCellAccess<'cell, T> {
    fn drop(&mut self) {
        // If we've not been disarmed, then set the value
        if let Some(v) = self.value.take() {
            self.loop_cell.0.set(Some(v))
        }
    }
}

/// Accessor for a [`LoopCell`], that will automatically write back any modifications to the value
/// on drop (unless disarmed with [`LoopCellMappedAccess::consume`]) so the [`LoopCell`] is "used
/// up".
///
/// Unlike [`LoopCellAccess`], this contains an extra value, and lets you perform modifications to
/// it with the "context" of the loop cell accessor (which is mutable).
///
/// This provides a clean way to bundle an accessor and also bundle a data value, which should be
/// processed with the accessor.
#[clippy::has_significant_drop]
pub struct LoopCellMappedAccess<'cell, T, V = ()> {
    /// Bare accessor. This handles all the relevant drop code.
    bare_access: LoopCellAccess<'cell, T>,
    /// Value "paired" with the loop cell access.
    value: V,
}

impl<'cell, T, V> LoopCellMappedAccess<'cell, T, V> {
    /// Apply a function to the mapped value, to produce a new mapped value - but it also makes the
    /// inner loop cell value that we have access to available.
    #[inline]
    pub fn map_loopcell_access<O>(
        self,
        f: impl FnOnce(&mut T, V) -> O,
    ) -> LoopCellMappedAccess<'cell, T, O> {
        let Self {
            mut bare_access,
            value,
        } = self;
        let o = f(&mut bare_access, value);
        LoopCellMappedAccess {
            bare_access,
            value: o,
        }
    }

    /// Commit the changes made to the [`LoopCell`] through this accessor, making the [`LoopCell`]
    /// available to everyone once again with the new cell data, while also emitting the bundled value.
    #[inline]
    pub fn commit(self) -> V {
        self.bare_access.commit();
        self.value
    }

    /// Consume the changes made to the [`LoopCell`] through this accessor, making the [`LoopCell`]
    /// never have any more values. This returns the last value of the [`LoopCell`] as modified by
    /// this accessor, as well as the bundled value.
    #[inline]
    pub fn consume(self) -> (T, V) {
        let cell_v = self.bare_access.consume();
        (cell_v, self.value)
    }

    /// Get the value of the loopcell from the access
    #[inline]
    pub fn get_loopcell_value(&self) -> &T {
        &self.bare_access
    }

    /// Get the value of the loopcell from the access, mutably.
    #[inline]
    pub fn get_loopcell_value_mut(&mut self) -> &mut T {
        &mut self.bare_access
    }

    /// Get the bundled value from the access
    #[inline]
    pub fn get_value(&self) -> &V {
        &self.value
    }

    /// Get the bundled value from the access, mutably.
    #[inline]
    pub fn get_value_mut(&mut self) -> &mut V {
        &mut self.value
    }

    #[inline]
    /// Unpack the bundled value from the normal [`LoopCellAccess`]
    pub fn unmap_access(self) -> (LoopCellAccess<'cell, T>, V) {
        (self.bare_access, self.value)
    }
}

impl<'cell, T, V: Default> From<LoopCellAccess<'cell, T>> for LoopCellMappedAccess<'cell, T, V> {
    #[inline]
    fn from(bare_access: LoopCellAccess<'cell, T>) -> Self {
        Self {
            bare_access,
            value: Default::default(),
        }
    }
}

impl<'cell, T, V> Deref for LoopCellMappedAccess<'cell, T, V> {
    type Target = V;

    #[inline]
    fn deref(&self) -> &Self::Target {
        self.get_value()
    }
}

impl<'cell, T, V> DerefMut for LoopCellMappedAccess<'cell, T, V> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.get_value_mut()
    }
}

impl<'cell, T, V> AsRef<V> for LoopCellMappedAccess<'cell, T, V> {
    #[inline]
    fn as_ref(&self) -> &V {
        self
    }
}

impl<'cell, T, V> AsMut<V> for LoopCellMappedAccess<'cell, T, V> {
    #[inline]
    fn as_mut(&mut self) -> &mut V {
        self
    }
}

/// Specialized cell for when you want to build an iterator that produces a value, to then be
/// modified and used, but then finally made available for the next iteration. The value of this
/// cell can be restored from an accessor on a different thread to the one where it was taken (i.e.
/// it is [`Sync`]).
///
/// This form is particularly useful when writing asynchronous event processors with shared data,
/// where you might need to hold an access across an await point. It is an alternative to
/// [`LoopCell`], and is likely to be used often.
///
/// Unlike the underlying [`option_lock::OptionLock`], this only implements [`Default`] if the type
/// parameter `T` implements [`Default`], and it is created with the default value of `T` in that
/// case. Also note that [`option_lock::OptionLock`] is implemented entirely with atomics - it's
/// very lightweight and doesn't carry the overhead of allocation or normal mutex. This is
/// essentially close to the most minimal equivalent to how we use `Cell<Option<T>>` in [`LoopCell`].
///
/// If you access the [`LoopSyncCell`] while something else is holding on to an accessor, then you
/// won't be able to get any access. If something else deliberately consumes it's accessor, then
/// you will not be able to get any values out of this any more. You can also
/// [create a `LoopSyncCell` which cannot have anything retrieved][LoopSyncCell::new_empty]
// The internal lock here is only held for very short periods of time (for taking and then
// restoring). This is why we tolerate spinlocking, as it's an extremely ephemeral lock. This type
// only ever permits exactly one accessor to actually exist at a time with `Some` in it.
#[repr(transparent)]
pub struct LoopSyncCell<T>(OptionLock<T>);

impl<T> LoopSyncCell<T> {
    /// Create a new [`LoopSyncCell`] with the given value
    #[inline]
    pub const fn new(initial_value: T) -> Self {
        Self(OptionLock::new(initial_value))
    }

    /// Create a new [`LoopSyncCell`] using the default value of the type it holds
    #[inline]
    pub fn new_default() -> Self
    where
        T: Default,
    {
        Self::default()
    }

    /// Create a new, empty [`LoopSyncCell`] that can never provide a value.
    #[inline]
    pub const fn new_empty() -> Self {
        Self(OptionLock::empty())
    }

    /// Attempt to access the loop cell, producing an accessor that will write back any changes to
    /// the cell once it is dropped (unless it's manually disarmed).
    ///
    /// Only produces [`Some`] if no other accessors are using this [`LoopSyncCell`]
    #[inline]
    pub fn access(&self) -> Option<LoopSyncCellAccess<'_, T>> {
        // Spinlock is ok because the lock is only ever held very ephemerally.
        let maybe_available = self.0.spin_lock().take();
        maybe_available.map(|value| LoopSyncCellAccess::new(self, value))
    }
}

impl<T: Copy + Debug> Debug for LoopSyncCell<T> {
    #[inline]
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        f.debug_tuple("LoopSyncCell").field(&self.0).finish()
    }
}

impl<T> From<T> for LoopSyncCell<T> {
    #[inline]
    fn from(value: T) -> Self {
        Self::new(value)
    }
}

impl<T: Default> Default for LoopSyncCell<T> {
    #[inline]
    fn default() -> Self {
        Self::new(T::default())
    }
}

/// Accessor for a [`LoopSyncCell`], that will automatically write back any modifications to `T`
/// when dropped (or manually committed), unless you deliberately disarm it with
/// [`LoopSyncCellAccess::consume`] to make it so the [`LoopSyncCell`] is "used up".
#[clippy::has_significant_drop]
pub struct LoopSyncCellAccess<'cell, T> {
    /// The actual loop cell. When creating this structure, this should now have [`None`] in it, as
    /// the loop accessor (self) holds the `T`.
    loop_cell: &'cell LoopSyncCell<T>,
    /// The value of the cell, directly.
    ///
    /// This is **always [`Some`] except during drop or discard/consume**.
    value: Option<T>,
}

impl<'cell, T> LoopSyncCellAccess<'cell, T> {
    /// Build a new [`LoopSyncCellAccess`] from the cell, and the value that was extracted from it.
    ///
    /// This is an internal function.
    #[inline]
    const fn new(cell: &'cell LoopSyncCell<T>, value: T) -> Self {
        Self {
            loop_cell: cell,
            value: Some(value),
        }
    }

    /// Consume the accessor and commit the changes made to the [`LoopSyncCell`]'s value, making the
    /// value available once again to anyone trying to get it via [`LoopSyncCell::access`]. Equivalent
    /// to [`mem::drop`]
    #[inline]
    pub fn commit(self) {
        mem::drop(self)
    }

    /// Consume the accessor, but do not write the value to the [`LoopSyncCell`]. This will leave the
    /// [`LoopSyncCell`] in such a state that it can no longer ever provide values.
    ///
    /// This returns the value itself as-per it's modifications.
    #[inline]
    pub fn consume(mut self) -> T {
        self.value
            .take()
            .expect("value inside loop cell accessor should always be Some")
    }

    /// Get a version of this capable of being mapped.
    #[inline]
    pub fn into_mapped_access(self) -> LoopSyncCellMappedAccess<'cell, T, ()> {
        self.into()
    }

    /// Directly map this bare [`LoopSyncCellAccess`] into one that is "mapped" to another value.
    #[inline]
    pub fn map_loopcell_access<O>(
        mut self,
        f: impl FnOnce(&mut T) -> O,
    ) -> LoopSyncCellMappedAccess<'cell, T, O> {
        let o = f(&mut self);
        LoopSyncCellMappedAccess {
            bare_access: self,
            value: o,
        }
    }

    /// Get the value of the loopcell from the access
    #[inline]
    pub fn as_loopcell_value(&self) -> &T {
        self
    }

    /// Get the value of the loopcell from the access, mutably.
    #[inline]
    pub fn as_loopcell_value_mut(&mut self) -> &mut T {
        self
    }
}

impl<'cell, T: Debug> Debug for LoopSyncCellAccess<'cell, T> {
    #[inline]
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        f.debug_struct("LoopSyncCellAccess")
            .field("loop_cell", &"<opaque>")
            .field("value", &self.value)
            .finish()
    }
}

impl<'cell, T> Deref for LoopSyncCellAccess<'cell, T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &T {
        self.value
            .as_ref()
            .expect("value should always be Some inside loopcell accessor")
    }
}

impl<'cell, T> DerefMut for LoopSyncCellAccess<'cell, T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut T {
        self.value
            .as_mut()
            .expect("value should always be Some inside loopcell accessor")
    }
}

impl<'cell, T> AsRef<T> for LoopSyncCellAccess<'cell, T> {
    #[inline]
    fn as_ref(&self) -> &T {
        self
    }
}

impl<'cell, T> AsMut<T> for LoopSyncCellAccess<'cell, T> {
    #[inline]
    fn as_mut(&mut self) -> &mut T {
        self
    }
}

impl<'cell, T> Drop for LoopSyncCellAccess<'cell, T> {
    fn drop(&mut self) {
        // While `self.value` is almost always `Some`, if we've been disarmed then it will be `None`. No point in spinlocking if there is nothing there.
        if let Some(v) = self.value.take() {
            // spinlock is ok because this is very ephemeral - note that the value returned "should" be `None` as only one thing can take out of the loop sync cell at once.
            self.loop_cell.0.spin_lock().replace(v);
        }
    }
}

/// Accessor for a [`LoopSyncCell`], that will automatically write back any modifications to the value
/// on drop (unless disarmed with [`LoopSyncCellMappedAccess::consume`]) so the [`LoopSyncCell`] is "used
/// up".
///
/// Unlike [`LoopSyncCellAccess`], this contains an extra value, and lets you perform modifications to
/// it with the "context" of the loop cell accessor (which is mutable).
///
/// This provides a clean way to bundle an accessor and also bundle a data value, which should be
/// processed with the accessor.
#[clippy::has_significant_drop]
pub struct LoopSyncCellMappedAccess<'cell, T, V = ()> {
    /// Bare accessor. This handles all the relevant drop code.
    bare_access: LoopSyncCellAccess<'cell, T>,
    /// Value "paired" with the loop cell access.
    value: V,
}

impl<'cell, T, V> LoopSyncCellMappedAccess<'cell, T, V> {
    /// Apply a function to the mapped value, to produce a new mapped value - but it also makes the
    /// inner loop cell value that we have access to available.
    #[inline]
    pub fn map_loopcell_access<O>(
        self,
        f: impl FnOnce(&mut T, V) -> O,
    ) -> LoopSyncCellMappedAccess<'cell, T, O> {
        let Self {
            mut bare_access,
            value,
        } = self;
        let o = f(&mut bare_access, value);
        LoopSyncCellMappedAccess {
            bare_access,
            value: o,
        }
    }

    /// Commit the changes made to the [`LoopSyncCell`] through this accessor, making the [`LoopSyncCell`]
    /// available to everyone once again with the new cell data, while also emitting the bundled value.
    #[inline]
    pub fn commit(self) -> V {
        self.bare_access.commit();
        self.value
    }

    /// Consume the changes made to the [`LoopSyncCell`] through this accessor, making the [`LoopSyncCell`]
    /// never have any more values. This returns the last value of the [`LoopSyncCell`] as modified by
    /// this accessor, as well as the bundled value.
    #[inline]
    pub fn consume(self) -> (T, V) {
        let cell_v = self.bare_access.consume();
        (cell_v, self.value)
    }

    /// Get the value of the loopcell from the access
    #[inline]
    pub fn get_loopcell_value(&self) -> &T {
        &self.bare_access
    }

    /// Get the value of the loopcell from the access, mutably.
    #[inline]
    pub fn get_loopcell_value_mut(&mut self) -> &mut T {
        &mut self.bare_access
    }

    /// Get the bundled value from the access
    #[inline]
    pub fn get_value(&self) -> &V {
        &self.value
    }

    /// Get the bundled value from the access, mutably.
    #[inline]
    pub fn get_value_mut(&mut self) -> &mut V {
        &mut self.value
    }

    #[inline]
    /// Unpack the bundled value from the normal [`LoopSyncCellAccess`]
    pub fn unmap_access(self) -> (LoopSyncCellAccess<'cell, T>, V) {
        (self.bare_access, self.value)
    }
}

impl<'cell, T, V: Default> From<LoopSyncCellAccess<'cell, T>>
    for LoopSyncCellMappedAccess<'cell, T, V>
{
    #[inline]
    fn from(bare_access: LoopSyncCellAccess<'cell, T>) -> Self {
        Self {
            bare_access,
            value: Default::default(),
        }
    }
}

impl<'cell, T, V> Deref for LoopSyncCellMappedAccess<'cell, T, V> {
    type Target = V;

    #[inline]
    fn deref(&self) -> &Self::Target {
        self.get_value()
    }
}

impl<'cell, T, V> DerefMut for LoopSyncCellMappedAccess<'cell, T, V> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.get_value_mut()
    }
}

impl<'cell, T, V> AsRef<V> for LoopSyncCellMappedAccess<'cell, T, V> {
    #[inline]
    fn as_ref(&self) -> &V {
        self
    }
}

impl<'cell, T, V> AsMut<V> for LoopSyncCellMappedAccess<'cell, T, V> {
    #[inline]
    fn as_mut(&mut self) -> &mut V {
        self
    }
}

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.