1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright 2022 Colin Finck <colin@reactos.org>
// SPDX-License-Identifier: MIT OR Apache-2.0
use crateSealed;
/// The type (singly or doubly linked list) of an empty enum that implements [`NtTypedList`].
/// Designates an empty enum as an NT list of a specific type (singly or doubly linked list).
///
/// You are supposed to define an empty enum and implement this trait for every list entry field
/// of every list element type in your program.
///
/// This is required, because a single element may be part of multiple NT lists, and henceforth
/// its element structure then contains multiple entry fields (e.g. [`NtListEntry`]).
/// To make all list functions insert and remove elements via the correct entry fields,
/// lists need to be uniquely identified, and this is what the empty enum types are for.
///
/// The easiest way to implement this trait is to use `derive` with the appropriate list type
/// ([`NtList`] or [`NtSingleList`]):
///
/// ```
/// # use nt_list::list::NtList;
/// #
/// #[derive(NtList)]
/// enum MyList {}
/// ```
///
/// [`NtList`]: enum@crate::list::NtList
/// [`NtListEntry`]: crate::list::NtListEntry
/// [`NtSingleList`]: enum@crate::single_list::NtSingleList
/// Designates a structure as a list element with an entry field (e.g. [`NtListEntry`]) of a
/// particular NT list.
/// The entry field's position inside the list is given by implementing the `offset` method.
/// The NT list is identified via the enum that implements [`NtTypedList`].
///
/// You can implement this trait multiple times for a structure if it is part of multiple
/// lists (and therefore contains multiple entry fields).
///
/// The easiest way to implement this trait for all entry fields of a structure is to use
/// `derive` on the structure:
///
/// ```
/// # use nt_list::NtListElement;
/// # use nt_list::list::{NtList, NtListEntry};
/// #
/// # #[derive(NtList)]
/// # enum MyList {}
/// #
/// #[derive(NtListElement)]
/// #[repr(C)]
/// struct MyElement {
/// entry: NtListEntry<Self, MyList>,
/// value: i32,
/// }
/// ```
///
/// # Safety
///
/// This trait is unsafe, because the compiler cannot verify that the `offset` method has been
/// implemented correctly.
/// Safe functions rely on the offset pointing to an actual [`NtListEntry`] or [`NtSingleListEntry`].
/// This trait must also only be implemented for structures marked with `#[repr(C)]`.
///
/// It is therefore recommended to only derive this trait as described above and never implement
/// it manually.
///
/// [`NtListEntry`]: crate::list::NtListEntry
/// [`NtSingleListEntry`]: crate::single_list::NtSingleListEntry
pub unsafe
/// Implements the [`NtListElement`] and (optionally) [`NtBoxedListElement`] traits for the given
/// element structure.
///
/// Technically, this macro traverses the structure and looks for [`NtListEntry`] and [`NtSingleListEntry`]
/// fields.
/// For each entry, it takes its list type parameter `L` and implements [`NtListElement`] along with
/// the `offset` trait function for it.
///
/// If an entry is marked with the `#[boxed]` attribute, [`NtBoxedListElement`] is also implemented for
/// the structure.
///
/// [`NtListEntry`]: crate::list::NtListEntry
/// [`NtSingleListEntry`]: crate::single_list::NtSingleListEntry
pub use NtListElement;
/// Enables [`NtBoxingListHead`] for a list element structure.
///
/// While an element may be part of multiple lists, only one list may have ownership of the element
/// and handle its memory allocation and deallocation.
/// Therefore, `NtBoxedListElement` can only be implemented once per list element structure.
///
/// The easiest way to implement this trait is to use the `#[boxed]` attribute for the appropriate
/// entry field and use `derive` on the structure:
///
/// ```
/// # use nt_list::NtListElement;
/// # use nt_list::list::{NtList, NtListEntry};
/// #
/// # #[derive(NtList)]
/// # enum MyList {}
/// #
/// #[derive(NtListElement)]
/// #[repr(C)]
/// struct MyElement {
/// #[boxed]
/// entry: NtListEntry<Self, MyList>,
/// value: i32,
/// }
/// ```
///
/// [`NtBoxingListHead`]: crate::list::NtBoxingListHead
/// [`NtListEntry`]: crate::list::NtListEntry