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
30impl<T> InnerFlag<T> {
34 #[allow(dead_code)]
36 pub fn from_ptr(ptr: NonNull<(RefCell<ManuallyDrop<T>>, Cell<isize>)>) -> Self {
38 Self(ptr)
39 }
40
41 #[inline]
45 pub fn count_ref(&self) -> &Cell<isize> {
46 unsafe { &self.0.as_ref().1 }
48 }
49
50 #[inline]
54 #[allow(dead_code)]
55 pub unsafe fn count_ptr_unchecked(&self) -> *const Cell<isize> {
57 self.count_ref() as *const _
58 }
59
60 #[inline]
62 pub fn ref_count(&self) -> isize {
63 self.count_ref().get().abs()
64 }
65
66 #[inline]
68 pub fn is_enabled(&self) -> bool {
69 self.count_ref().get().is_positive()
70 }
71
72 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 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 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 #[inline]
133 pub unsafe fn as_ref_unchecked(&self) -> &RefCell<ManuallyDrop<T>> {
134 unsafe { &self.0.as_ref().0 }
136 }
137
138 #[inline]
140 pub unsafe fn as_ptr_unchecked(&self) -> *const RefCell<ManuallyDrop<T>> {
141 unsafe { self.as_ref_unchecked() as *const _ }
142 }
143
144 #[inline]
146 pub fn inner_ptr(&self) -> NonNull<(RefCell<ManuallyDrop<T>>, Cell<isize>)> {
147 self.0
148 }
149}
150
151#[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 pub fn ref_count(&self) -> isize {
167 debug_assert!(self.0.ref_count() >= 1);
169 self.0.ref_count() - 1
170 }
171
172 pub fn is_enabled(&self) -> bool {
174 self.0.is_enabled()
175 }
176
177 pub fn enable(&self) -> Option<()> {
179 self.0.enable()
180 }
181
182 pub fn disable(&self) -> Option<()> {
186 self.0.disable()
187 }
188
189 pub fn borrow(&self) -> Ref<'_, T> {
200 Ref::map(self.deref().borrow(),|md| md.deref())
201 }
202
203 pub fn borrow_mut(&self) -> RefMut<'_, T> {
215 RefMut::map(self.deref().borrow_mut(),|md| md.deref_mut())
216 }
217
218 pub fn try_borrow(&self) -> Option<Ref<'_, T>> {
227 self.deref().try_borrow().ok().map(|r| {
228 Ref::map(r, |md| md.deref()) })
230 }
231
232 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()) })
244 }
245
246 pub fn new(value: T) -> Self {
248 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 pub fn as_ref_cell_ref(&self) -> &RefCell<ManuallyDrop<T>> {
261 unsafe { self.0.as_ref_unchecked() }
263 }
264
265 pub fn as_ref_cell_ptr(&self) -> *const RefCell<ManuallyDrop<T>> {
267 unsafe { self.0.as_ptr_unchecked() }
269 }
270
271 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 pub fn replace(&self, value: T) -> T {
292 unsafe { ManuallyDrop::take(&mut self.deref().replace(ManuallyDrop::new(value))) }
294 }
295
296 pub fn try_replace(&self, value: T) -> Result<T,T> {
306 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 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 }
349
350 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);
369 return Err(self);
370 }
371 };
372 self.disable();
373 unsafe {
374 Ok(ManuallyDrop::take(rm.deref_mut()))
375 }
376 }
378}
379
380impl<T> Drop for FlagCell<T> {
381 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 unsafe {
393 let refcell = &mut (*ptr.as_ptr()).0;
395 let mut_man_drop = RefCell::get_mut(refcell);
396 ManuallyDrop::drop(mut_man_drop);
397
398 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 unsafe { self.0.as_ref_unchecked() }
415 }
416}
417
418#[repr(transparent)]
423#[derive(Debug)]
424pub struct FlagRef<T>(InnerFlag<T>);
425
426#[derive(Debug)]
431pub enum FlagRefOption<T> {
432 Some(T),
433 Conflict,
434 Empty,
435 Disabled,
436}
437
438impl<T> FlagRefOption<T> {
439 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 pub fn into_option(self) -> Option<T> {
456 self.into()
457 }
458
459 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 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 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 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 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 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 let borrow_unwrapped = borrow.map(|r| Ref::map(r, |md| md.deref()));
539 FlagRefOption::from_borrow(borrow_unwrapped)
540 }
541
542 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 let borrow_unwrapped = borrow.map(|r| RefMut::map(r, |md| md.deref_mut()));
553 FlagRefOption::from_borrow(borrow_unwrapped)
554 }
555
556 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 pub fn new() -> Self {
573 Self::EMPTY
574 }
575}
576
577impl<T> Default for FlagRef<T>{
578 fn default() -> Self {
582 Self::new()
583 }
584}
585
586impl<T> Drop for FlagRef<T> {
587 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 unsafe {
597 let refcell = &mut (*ptr.as_ptr()).0;
599 let mut_man_drop = RefCell::get_mut(refcell);
600 ManuallyDrop::drop(mut_man_drop);
601
602 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 fn clone(&self) -> Self {
616 self.0.inc_ref_count();
617 Self(InnerFlag(self.0.inner_ptr()))
618 }
619}
620
621