@@ -119,7 +119,6 @@ impl<T: DriverOps> Drop for Registration<T> {
119
119
/// - [`RawDeviceId::ZERO`] is actually a zeroed-out version of the raw device id.
120
120
/// - [`RawDeviceId::to_rawid`] stores `offset` in the context/data field of the raw device id so
121
121
/// that buses can recover the pointer to the data.
122
- #[ const_trait]
123
122
pub unsafe trait RawDeviceId {
124
123
/// The raw type that holds the device id.
125
124
///
@@ -131,13 +130,6 @@ pub unsafe trait RawDeviceId {
131
130
/// Id tables created from [`Self`] use [`Self::ZERO`] as the sentinel to indicate the end of
132
131
/// the table.
133
132
const ZERO : Self :: RawType ;
134
-
135
- /// Converts an id into a raw id.
136
- ///
137
- /// `offset` is the offset from the memory location where the raw device id is stored to the
138
- /// location where its associated context information is stored. Implementations must store
139
- /// this in the appropriate context/data field of the raw type.
140
- fn to_rawid ( & self , offset : isize ) -> Self :: RawType ;
141
133
}
142
134
143
135
/// A zero-terminated device id array, followed by context data.
@@ -149,44 +141,102 @@ pub struct IdArray<T: RawDeviceId, U, const N: usize> {
149
141
}
150
142
151
143
impl < T : RawDeviceId , U , const N : usize > IdArray < T , U , N > {
144
+ const U_NONE : Option < U > = None ;
145
+
146
+ /// Returns an `IdTable` backed by `self`.
147
+ ///
148
+ /// This is used to essentially erase the array size.
149
+ pub const fn as_table ( & self ) -> IdTable < ' _ , T , U > {
150
+ IdTable {
151
+ first : & self . ids [ 0 ] ,
152
+ _p : PhantomData ,
153
+ }
154
+ }
155
+
156
+ /// Returns the number of items in the ID table.
157
+ pub const fn count ( & self ) -> usize {
158
+ self . ids . len ( )
159
+ }
160
+
161
+ /// Returns the inner IdArray array, without the context data.
162
+ // pub const fn as_ids(&self) -> IdArrayIds<T, N>
163
+ // where
164
+ // T: RawDeviceId + Copy,
165
+ // {
166
+ // self.ids
167
+ // }
168
+
152
169
/// Creates a new instance of the array.
153
170
///
154
171
/// The contents are derived from the given identifiers and context information.
155
- pub const fn new ( ids : [ T ; N ] , infos : [ Option < U > ; N ] ) -> Self
172
+ #[ doc( hidden) ]
173
+ pub const unsafe fn new ( raw_ids : [ T :: RawType ; N ] , infos : [ Option < U > ; N ] ) -> Self
156
174
where
157
- T : ~const RawDeviceId + Copy ,
175
+ T : RawDeviceId + Copy ,
176
+ T :: RawType : Copy + Clone ,
158
177
{
159
- let mut array = Self {
160
- ids : [ T :: ZERO ; N ] ,
178
+ Self {
179
+ ids : raw_ids ,
161
180
sentinel : T :: ZERO ,
162
181
id_infos : infos,
163
- } ;
164
- let mut i = 0usize ;
165
- while i < N {
166
- // SAFETY: Both pointers are within `array` (or one byte beyond), consequently they are
167
- // derived from the same allocated object. We are using a `u8` pointer, whose size 1,
168
- // so the pointers are necessarily 1-byte aligned.
169
- let offset = unsafe {
170
- ( & array. id_infos [ i] as * const _ as * const u8 )
171
- . offset_from ( & array. ids [ i] as * const _ as _ )
172
- } ;
173
- array. ids [ i] = ids[ i] . to_rawid ( offset) ;
174
- i += 1 ;
175
182
}
176
- array
177
183
}
178
184
179
- /// Returns an `IdTable` backed by `self`.
180
- ///
181
- /// This is used to essentially erase the array size.
182
- pub const fn as_table ( & self ) -> IdTable < ' _ , T , U > {
183
- IdTable {
184
- first : & self . ids [ 0 ] ,
185
- _p : PhantomData ,
186
- }
185
+ #[ doc( hidden) ]
186
+ pub const fn get_offset ( idx : usize ) -> isize
187
+ where
188
+ T : RawDeviceId + Copy ,
189
+ T :: RawType : Copy + Clone ,
190
+ {
191
+ // SAFETY: We are only using this dummy value to get offsets.
192
+ let array = unsafe { Self :: new ( [ T :: ZERO ; N ] , [ Self :: U_NONE ; N ] ) } ;
193
+ // SAFETY: Both pointers are within `array` (or one byte beyond), consequently they are
194
+ // derived from the same allocated object. We are using a `u8` pointer, whose size 1,
195
+ // so the pointers are necessarily 1-byte aligned.
196
+ let ret = unsafe {
197
+ ( & array. id_infos [ idx] as * const _ as * const u8 )
198
+ . offset_from ( & array. ids [ idx] as * const _ as _ )
199
+ } ;
200
+ core:: mem:: forget ( array) ;
201
+ ret
187
202
}
188
203
}
189
204
205
+ // Creates a new ID array. This is a macro so it can take as a parameter the concrete ID type in order
206
+ // to call to_rawid() on it, and still remain const. This is necessary until a new const_trait_impl
207
+ // implementation lands, since the existing implementation was removed in Rust 1.73.
208
+ #[ macro_export]
209
+ #[ doc( hidden) ]
210
+ macro_rules! _new_id_array {
211
+ ( ( $( $args: tt) * ) , $id_type: ty) => { {
212
+ /// Creates a new instance of the array.
213
+ ///
214
+ /// The contents are derived from the given identifiers and context information.
215
+ const fn new< U , const N : usize >( ids: [ $id_type; N ] , infos: [ Option <U >; N ] )
216
+ -> $crate:: driver:: IdArray <$id_type, U , N >
217
+ where
218
+ $id_type: $crate:: driver:: RawDeviceId + Copy ,
219
+ <$id_type as $crate:: driver:: RawDeviceId >:: RawType : Copy + Clone ,
220
+ {
221
+ let mut raw_ids =
222
+ [ <$id_type as $crate:: driver:: RawDeviceId >:: ZERO ; N ] ;
223
+ let mut i = 0usize ;
224
+ while i < N {
225
+ let offset: isize = $crate:: driver:: IdArray :: <$id_type, U , N >:: get_offset( i) ;
226
+ raw_ids[ i] = ids[ i] . to_rawid( offset) ;
227
+ i += 1 ;
228
+ }
229
+
230
+ // SAFETY: We are passing valid arguments computed with the correct offsets.
231
+ unsafe {
232
+ $crate:: driver:: IdArray :: <$id_type, U , N >:: new( raw_ids, infos)
233
+ }
234
+ }
235
+
236
+ new( $( $args) * )
237
+ } }
238
+ }
239
+
190
240
/// A device id table.
191
241
///
192
242
/// The table is guaranteed to be zero-terminated and to be followed by an array of context data of
@@ -337,8 +387,8 @@ macro_rules! define_id_array {
337
387
( $table_name: ident, $id_type: ty, $data_type: ty, [ $( $t: tt) * ] ) => {
338
388
const $table_name:
339
389
$crate:: driver:: IdArray <$id_type, $data_type, { $crate:: count_paren_items!( $( $t) * ) } > =
340
- $crate:: driver :: IdArray :: new (
341
- $crate:: first_item!( $id_type, $( $t) * ) , $crate:: second_item!( $( $t) * ) ) ;
390
+ $crate:: _new_id_array! ( (
391
+ $crate:: first_item!( $id_type, $( $t) * ) , $crate:: second_item!( $( $t) * ) ) , $id_type ) ;
342
392
} ;
343
393
}
344
394
0 commit comments