#![allow(unsafe_code)]
use unsafe_list::{UnsafeListHead, UnsafeListNode, define_unsafe_list_head, init_unsafe_list_head};
struct Node {
val: usize,
list: UnsafeListNode<Node>,
}
impl Node {
fn create(val: usize) -> Self {
Self { val, list: UnsafeListNode::new() }
}
}
fn collect_vals(head: &UnsafeListHead<Node>) -> Vec<usize> {
head.iter().map(|n| n.val).collect()
}
fn collect_vals_rev(head: &UnsafeListHead<Node>) -> Vec<usize> {
head.iter().rev().map(|n| n.val).collect()
}
#[test]
fn empty_list() {
unsafe {
define_unsafe_list_head!(head, Node, list);
assert!(head.list_empty());
assert!(head.list_empty_careful());
assert!(head.list_first_entry_or_null().is_none());
assert!(head.list_first_entry_or_null_mut().is_none());
}
}
#[test]
fn list_add_front() {
unsafe {
define_unsafe_list_head!(head, Node, list);
let mut a = Node::create(1);
let mut b = Node::create(2);
let mut c = Node::create(3);
head.list_add(&mut a.list);
head.list_add(&mut b.list);
head.list_add(&mut c.list);
assert!(!head.list_empty());
assert_eq!(collect_vals(&head), [3, 2, 1]);
}
}
#[test]
fn list_add_tail() {
unsafe {
define_unsafe_list_head!(head, Node, list);
let mut a = Node::create(1);
let mut b = Node::create(2);
let mut c = Node::create(3);
head.list_add_tail(&mut a.list);
head.list_add_tail(&mut b.list);
head.list_add_tail(&mut c.list);
assert_eq!(collect_vals(&head), [1, 2, 3]);
}
}
#[test]
fn first_and_last_entry() {
unsafe {
define_unsafe_list_head!(head, Node, list);
let mut a = Node::create(10);
let mut b = Node::create(20);
let mut c = Node::create(30);
head.list_add_tail(&mut a.list);
head.list_add_tail(&mut b.list);
head.list_add_tail(&mut c.list);
assert_eq!(head.list_first_entry().val, 10);
assert_eq!(head.list_last_entry().val, 30);
assert_eq!(head.list_first_entry_mut().val, 10);
assert_eq!(head.list_last_entry_mut().val, 30);
}
}
#[test]
fn first_entry_or_null() {
unsafe {
define_unsafe_list_head!(head, Node, list);
assert!(head.list_first_entry_or_null().is_none());
assert!(head.list_first_entry_or_null_mut().is_none());
let mut a = Node::create(42);
head.list_add(&mut a.list);
assert_eq!(head.list_first_entry_or_null().unwrap().val, 42);
assert_eq!(head.list_first_entry_or_null_mut().unwrap().val, 42);
}
}
#[test]
fn list_is_last() {
unsafe {
define_unsafe_list_head!(head, Node, list);
let mut a = Node::create(1);
let mut b = Node::create(2);
head.list_add_tail(&mut a.list);
head.list_add_tail(&mut b.list);
assert!(!head.list_is_last(&a.list));
assert!(head.list_is_last(&b.list));
}
}
#[test]
fn list_del() {
unsafe {
define_unsafe_list_head!(head, Node, list);
let mut a = Node::create(1);
let mut b = Node::create(2);
let mut c = Node::create(3);
head.list_add_tail(&mut a.list);
head.list_add_tail(&mut b.list);
head.list_add_tail(&mut c.list);
b.list.list_del();
assert_eq!(collect_vals(&head), [1, 3]);
a.list.list_del();
assert_eq!(collect_vals(&head), [3]);
c.list.list_del();
assert!(head.list_empty());
}
}
#[test]
fn list_del_init() {
unsafe {
define_unsafe_list_head!(head, Node, list);
let mut a = Node::create(1);
let mut b = Node::create(2);
head.list_add_tail(&mut a.list);
head.list_add_tail(&mut b.list);
a.list.list_del_init();
assert_eq!(collect_vals(&head), [2]);
head.list_add(&mut a.list);
assert_eq!(collect_vals(&head), [1, 2]);
}
}
#[test]
fn list_replace() {
unsafe {
define_unsafe_list_head!(head, Node, list);
let mut a = Node::create(1);
let mut b = Node::create(2);
let mut c = Node::create(99);
head.list_add_tail(&mut a.list);
head.list_add_tail(&mut b.list);
a.list.list_replace(&mut c.list);
assert_eq!(collect_vals(&head), [99, 2]);
}
}
#[test]
fn list_replace_init() {
unsafe {
define_unsafe_list_head!(head, Node, list);
let mut a = Node::create(1);
let mut b = Node::create(2);
let mut c = Node::create(99);
head.list_add_tail(&mut a.list);
head.list_add_tail(&mut b.list);
a.list.list_replace_init(&mut c.list);
assert_eq!(collect_vals(&head), [99, 2]);
head.list_add(&mut a.list);
assert_eq!(collect_vals(&head), [1, 99, 2]);
}
}
#[test]
fn list_move() {
unsafe {
define_unsafe_list_head!(head1, Node, list);
define_unsafe_list_head!(head2, Node, list);
let mut a = Node::create(1);
let mut b = Node::create(2);
let mut c = Node::create(3);
head1.list_add_tail(&mut a.list);
head1.list_add_tail(&mut b.list);
head1.list_add_tail(&mut c.list);
b.list.list_move(&mut head2);
assert_eq!(collect_vals(&head1), [1, 3]);
assert_eq!(collect_vals(&head2), [2]);
}
}
#[test]
fn list_move_tail() {
unsafe {
define_unsafe_list_head!(head1, Node, list);
define_unsafe_list_head!(head2, Node, list);
let mut a = Node::create(1);
let mut b = Node::create(2);
head1.list_add_tail(&mut a.list);
head1.list_add_tail(&mut b.list);
let mut c = Node::create(3);
head2.list_add(&mut c.list);
a.list.list_move_tail(&mut head2);
assert_eq!(collect_vals(&head1), [2]);
assert_eq!(collect_vals(&head2), [3, 1]);
}
}
#[test]
fn list_empty_careful() {
unsafe {
define_unsafe_list_head!(head, Node, list);
assert!(head.list_empty_careful());
let mut a = Node::create(1);
head.list_add(&mut a.list);
assert!(!head.list_empty_careful());
a.list.list_del();
assert!(head.list_empty());
assert!(head.list_empty_careful());
}
}
#[test]
fn iter_forward_and_reverse() {
unsafe {
define_unsafe_list_head!(head, Node, list);
let mut a = Node::create(1);
let mut b = Node::create(2);
let mut c = Node::create(3);
head.list_add_tail(&mut a.list);
head.list_add_tail(&mut b.list);
head.list_add_tail(&mut c.list);
assert_eq!(collect_vals(&head), [1, 2, 3]);
assert_eq!(collect_vals_rev(&head), [3, 2, 1]);
}
}
#[test]
fn iter_mut_forward() {
unsafe {
define_unsafe_list_head!(head, Node, list);
let mut a = Node::create(1);
let mut b = Node::create(2);
let mut c = Node::create(3);
head.list_add_tail(&mut a.list);
head.list_add_tail(&mut b.list);
head.list_add_tail(&mut c.list);
for node in &mut head {
node.val *= 10;
}
assert_eq!(collect_vals(&head), [10, 20, 30]);
}
}
#[test]
fn iter_mut_reverse() {
unsafe {
define_unsafe_list_head!(head, Node, list);
let mut a = Node::create(1);
let mut b = Node::create(2);
let mut c = Node::create(3);
head.list_add_tail(&mut a.list);
head.list_add_tail(&mut b.list);
head.list_add_tail(&mut c.list);
let vals: Vec<usize> = head.iter_mut().rev().map(|n| n.val).collect();
assert_eq!(vals, [3, 2, 1]);
}
}
#[test]
fn iter_empty_list() {
define_unsafe_list_head!(head, Node, list);
assert_eq!(collect_vals(&head), Vec::<usize>::new());
assert_eq!(collect_vals_rev(&head), Vec::<usize>::new());
let vals: Vec<usize> = head.iter_mut().map(|n| n.val).collect();
assert_eq!(vals, Vec::<usize>::new());
let vals: Vec<usize> = head.iter_mut().rev().map(|n| n.val).collect();
assert_eq!(vals, Vec::<usize>::new());
}
#[test]
fn iter_single_element() {
unsafe {
define_unsafe_list_head!(head, Node, list);
let mut a = Node::create(42);
head.list_add(&mut a.list);
assert_eq!(collect_vals(&head), [42]);
assert_eq!(collect_vals_rev(&head), [42]);
}
}
#[test]
fn init_macro() {
unsafe {
let mut head = UnsafeListHead::<Node>::new();
init_unsafe_list_head!(head, Node, list);
assert!(head.list_empty());
let mut a = Node::create(1);
head.list_add(&mut a.list);
assert_eq!(head.list_first_entry().val, 1);
}
}
#[test]
fn define_macro() {
unsafe {
define_unsafe_list_head!(head, Node, list);
assert!(head.list_empty());
let mut a = Node::create(1);
head.list_add(&mut a.list);
assert_eq!(head.list_first_entry().val, 1);
}
}