intrusive_list.rs 1.4 KB

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