@@ -1184,6 +1184,88 @@ where
1184
1184
}
1185
1185
}
1186
1186
1187
+ /// Apply a function to an `impl `[`FnBind`][]`<_>`'s output.
1188
+ ///
1189
+ /// # Example
1190
+ ///
1191
+ /// ```rust
1192
+ /// #![feature(const_fn_trait_bound)]
1193
+ /// #![feature(const_trait_impl)]
1194
+ /// #![feature(const_mut_refs)]
1195
+ /// use core::cell::UnsafeCell;
1196
+ /// use r3_core::{kernel::{cfg, traits}, bind::{Bind, FnBind, fn_bind_map}};
1197
+ ///
1198
+ /// /// Like `r3::bind::bind` but wraps the output in `UnsafeCell`
1199
+ /// const fn unsafe_cell_bind<'pool, C, Binder, Func, T>(
1200
+ /// cfg: &mut cfg::Cfg<'pool, C>,
1201
+ /// binder: Binder,
1202
+ /// func: Func,
1203
+ /// ) -> Bind<'pool, C::System, UnsafeCell<T>>
1204
+ /// where
1205
+ /// C: ~const traits::CfgBase,
1206
+ /// C::System: traits::KernelBase + traits::KernelStatic,
1207
+ /// Func: ~const FnBind<Binder, Output = T>,
1208
+ /// T: 'static,
1209
+ /// {
1210
+ /// Bind::define()
1211
+ /// // Apply `UnsafeCell::new` on `func`'s output
1212
+ /// .init_with_bind(binder, fn_bind_map(func, UnsafeCell::new))
1213
+ /// .finish(cfg)
1214
+ /// }
1215
+ /// ```
1216
+ pub const fn fn_bind_map < FnBind , Mapper > (
1217
+ inner : FnBind ,
1218
+ mapper : Mapper ,
1219
+ ) -> FnBindMap < FnBind , Mapper > {
1220
+ FnBindMap { inner, mapper }
1221
+ }
1222
+
1223
+ /// Applies a function to a [`FnBind`][]'s output.
1224
+ ///
1225
+ /// Created by [`fn_bind_map`][].
1226
+ pub struct FnBindMap < Inner , Mapper > {
1227
+ inner : Inner ,
1228
+ mapper : Mapper ,
1229
+ }
1230
+
1231
+ impl < Binder , Inner , InnerBoundFn , Output , Mapper , NewOutput > const FnBind < Binder >
1232
+ for FnBindMap < Inner , Mapper >
1233
+ where
1234
+ Inner : ~const FnBind < Binder , Output = Output , BoundFn = InnerBoundFn > ,
1235
+ InnerBoundFn : FnOnce ( ) -> Output + Copy + Send + ' static ,
1236
+ Output : ' static ,
1237
+ Mapper : FnOnce ( Output ) -> NewOutput + Copy + Send + ' static ,
1238
+ NewOutput : ' static ,
1239
+ {
1240
+ type Output = NewOutput ;
1241
+
1242
+ // FIXME: `impl` type alias in trait impls implicitly captures the
1243
+ // surrounding environment's generic parameters? That's probably why this
1244
+ // `impl` type alias has to stay outside this `impl` block.
1245
+ type BoundFn = MappedBoundFn < InnerBoundFn , Output , Mapper , NewOutput > ;
1246
+
1247
+ fn bind ( self , binder : Binder , ctx : & mut CfgBindCtx < ' _ > ) -> Self :: BoundFn {
1248
+ map_bind_inner ( self . inner . bind ( binder, ctx) , self . mapper )
1249
+ }
1250
+ }
1251
+
1252
+ type MappedBoundFn < InnerBoundFn , Output , Mapper , NewOutput >
1253
+ where
1254
+ InnerBoundFn : Copy + Send + ' static ,
1255
+ Mapper : Copy + Send + ' static ,
1256
+ = impl FnOnce ( ) -> NewOutput + Copy + Send + ' static ;
1257
+
1258
+ const fn map_bind_inner < InnerBoundFn , Output , Mapper , NewOutput > (
1259
+ inner_bound_fn : InnerBoundFn ,
1260
+ mapper : Mapper ,
1261
+ ) -> MappedBoundFn < InnerBoundFn , Output , Mapper , NewOutput >
1262
+ where
1263
+ InnerBoundFn : FnOnce ( ) -> Output + Copy + Send + ' static ,
1264
+ Mapper : FnOnce ( Output ) -> NewOutput + Copy + Send + ' static ,
1265
+ {
1266
+ move || ( mapper) ( inner_bound_fn ( ) )
1267
+ }
1268
+
1187
1269
// Binder traits
1188
1270
// ----------------------------------------------------------------------------
1189
1271
0 commit comments