Skip to main content

flag_cell/
local.rs

1use std::alloc::{dealloc, Layout};
2use std::cell::{Cell, RefCell, RefMut, Ref};
3use std::mem;
4use std::mem::ManuallyDrop;
5use std::num::NonZeroUsize;
6use std::ops::{Deref, DerefMut};
7use std::ptr::{drop_in_place, NonNull};
8
9macro_rules! dangling_then_return {
10    ($ptr:expr , $thing:expr) => {
11        if is_dangling($ptr) {
12            return $thing;
13        }
14    };
15    ($ptr:expr) => {
16        if is_dangling($ptr) {
17            return;
18        }
19    };
20}
21
22pub fn is_dangling<T: ?Sized>(ptr: *const T) -> bool {
23    ptr.cast::<()>().addr() == usize::MAX
24}
25
26#[repr(transparent)]
27#[derive(Debug)]
28struct InnerFlag<T>(NonNull<(RefCell<ManuallyDrop<T>>, Cell<isize>)>);
29
30// 不可能创建一个空的自己,不作null校验
31// 在内存被 dealloc 后,正常使用情况下应当不存在可能的InnerFlag被持有,当InnerFlag存在时,内存应当始终有效,因此不作任何判悬垂校验
32// TODO:引用计数理论上可以达到 isize::MAX,但应该不太可能有人做得到,暂时不写溢出检查,直接panic
33impl<T> InnerFlag<T> {
34    /// 从合法指针创建InnerFlag
35    #[allow(dead_code)]
36    // TODO:允许外部得到数据引用时暴露此方法
37    pub fn from_ptr(ptr: NonNull<(RefCell<ManuallyDrop<T>>, Cell<isize>)>) -> Self {
38        Self(ptr)
39    }
40    
41    /// 获取计数的引用
42    ///
43    /// 外部应当永远不会调用到此方法
44    #[inline]
45    pub fn count_ref(&self) -> &Cell<isize> {
46        // SAFETY: 仅当指针非空时调用,外部已做is_empty校验,指针必合法
47        unsafe { &self.0.as_ref().1 }
48    }
49    
50    /// 获取计数的裸指针
51    ///
52    /// 外部应当永远不会调用到此方法
53    #[inline]
54    #[allow(dead_code)]
55    // TODO:允许外部得到数据引用时暴露此方法
56    pub unsafe fn count_ptr_unchecked(&self) -> *const Cell<isize> {
57        self.count_ref() as *const _
58    }
59    
60    /// 获取FlagRef数量
61    #[inline]
62    pub fn ref_count(&self) -> isize {
63        self.count_ref().get().abs()
64    }
65    
66    /// 获取当前是否逻辑可用
67    #[inline]
68    pub fn is_enabled(&self) -> bool {
69        self.count_ref().get().is_positive()
70    }
71    
72    /// 使引用数量加一,返回当前数量
73    ///
74    /// 外部应当永远不会调用到此方法
75    ///
76    /// # Panics
77    /// 计数溢出时 panic
78    pub fn inc_ref_count(&self) -> isize  {
79        let cell = self.count_ref();
80        let val = cell.get();
81        if val == isize::MAX || val == isize::MIN + 1 {
82            panic!("Flag 计数溢出,最大允许 {}",isize::MAX);
83        };
84        // 不用判断0,因为0时数据会被销毁,从而永远不可能在0时调用该方法
85        debug_assert_ne!(val, 0);
86        let new_val = if val > 0 {val + 1} else {val - 1};
87        cell.set(new_val);
88        new_val
89    }
90    
91    /// 使引用数量减一,返回当前数量
92    ///
93    /// 外部应当永远不会调用到此方法
94    ///
95    /// # Panics
96    /// 计数==0 时 panic
97    pub fn dec_ref_count(&self) -> isize {
98        let cell = self.count_ref();
99        let val = cell.get();
100        if val == 0 {
101            panic!("Flag 计数为0时递减计数");
102        }
103        debug_assert_ne!(val, 0);
104        let new_val = if val > 0 {val - 1} else {val + 1};
105        cell.set(new_val);
106        new_val
107    }
108    
109    pub fn enable(&self) -> Option<()>{
110        let cell = self.count_ref();
111        let val = cell.get();
112        if val.is_positive() {
113            None
114        } else {
115            cell.set(-val);
116            Some(())
117        }
118    }
119    
120    pub fn disable(&self) -> Option<()>{
121        let cell = self.count_ref();
122        let val = cell.get();
123        if val.is_positive() {
124            cell.set(-val);
125            Some(())
126        } else {
127            None
128        }
129    }
130    
131    /// 获取内部RefCell的只读引用
132    #[inline]
133    pub unsafe fn as_ref_unchecked(&self) -> &RefCell<ManuallyDrop<T>> {
134        // SAFETY: 调用者必须保证指针非空+内存未释放
135        unsafe { &self.0.as_ref().0 }
136    }
137    
138    /// 获取内部RefCell的裸指针
139    #[inline]
140    pub unsafe fn as_ptr_unchecked(&self) -> *const RefCell<ManuallyDrop<T>> {
141        unsafe { self.as_ref_unchecked() as *const _ }
142    }
143    
144    /// 获取内部核心指针
145    #[inline]
146    pub fn inner_ptr(&self) -> NonNull<(RefCell<ManuallyDrop<T>>, Cell<isize>)> {
147        self.0
148    }
149}
150
151/// 带标记+引用计数+内部可变性的智能容器
152/// 逻辑上是唯一所有权持有者,逻辑禁用后可通过FlagRef::resurrect复活
153///
154/// 确保在安全使用时,Cell存在即内部数据存在。
155/// 正常使用时,逻辑上是不会有人再访问已经释放的数据的,因为确保访问者死完了数据才会释放。
156#[repr(transparent)]
157#[derive(Debug)]
158pub struct FlagCell<T>(InnerFlag<T>);
159
160impl<T> FlagCell<T> {
161    fn from_inner(ptr: NonNull<(RefCell<ManuallyDrop<T>>, Cell<isize>)>) -> Self {
162        Self(InnerFlag(ptr))
163    }
164    
165    /// 获取当前 [`FlagRef`] 引用数量
166    pub fn ref_count(&self) -> isize {
167        // 减去自己
168        debug_assert!(self.0.ref_count() >= 1);
169        self.0.ref_count() - 1
170    }
171    
172    /// 获取数据是否逻辑启用
173    pub fn is_enabled(&self) -> bool {
174        self.0.is_enabled()
175    }
176    
177    /// 将数据逻辑启用
178    pub fn enable(&self) -> Option<()> {
179        self.0.enable()
180    }
181    
182    /// 将数据逻辑禁用
183    ///
184    /// 这将禁止所有对应 [`FlagRef`] 使用内部数据,直到调用 [`enable`]
185    pub fn disable(&self) -> Option<()> {
186        self.0.disable()
187    }
188    
189    /// Immutably borrows the wrapped value.
190    ///
191    /// The borrow lasts until the returned `Ref` exits scope. Multiple
192    /// immutable borrows can be taken out at the same time.
193    ///
194    /// # Panics
195    ///
196    /// Panics if the value is currently mutably borrowed. For a non-panicking variant, use
197    /// [`try_borrow`](#method.try_borrow).
198    ///
199    pub fn borrow(&self) -> Ref<'_, T> {
200        Ref::map(self.deref().borrow(),|md| md.deref())
201    }
202    
203    /// Mutably borrows the wrapped value.
204    ///
205    /// The borrow lasts until the returned `RefMut` or all `RefMut`s derived
206    /// from it exit scope. The value cannot be borrowed while this borrow is
207    /// active.
208    ///
209    /// # Panics
210    ///
211    /// Panics if the value is currently borrowed. For a non-panicking variant, use
212    /// [`try_borrow_mut`](#method.try_borrow_mut).
213    ///
214    pub fn borrow_mut(&self) -> RefMut<'_, T> {
215        RefMut::map(self.deref().borrow_mut(),|md| md.deref_mut())
216    }
217    
218    /// Immutably borrows the wrapped value, returning an error if the value is currently mutably
219    /// borrowed.
220    ///
221    /// The borrow lasts until the returned `Ref` exits scope. Multiple immutable borrows can be
222    /// taken out at the same time.
223    ///
224    /// This is the non-panicking variant of [`borrow`](#method.borrow).
225    ///
226    pub fn try_borrow(&self) -> Option<Ref<'_, T>> {
227        self.deref().try_borrow().ok().map(|r| {
228            Ref::map(r, |md| md.deref()) // 解包ManuallyDrop
229        })
230    }
231    
232    /// Mutably borrows the wrapped value, returning an error if the value is currently borrowed.
233    ///
234    /// The borrow lasts until the returned `RefMut` or all `RefMut`s derived
235    /// from it exit scope. The value cannot be borrowed while this borrow is
236    /// active.
237    ///
238    /// This is the non-panicking variant of [`borrow_mut`](#method.borrow_mut).
239    ///
240    pub fn try_borrow_mut(&self) -> Option<RefMut<'_, T>> {
241        self.deref().try_borrow_mut().ok().map(|r| {
242            RefMut::map(r, |md| md.deref_mut()) // 解包ManuallyDrop
243        })
244    }
245    
246    /// Creates a new `FlagCell` containing `value`.
247    pub fn new(value: T) -> Self {
248        // 对标 std::rc,leak 解放堆内存生命周期,手动管理释放
249        Self::from_inner(
250            NonNull::from(
251                Box::leak(Box::new(
252                    (RefCell::new(ManuallyDrop::new(value)), Cell::new(1)
253                    )
254                ))
255            )
256        )
257    }
258    
259    /// 得到内部[`RefCell`]的引用
260    pub fn as_ref_cell_ref(&self) -> &RefCell<ManuallyDrop<T>> {
261        // SAFETY:确保正常使用时,FlagCell 存在即数据存在
262        unsafe { self.0.as_ref_unchecked() }
263    }
264    
265    /// 得到内部[`RefCell`]的指针
266    pub fn as_ref_cell_ptr(&self) -> *const RefCell<ManuallyDrop<T>> {
267        // SAFETY:确保正常使用时,FlagCell 存在即数据存在
268        unsafe { self.0.as_ptr_unchecked() }
269    }
270    
271    /// 生成一个 [`FlagRef`]
272    ///
273    pub fn flag_borrow(&self) -> FlagRef<T> {
274        let ref_flag = FlagRef(InnerFlag(self.0.inner_ptr()));
275        ref_flag.0.inc_ref_count();
276        ref_flag
277    }
278    
279    
280    /// Replaces the wrapped value with a new one, returning the old value,
281    /// without deinitializing either one.
282    ///
283    /// This function corresponds to [`mem::replace`].
284    ///
285    /// # Panics
286    ///
287    /// Panics if the value is currently borrowed.
288    ///
289    /// For non-panicking variant , see [`try_replace`](#method.try_replace).
290    ///
291    pub fn replace(&self, value: T) -> T {
292        // SAFETY: replace返回所有权,且这个ManuallyDrop马上被丢弃
293        unsafe { ManuallyDrop::take(&mut self.deref().replace(ManuallyDrop::new(value))) }
294    }
295    
296    /// Replaces the wrapped value with a new one, returning the old value,
297    /// without deinitializing either one.
298    ///
299    /// This function corresponds to [`mem::replace`].
300    ///
301    /// 如果当前存在引用,返回Err返还传入值
302    ///
303    /// This is the non-panicking variant of [`replace`](#method.replace).
304    ///
305    pub fn try_replace(&self, value: T) -> Result<T,T> {
306        // SAFETY: replace返回所有权,且这个ManuallyDrop马上被丢弃
307        unsafe {
308            Ok(ManuallyDrop::take(
309                &mut mem::replace(
310                    match self.deref().try_borrow_mut() {
311                        Ok(v) => {
312                            v
313                        }
314                        Err(_) => {return Err(value)}
315                    }.deref_mut(),
316                    ManuallyDrop::new(value)
317                )
318            ))
319        }
320    }
321    
322    /// 消费自身,返回内部数据,同时禁用
323    ///
324    /// # Panics
325    /// 若当前存在任何引用(包括FlagRef),或被异常禁用,panic。
326    ///
327    /// For non-panicking variant , see [`try_unwrap`](#method.try_borrow).
328    ///
329    pub fn unwrap(self) -> T {
330        let ref_count = self.ref_count();
331        if ref_count > 0 {
332            panic!(
333                "called `FlagCell::unwrap()` on a value with active FlagRef references (ref_count = {})",
334                ref_count
335            );
336        }
337        
338        if !self.is_enabled() {
339            panic!("called `FlagCell::unwrap()` on a disabled FlagCell");
340        }
341        
342        let mut rm = self.as_ref_cell_ref().borrow_mut();
343        self.disable();
344        unsafe {
345            ManuallyDrop::take(rm.deref_mut())
346        }
347        // self 将在此处被drop。
348    }
349    
350    /// 消费自身,返回内部数据,同时禁用
351    ///
352    /// 若当前存在任何引用(包括FlagRef),或被异常禁用,返还Self
353    ///
354    /// This is the non-panicking variant of [`unwrap`](#method.unwrap).
355    ///
356    pub fn try_unwrap(self) -> Result<T, Self> {
357        let ref_count = self.ref_count();
358        if !self.is_enabled() || ref_count > 0 {
359            return Err(self);
360        }
361        
362        let r = self.as_ref_cell_ref().try_borrow_mut();
363        let mut rm = match r {
364            Ok(ref_mut) => {ref_mut}
365            Err(_) => {
366                // 如果不在此分支内drop r,编译器会认为 r 会活得更久,从而拒绝给出 self
367                // 很奇葩,我都return了他还活个啥?
368                drop(r);
369                return Err(self);
370            }
371        };
372        self.disable();
373        unsafe {
374            Ok(ManuallyDrop::take(rm.deref_mut()))
375        }
376        // self 将在此处被drop。
377    }
378}
379
380impl<T> Drop for FlagCell<T> {
381    // 这drop与FlagRef的drop严格互斥
382    fn drop(&mut self) {
383        
384        let ptr = self.0.inner_ptr();
385        
386        self.disable();
387        
388        let new_count = self.0.dec_ref_count();
389        if new_count == 0 {
390            // SAFETY: 计数0=无其他引用,可以释放。
391            // new_count 首次归零意味着,内存未曾释放,这是唯一释放点。
392            unsafe {
393                // 修复:先手动析构ManuallyDrop包裹的T,再析构外层结构
394                let refcell = &mut (*ptr.as_ptr()).0;
395                let mut_man_drop = RefCell::get_mut(refcell);
396                ManuallyDrop::drop(mut_man_drop);
397                
398                // 析构剩余结构 + 释放内存
399                drop_in_place(ptr.as_ptr());
400                dealloc(
401                    ptr.as_ptr() as *mut u8,
402                    Layout::new::<(RefCell<ManuallyDrop<T>>, Cell<isize>)>()
403                );
404            }
405        }
406    }
407}
408
409impl<T> Deref for FlagCell<T> {
410    type Target = RefCell<ManuallyDrop<T>>;
411    
412    fn deref(&self) -> &Self::Target {
413        // SAFETY:FlagCell存在则内存有效、指针合法
414        unsafe { self.0.as_ref_unchecked() }
415    }
416}
417
418// impl<T> !Send for FlagCell<T> {}
419// impl<T> !Sync for FlagCell<T> {}
420
421/// 从FlagCell产生的轻量共享引用,可Clone,单线程使用
422#[repr(transparent)]
423#[derive(Debug)]
424pub struct FlagRef<T>(InnerFlag<T>);
425
426/// Some: 可借用 <br>
427/// Conflict: 借用冲突,不符合rust借用原则
428/// Empty: 内部为空,即此FlagRef是从new函数创建的
429/// Disabled: 内部数据当前已禁用
430#[derive(Debug)]
431pub enum FlagRefOption<T> {
432    Some(T),
433    Conflict,
434    Empty,
435    Disabled,
436}
437
438impl<T> FlagRefOption<T> {
439    /// 解包 FlagRefOption
440    ///
441    /// # Panics
442    /// 若非 `Some` ,panic
443    pub fn unwrap(self) -> T {
444        if let FlagRefOption::Some(val) = self {
445            val
446        }
447        else {
448            panic!("called `FlagRefOption::unwrap()` on a not `Some` value")
449        }
450    }
451    
452    /// 将自己转换为原生 `Option` 类型
453    ///
454    /// Some转换为Some,其余全部转换为None
455    pub fn into_option(self) -> Option<T> {
456        self.into()
457    }
458    
459    /// Maps an `FlagRefOption<T>` to `FlagRefOption<U>` by applying a function to a contained value (为`Some`) or returns 原变体 (非`Some`).
460    pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> FlagRefOption<U> {
461        match self{
462            FlagRefOption::Some(v) => FlagRefOption::Some(f(v)),
463            FlagRefOption::Conflict => FlagRefOption::Conflict,
464            FlagRefOption::Empty => FlagRefOption::Empty,
465            FlagRefOption::Disabled => FlagRefOption::Disabled,
466        }
467    }
468}
469
470impl<T> From<FlagRefOption<T>> for Option<T> {
471    fn from(f: FlagRefOption<T>) -> Option<T> {
472        match f {
473            FlagRefOption::Some(v) => Some(v),
474            _ => None,
475        }
476    }
477}
478
479impl<T> FlagRefOption<T> {
480    fn from_borrow(opt: Option<T>) -> Self {
481        opt.map(Self::Some).unwrap_or(Self::Conflict)
482    }
483}
484
485impl<T> FlagRef<T> {
486    /// 空指针实例
487    // 抄的std::rc::Weak::new()方法。
488    pub const EMPTY: Self =
489        Self( InnerFlag(NonNull::without_provenance(NonZeroUsize::MAX)) );
490    
491    pub fn ref_count(&self) -> isize {
492        dangling_then_return!(self.0.inner_ptr().as_ptr(),0);
493        // 减去可能存在的 FlagCell
494        if self.is_enabled() { self.0.ref_count() - 1 } else { self.0.ref_count() }
495    }
496    
497    pub fn is_enabled(&self) -> bool {
498        dangling_then_return!(self.0.inner_ptr().as_ptr(),false);
499        self.0.is_enabled()
500    }
501    
502    /// 强制将数据逻辑启用
503    ///
504    /// # SAFETY
505    /// 本方法为**逻辑不安全操作**:无内存未定义行为、无 panic 风险。
506    /// 暴露此方法是为了满足特定场景的便捷性需求。
507    ///
508    /// 此方法会虚构出一个 `FlagCell` ,可能造成其他相关类型功能异常。
509    pub unsafe fn enable(&self) -> FlagRefOption<()> {
510        dangling_then_return!(self.0.inner_ptr().as_ptr(),FlagRefOption::Empty);
511        self.0.enable();
512        FlagRefOption::Some(())
513    }
514    
515    /// 强制将数据逻辑禁用
516    ///
517    /// # SAFETY
518    /// 本方法为**逻辑不安全操作**:无内存未定义行为、无 panic 风险。
519    /// 暴露此方法是为了满足特定场景的便捷性需求。
520    ///
521    /// 此方法会强制 `RefCell` 失效,可能造成其他相关类型功能异常。
522    pub unsafe fn disable(&self) -> FlagRefOption<()> {
523        dangling_then_return!(self.0.inner_ptr().as_ptr(),FlagRefOption::Empty);
524        self.0.disable();
525        FlagRefOption::Some(())
526    }
527    
528    /// 尝试借用内部值。
529    ///
530    /// 详见 [`FlagRefOption`]
531    pub fn try_borrow(&self) -> FlagRefOption<Ref<'_, T>> {
532        dangling_then_return!(self.0.inner_ptr().as_ptr(), FlagRefOption::Empty);
533        if !self.is_enabled() {
534            return FlagRefOption::Disabled;
535        }
536        let borrow = unsafe { self.0.as_ref_unchecked().try_borrow().ok() };
537        // 解包ManuallyDrop<T> → T
538        let borrow_unwrapped = borrow.map(|r| Ref::map(r, |md| md.deref()));
539        FlagRefOption::from_borrow(borrow_unwrapped)
540    }
541    
542    /// 尝试可变借用内部值。
543    ///
544    /// 详见 [`FlagRefOption`]
545    pub fn try_borrow_mut(&self) -> FlagRefOption<RefMut<'_, T>> {
546        dangling_then_return!(self.0.inner_ptr().as_ptr(), FlagRefOption::Empty);
547        if !self.is_enabled() {
548            return FlagRefOption::Disabled;
549        }
550        let borrow = unsafe { self.0.as_ref_unchecked().try_borrow_mut().ok() };
551        // 解包ManuallyDrop<T> → T
552        let borrow_unwrapped = borrow.map(|r| RefMut::map(r, |md| md.deref_mut()));
553        FlagRefOption::from_borrow(borrow_unwrapped)
554    }
555    
556    /// 尝试复活 `FlagCell`
557    ///
558    /// 仅当前对应 `FlagCell` 销毁即数据逻辑禁用时,可复活,否则返回 `Disabled` 。
559    pub fn resurrect(&self) -> FlagRefOption<FlagCell<T>> {
560        dangling_then_return!(self.0.inner_ptr().as_ptr(),FlagRefOption::Empty);
561        if self.is_enabled() {
562            return FlagRefOption::Disabled;
563        }
564        unsafe { self.enable(); }
565        self.0.inc_ref_count();
566        FlagRefOption::Some(FlagCell::from_inner(self.0.inner_ptr()))
567    }
568    
569    /// 创建一个不指向任何内容的 `FlagRef`
570    ///
571    /// 尝试调用任何方法都将返回 `Empty`
572    pub fn new() -> Self {
573        Self::EMPTY
574    }
575}
576
577impl<T> Default for FlagRef<T>{
578    /// 创建一个不指向任何内容的 `FlagRef`
579    ///
580    /// 尝试调用任何方法都将返回 `Empty`
581    fn default() -> Self {
582        Self::new()
583    }
584}
585
586impl<T> Drop for FlagRef<T> {
587    // 与FlagCell的drop严格互斥
588    fn drop(&mut self) {
589        let ptr = self.0.inner_ptr();
590        dangling_then_return!(ptr.as_ptr());
591        
592        let new_count = self.0.dec_ref_count();
593        if new_count == 0 {
594            // SAFETY: 计数0=Cell不存在=无其他引用,指针合法。
595            // new_count 首次归零意味着,内存未曾释放,这是唯一释放点。
596            unsafe {
597                // 修复:先手动析构ManuallyDrop包裹的T,再析构外层结构
598                let refcell = &mut (*ptr.as_ptr()).0;
599                let mut_man_drop = RefCell::get_mut(refcell);
600                ManuallyDrop::drop(mut_man_drop);
601                
602                // 析构剩余结构 + 释放内存
603                drop_in_place(ptr.as_ptr());
604                dealloc(
605                    ptr.as_ptr() as *mut u8,
606                    Layout::new::<(RefCell<ManuallyDrop<T>>, Cell<isize>)>()
607                );
608            }
609        }
610    }
611}
612
613impl<T> Clone for FlagRef<T> {
614    /// 克隆一个 FlagRef,使引用计数加一
615    fn clone(&self) -> Self {
616        self.0.inc_ref_count();
617        Self(InnerFlag(self.0.inner_ptr()))
618    }
619}
620
621// impl<T> !Send for FlagRef<T> {}
622// impl<T> !Sync for FlagRef<T> {}