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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
//! A bitfields crate.
//!
//! ```
//! use superbitty::{bitfields, BitFieldCompatible};
//!
//! #[derive(BitFieldCompatible, Debug, Clone, Copy, PartialEq, Eq)]
//! pub enum Enum {
//! A,
//! B,
//! C,
//! D,
//! }
//!
//! #[derive(Clone, Copy)]
//! pub struct Rest(pub u8);
//!
//! // SAFETY: We only set this via `Bitfields`, and thus the values are guaranteed
//! // to stay in range.
//! unsafe impl BitFieldCompatible for Rest {
//! const SHIFT: u32 = 0;
//! const BITS_LEN: u32 = 6;
//! fn into_raw(self) -> u128 { self.0 as u128 }
//! unsafe fn from_raw(v: u128) -> Self { Self(v as u8) }
//! }
//!
//! bitfields! {
//! pub struct Bitfields : u8 {
//! pub e: Enum,
//! pub r: Rest,
//! }
//! }
//!
//! fn main() {
//! let mut instance = Bitfields::new(Enum::B, Rest(0b010));
//! assert_eq!(instance.e(), Enum::B);
//! instance.set_r(Rest(0b101));
//! assert_eq!(instance.r().0, 0b101);
//! }
//! ```
/// A bitfield struct.
///
/// All fields must implement [`BitFieldCompatible`] and their ranges must be non-overlapping
/// and big enough to hold the bitfields.
///
/// ```
/// # use superbitty::{bitfields, BitFieldCompatible};
/// #[derive(BitFieldCompatible, Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
/// enum EnumA { #[default] A, B }
/// #[derive(BitFieldCompatible, Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
/// enum EnumB { #[default] A, B, C }
///
/// bitfields! {
/// #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
/// pub struct Bitfields : u8 {
/// enum_a: EnumA, // from bit 0 to bit 1 (exclusive)
/// pub enum_b: EnumB, // from bit 1 to bit 3
/// }
/// }
///
/// let mut instance = Bitfields::new(EnumA::B, EnumB::A);
/// assert_eq!(instance.enum_a(), EnumA::B);
/// assert_eq!(instance.enum_b(), EnumB::A);
///
/// instance.set_enum_b(EnumB::C);
/// assert_eq!(instance.enum_a(), EnumA::B);
/// assert_eq!(instance.enum_b(), EnumB::C);
/// ```
///
/// The traits derived in the example - [`Debug`], [`Clone`], [`Copy`], [`Default`],
/// [`PartialEq`], [`Eq`], [`PartialOrd`], [`Ord`] and [`Hash`] - are the only you
/// can `#[derive()]`. All others need to be manually implemented.
///
/// By default, the constructor function will be called `new` and will have the same
/// visibility as the struct. You can control that by adding
/// `construct = <visibility> fn <name>();` after the struct, like the following:
/// ```ignore
/// bitfields! {
/// // ...
/// construct = pub fn new();
/// }
/// ```
///
/// The base type is stored as [`Raw`] in a (private) tuple field `0`. You can call its
/// [`raw()`] method to get the raw bitfields data (but you cannot modify it):
/// ```rust
/// # use superbitty::{bitfields, BitFieldCompatible};
/// #[derive(BitFieldCompatible, Clone, Copy)]
/// enum Enum { A, B }
///
/// bitfields! {
/// pub struct Bitfields : u8 {
/// a: Enum,
/// b: Enum,
/// c: Enum,
/// }
/// }
///
/// let mut instance = Bitfields::new(Enum::B, Enum::A, Enum::B);
/// assert_eq!(instance.0.raw(), 0b101); // `Enum::B` is 1, `Enum::A` is 0.
/// ```
///
/// [`BitFieldCompatible`]: crate::BitFieldCompatible
/// [`Debug`]: core::fmt::Debug
/// [`Hash`]: core::hash::Hash
/// [`raw()`]: Raw::raw
pub use bitfields;
/// An enum that can be used as a bitfield.
///
/// It must be [`Copy`].
///
/// It must carry no payload and have no negative discriminants.
///
/// ```
/// # use superbitty::BitFieldCompatible;
/// #[derive(BitFieldCompatible, Clone, Copy)]
/// enum BitFieldCompatibleEnum { A, B, C }
/// ```
pub use BitFieldCompatible;
pub use crateRaw;
/// A type that can be used as a bitfield. This is usually [derived] for enums.
/// Structs and unions can implement this explicitly, as the safety requirements cannot be
/// guaranteed for them with `#[derive()]` (at least not easily).
///
/// # Safety
///
/// [`into_raw()`] must provide a value within the range specified by [`SHIFT`] and [`BITS_LEN`].
///
/// [derived]: macro@BitFieldCompatible
/// [`into_raw()`]: BitFieldCompatible::into_raw
/// [`SHIFT`]: BitFieldCompatible::SHIFT
/// [`BITS_LEN`]: BitFieldCompatible::BITS_LEN
pub unsafe