Skip to content
Snippets Groups Projects
Commit c3d8c52e authored by Guanqun Lu's avatar Guanqun Lu Committed by Gav Wood
Browse files

enhance the environmental macro (#683)

parent d7d591cf
No related merge requests found
......@@ -217,6 +217,32 @@ macro_rules! environmental {
}
}
};
($name:ident<$traittype:ident> : trait $t:ident <$concretetype:ty>) => {
#[allow(non_camel_case_types, dead_code)]
struct $name <H: $traittype> { _private_field: $crate::imp::PhantomData<H> }
thread_local_impl!(static GLOBAL: $crate::imp::RefCell<Option<*mut ($t<$concretetype> + 'static)>>
= $crate::imp::RefCell::new(None));
impl<H: $traittype> $name<H> {
#[allow(unused_imports)]
pub fn using<R, F: FnOnce() -> R>(
protected: &mut $t<H>,
f: F
) -> R {
let lifetime_extended = unsafe {
$crate::imp::transmute::<&mut $t<H>, &mut ($t<$concretetype> + 'static)>(protected)
};
$crate::using(&GLOBAL, lifetime_extended, f)
}
pub fn with<R, F: for<'a> FnOnce(&'a mut ($t<$concretetype> + 'a)) -> R>(
f: F
) -> Option<R> {
$crate::with(&GLOBAL, |x| f(x))
}
}
};
($name:ident : trait $t:ident <>) => { environmental! { $name : trait @$t [] } };
($name:ident : trait $t:ident < $($args:ty),* $(,)* >) => { environmental! { $name : trait @$t [$($args,)*] } };
($name:ident : trait $t:ident) => { environmental! { $name : trait @$t [] } };
......@@ -345,11 +371,11 @@ mod tests {
let numbers = vec![1, 2, 3];
let mut numbers = &numbers[..];
let out = foo::using(&mut numbers, || {
foo::with(|x| x.mul_and_add() )
let out = foo::<ConcretePlus>::using(&mut numbers, || {
foo::<ConcretePlus>::with(|x| x.mul_and_add() )
}).unwrap();
assert_eq!(out, 6 + 42);
environmental!(foo: trait Multiplier<ConcretePlus>);
environmental!(foo<Plus>: trait Multiplier<ConcretePlus>);
}
}
......@@ -20,6 +20,7 @@ pub mod imp {
pub use std::thread::LocalKey;
pub use std::mem::transmute;
pub use std::mem::replace;
pub use std::marker::PhantomData;
}
#[doc(hidden)]
......
......@@ -19,6 +19,7 @@ pub mod imp {
pub use core::cell::RefCell;
pub use core::mem::transmute;
pub use core::mem::replace;
pub use core::marker::PhantomData;
// This code is a simplified version of [`LocalKey`] and it's wasm32 specialization: [`statik::Key`].
// [`LocalKey`]: https://github.com/alexcrichton/rust/blob/98931165a23a1c2860d99759385f45d6807c8982/src/libstd/thread/local.rs#L89
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment