intrusive_list.rs 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. use core::ptr::NonNull;
  2. pub struct Link {
  3. prev: Option<NonNull<Link>>,
  4. next: Option<NonNull<Link>>,
  5. }
  6. impl Link {
  7. pub const fn new() -> Self {
  8. Self {
  9. prev: None,
  10. next: None,
  11. }
  12. }
  13. pub fn insert(&mut self, node: &mut Self) {
  14. unsafe {
  15. let insert_node = NonNull::new(node as *mut Self);
  16. if let Some(next) = self.next {
  17. (*next.as_ptr()).prev = insert_node;
  18. }
  19. node.next = self.next;
  20. node.prev = NonNull::new(self as *mut Self);
  21. self.next = insert_node;
  22. }
  23. }
  24. pub fn remove(&mut self) {
  25. if let Some(next) = self.next {
  26. unsafe { (*next.as_ptr()).prev = self.prev };
  27. }
  28. if let Some(prev) = self.prev {
  29. unsafe { (*prev.as_ptr()).next = self.next };
  30. }
  31. self.prev = None;
  32. self.next = None;
  33. }
  34. pub fn next(&self) -> Option<&Self> {
  35. self.next.map(|node| unsafe { &*node.as_ptr() })
  36. }
  37. pub fn next_mut(&mut self) -> Option<&mut Self> {
  38. self.next.map(|node| unsafe { &mut *node.as_ptr() })
  39. }
  40. }
  41. #[macro_export]
  42. macro_rules! container_of {
  43. ($ptr:expr, $type:ty, $($f:tt)*) => {{
  44. let ptr = $ptr as *const _ as *const u8;
  45. let offset: usize = ::core::mem::offset_of!($type, $($f)*);
  46. ptr.sub(offset) as *mut $type
  47. }}
  48. }
  49. #[allow(unused_imports)]
  50. pub use container_of;