#[macro_export(local_inner_macros)]
macro_rules! const_assert_impl {
($val:ident: $tr:path) => {{
const fn value_must_impl<T: $tr>(_: &T) {}
value_must_impl(&$val);
}};
($val:ident: $tr:path, $($rest:path),+) => {
const_assert_impl!($val: $tr);
const_assert_impl!($val: $($rest),+);
};
($ty:ty: $tr:path) => {{
const fn type_must_impl<T: $tr>() {}
type_must_impl::<$ty>();
}};
($ty:ty: $tr:path, $($rest:path),+) => {
const_assert_impl!($ty: $tr);
const_assert_impl!($ty: $($rest),+);
};
({$val:expr}: $($tr:path),+) => {{
let tmp = $val;
const_assert_impl!(tmp: $($tr),+)
}};
}
#[macro_export(local_inner_macros)]
macro_rules! const_assert_align {
(?const_expr ($x:expr)) => {
const _: [(); 0 - !{ const ASSERT: bool = $x; ASSERT } as usize] = [];
};
($ty:ty, $align:expr) => {{
const_assert_align!(?const_expr (::std::mem::align_of::<$ty>() == $align));
}};
}
#[macro_export(local_inner_macros)]
macro_rules! packed_read {
($val:ident.$field:ident) => {{
const_assert_impl!({$val.$field}: ::std::marker::Copy);
let brw = ::std::ptr::addr_of!($val.$field);
unsafe { brw.read_unaligned() }
}};
(($expr:expr).$field:ident) => {{
let tmp = $expr;
packed_read!(tmp.$field)
}};
}
#[macro_export(local_inner_macros)]
macro_rules! unaligned_read {
($val:ident) => {{
let brw = ::std::ptr::addr_of!(*$val);
let alg = unsafe { brw.read_unaligned() };
const_assert_impl!(alg: ::std::marker::Copy);
alg
}};
($expr:expr) => {{
let tmp = $expr;
unaligned_read!(tmp)
}};
}
#[macro_export]
macro_rules! unaligned_ref_read {
($ptr:ident as $ty:ty) => {{
debug_assert!(!$ptr.is_null());
let r: $ty = unsafe { $ptr.read_unaligned() };
r
}};
}
#[macro_export]
macro_rules! unaligned_do {
($ptr:ident as $ty:ty => |$arg:ident| $closure:expr) => {{
debug_assert!(!$ptr.is_null());
let $arg: $ty = unsafe { $ptr.read_unaligned() };
let _returned = $closure;
::std::mem::forget($arg);
_returned
}};
}
#[macro_export(local_inner_macros)]
macro_rules! define_serialize_chained {
(&$ty:ty => |$zelf:ident, $dest:ident| $closure:expr) => {
#[inline]
fn _serialize_chained<W: Write>(&self, dest: &mut W) -> $crate::SeResult<usize> {
let $zelf: &$ty = self;
let $dest = dest;
$closure
}
#[inline]
unsafe fn _serialize_chained_unaligned<W: ::std::io::Write>(zelf: *const Self, dest: &mut W) -> $crate::SeResult<usize> {
let $zelf: &$ty = unaligned_ref_read!(zelf as &$ty);
let $dest = dest;
$closure
}
};
(*$ty:ty => |$zelf:ident, $dest:ident| $closure:expr) => {
#[inline]
fn _serialize_chained<W: ::std::io::Write>(&self, dest: &mut W) -> $crate::SeResult<usize> {
let $zelf: $ty = *self;
let $dest = dest;
$closure
}
#[inline]
unsafe fn _serialize_chained_unaligned<W: ::std::io::Write>(zelf: *const Self, dest: &mut W) -> $crate::SeResult<usize> {
let $zelf: $ty = unaligned_read!(zelf);
let $dest = dest;
$closure
}
};
($ty:ty => |$zelf:ident, $dest:ident| $closure:expr) => {
#[inline]
fn _serialize_chained<W: ::std::io::Write>(&self, dest: &mut W) -> $crate::SeResult<usize> {
let $zelf: &$ty = self;
let $dest = dest;
$closure
}
#[inline]
unsafe fn _serialize_chained_unaligned<W: ::std::io::Write>(zelf: *const Self, dest: &mut W) -> $crate::SeResult<usize> {
let $dest = dest;
unaligned_do!(zelf as $ty => |$zelf| $closure)
}
};
}