Skip to content

Commit d18c1d0

Browse files
authored
Guoweikang/linked list (#1)
* Synchronize r4l linked_lists latest code, update to v0.2.0 -------- 1 Add List sample code 2 Add more test case 3 Remove iter_back, can directly use iter().rev() 4 Add def_node to make it easier to use 5 remove unused unsafe_list source code 6 node support innner() and into_inner() 7 Directly use vis in macro 8 Repo name from linked_list to linked_list_r4l 8 Linked list push to crates-io and update to v0.2.0 Signed-off-by: guoweikang <[email protected]>
1 parent 34c8db3 commit d18c1d0

File tree

6 files changed

+976
-747
lines changed

6 files changed

+976
-747
lines changed

Cargo.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
[package]
2-
name = "linked_list"
3-
version = "0.1.0"
2+
name = "linked_list_r4l"
3+
version = "0.2.0"
44
edition = "2021"
5-
authors = ["Wedson Almeida Filho <[email protected]>"]
5+
authors = ["Wedson Almeida Filho <[email protected]>", "WeiKang Guo <[email protected]>"]
66
description = "Linked lists that supports arbitrary removal in constant time"
77
license = "GPL-2.0-or-later"
88
homepage = "https://github.com/arceos-org/arceos"
9-
repository = "https://github.com/arceos-org/linked_list"
10-
documentation = "https://arceos-org.github.io/linked_list"
9+
repository = "https://github.com/arceos-org/linked_list_r4l"
10+
documentation = "https://docs.rs/linked_list_r4l"
11+
keywords = ["list"]
12+
categories = ["no-std", "rust-patterns"]
1113

1214
[dependencies]

README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# LinkedList
2+
3+
[![Crates.io](https://img.shields.io/crates/v/linked_list_r4l)](https://crates.io/crates/linked_list_r4l)
4+
[![Doc.rs](https://docs.rs/linked_list_r4l/badge.svg)](https://docs.rs/linked_list_r4l)
5+
[![CI](https://github.com/arceos-org/linked_list_r4l/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/arceos-org/linked_list_r4l/actions/workflows/ci.yml)
6+
7+
Linked lists that supports arbitrary removal in constant time.
8+
9+
It is based on the linked list implementation in [Rust-for-Linux][1].
10+
11+
[1]: https://github.com/Rust-for-Linux/linux/blob/rust/rust/kernel/linked_list.rs
12+
13+
## Examples
14+
15+
```rust
16+
use linked_list_r4l::{GetLinks, Links, List};
17+
18+
type InnerType = usize;
19+
20+
pub struct ExampleNode {
21+
pub inner: InnerType,
22+
links: Links<Self>,
23+
}
24+
25+
impl GetLinks for ExampleNode {
26+
type EntryType = Self;
27+
28+
fn get_links(t: &Self) -> &Links<Self> {
29+
&t.links
30+
}
31+
}
32+
33+
impl ExampleNode {
34+
fn new(inner: InnerType) -> Self {
35+
Self {
36+
inner,
37+
links: Links::new()
38+
}
39+
}
40+
41+
fn inner(&self) -> &InnerType {
42+
&self.inner
43+
}
44+
}
45+
46+
let node1 = Box::new(ExampleNode::new(0));
47+
let node2 = Box::new(ExampleNode::new(1));
48+
let mut list = List::<Box<ExampleNode>>::new();
49+
50+
list.push_back(node1);
51+
list.push_back(node2);
52+
53+
// Support Iter
54+
for (i,e) in list.iter().enumerate() {
55+
assert!(*e.inner() == i);
56+
}
57+
58+
// Pop drop
59+
assert!(*list.pop_front().unwrap().inner() == 0);
60+
assert!(*list.pop_front().unwrap().inner() == 1);
61+
62+
```
63+
64+

src/lib.rs

Lines changed: 174 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,178 @@
1-
//! Linked lists that supports arbitrary removal in constant time.
2-
//!
3-
//! It is based on the linked list implementation in [Rust-for-Linux][1].
4-
//!
5-
//! [1]: https://github.com/Rust-for-Linux/linux/blob/rust/rust/kernel/linked_list.rs
6-
7-
#![no_std]
1+
#![cfg_attr(not(test), no_std)]
2+
#![doc = include_str!("../README.md")]
83

94
mod linked_list;
5+
mod raw_list;
6+
pub use linked_list::List;
7+
pub use raw_list::{GetLinks, Links};
8+
9+
#[macro_export(local_inner_macros)]
10+
#[doc(hidden)]
11+
macro_rules! __def_node_internal {
12+
($(#[$meta:meta])* $vis:vis struct $name:ident($type:ty);) => {
13+
$(#[$meta])*
14+
$vis struct $name {
15+
inner: $type,
16+
links: $crate::Links<Self>,
17+
}
18+
19+
impl $crate::GetLinks for $name {
20+
type EntryType = Self;
21+
22+
#[inline]
23+
fn get_links(t: &Self) -> &$crate::Links<Self> {
24+
&t.links
25+
}
26+
}
27+
28+
impl $name {
29+
#[doc = "Create a node"]
30+
pub const fn new(inner: $type) -> Self {
31+
Self {
32+
inner,
33+
links: $crate::Links::new(),
34+
}
35+
}
36+
37+
#[inline]
38+
#[doc = "Return the referece of wrapped inner"]
39+
pub const fn inner(&self) -> &$type {
40+
&self.inner
41+
}
42+
43+
#[inline]
44+
#[doc = "Consumes the `node`, returning the wrapped inner"]
45+
pub fn into_inner(self) -> $type {
46+
self.inner
47+
}
48+
}
49+
50+
impl core::ops::Deref for $name {
51+
type Target = $type;
52+
53+
#[inline]
54+
fn deref(&self) -> &Self::Target {
55+
&self.inner
56+
}
57+
}
58+
};
59+
60+
($(#[$meta:meta])* $vis:vis struct $name:ident<$gen:ident>($type:ty);) => {
61+
$(#[$meta])*
62+
$vis struct $name<$gen> {
63+
inner: $type,
64+
links: $crate::Links<Self>,
65+
}
66+
67+
impl<$gen> $crate::GetLinks for $name<$gen> {
68+
type EntryType = Self;
69+
70+
#[inline]
71+
fn get_links(t: &Self) -> &$crate::Links<Self> {
72+
&t.links
73+
}
74+
}
75+
76+
impl<$gen> $name<$gen> {
77+
#[doc = "Create a node"]
78+
pub const fn new(inner: $type) -> Self {
79+
Self {
80+
inner,
81+
links: $crate::Links::new(),
82+
}
83+
}
84+
85+
#[inline]
86+
#[doc = "Return the referece of wrapped inner"]
87+
pub const fn inner(&self) -> &$type {
88+
&self.inner
89+
}
90+
91+
#[inline]
92+
#[doc = "Consumes the `node`, returning the wrapped inner"]
93+
pub fn into_inner(self) -> $type {
94+
self.inner
95+
}
96+
}
97+
98+
impl<$gen> core::ops::Deref for $name<$gen> {
99+
type Target = $type;
10100

11-
pub mod unsafe_list;
101+
#[inline]
102+
fn deref(&self) -> &Self::Target {
103+
&self.inner
104+
}
105+
}
106+
};
107+
}
12108

13-
pub use self::linked_list::{AdapterWrapped, List, Wrapper};
14-
pub use unsafe_list::{Adapter, Cursor, Links};
109+
/// A macro for create a node type that can be used in List.
110+
///
111+
/// # Syntax
112+
///
113+
/// ```ignore
114+
/// def_node! {
115+
/// /// A node with usize value.
116+
/// [pub] struct UsizedNode(usize);
117+
/// /// A node with generic inner type.
118+
/// [pub] struct WrapperNode<T>(T);
119+
/// }
120+
/// ```
121+
///
122+
/// # Example
123+
///
124+
/// ```rust
125+
/// use linked_list_r4l::{def_node, List};
126+
///
127+
/// def_node!{
128+
/// /// An example Node with usize
129+
/// struct ExampleNode(usize);
130+
/// /// An example Node with generic Inner type and pub(crate)
131+
/// pub(crate) struct NativeGenericNode(usize);
132+
/// /// An example Node with generic Inner type and pub vis
133+
/// pub struct GenericNode<T>(T);
134+
/// }
135+
///
136+
/// let node1 = Box::new(ExampleNode::new(0));
137+
/// let node2 = Box::new(ExampleNode::new(1));
138+
/// let mut list = List::<Box<ExampleNode>>::new();
139+
///
140+
/// list.push_back(node1);
141+
/// list.push_back(node2);
142+
///
143+
/// for (i,e) in list.iter().enumerate() {
144+
/// assert!(*e.inner() == i);
145+
/// }
146+
///
147+
/// let node1 = list.pop_front().unwrap();
148+
/// let node2 = list.pop_front().unwrap();
149+
///
150+
/// assert!(node1.into_inner() == 0);
151+
/// assert!(node2.into_inner() == 1);
152+
/// assert!(list.pop_front().is_none());
153+
///
154+
/// let node1 = Box::new(GenericNode::new(0));
155+
/// let node2 = Box::new(GenericNode::new(1));
156+
///
157+
/// let mut list = List::<Box<GenericNode<usize>>>::new();
158+
///
159+
/// list.push_back(node1);
160+
/// list.push_back(node2);
161+
///
162+
/// for (i,e) in list.iter().enumerate() {
163+
/// assert!(*e.inner() == i);
164+
/// }
165+
/// ```
166+
///
167+
#[macro_export(local_inner_macros)]
168+
macro_rules! def_node {
169+
($(#[$meta:meta])* $vis:vis struct $name:ident($type:ty); $($t:tt)*) => {
170+
__def_node_internal!($(#[$meta])* $vis struct $name($type););
171+
def_node!($($t)*);
172+
};
173+
($(#[$meta:meta])* $vis:vis struct $name:ident<$gen:ident>($type:ty); $($t:tt)*) => {
174+
__def_node_internal!($(#[$meta])* $vis struct $name<$gen>($type););
175+
def_node!($($t)*);
176+
};
177+
() => ()
178+
}

0 commit comments

Comments
 (0)