Слияние кода завершено, страница обновится автоматически
// Copyright (c) 2020 Huawei Technologies Co.,Ltd. All rights reserved.
//
// StratoVirt is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan
// PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
/// Macro: Calculate offset of specified field in a type.
#[macro_export]
macro_rules! __offset_of {
($type_name:ty, $field:ident) => {{
let tmp = core::mem::MaybeUninit::<$type_name>::uninit();
let outer = tmp.as_ptr();
// SAFETY: The pointer is valid and aligned, just not initialised; `addr_of` ensures
// that we don't actually read from `outer` (which would be UB) nor create an
// intermediate reference.
let inner = unsafe { core::ptr::addr_of!((*outer).$field) } as *const u8;
// SAFETY: Two pointers are within the same allocation block.
unsafe { inner.offset_from(outer as *const u8) as usize }
}};
}
/// Macro: Calculate offset of a field in a recursive type.
///
/// # Arguments
///
/// The Arguments is: a type name and its field name,
/// follows by a series of sub-type's name and its field's name.
///
/// # Examples
///
/// ```rust
/// #[macro_use]
/// extern crate util;
///
/// fn main() {
/// struct Rectangle {
/// pub length: u64,
/// pub width: u64,
/// }
/// assert_eq!(offset_of!(Rectangle, length), 0);
/// assert_eq!(offset_of!(Rectangle, width), 8);
/// }
/// ```
#[macro_export]
macro_rules! offset_of {
($type_name:ty, $field:ident) => { $crate::__offset_of!($type_name, $field) };
($type_name:ty, $field:ident, $($sub_type_name:ty, $sub_field:ident), +) => {
$crate::__offset_of!($type_name, $field) + offset_of!($($sub_type_name, $sub_field), +)
};
}
#[cfg(test)]
mod tests {
#[test]
fn test_offset_of() {
#[repr(C)]
pub struct Student {
student_id: u32,
weight: u8,
age: u8,
marks: u32,
is_male: bool,
}
assert_eq!(offset_of!(Student, student_id), 0);
assert_eq!(offset_of!(Student, weight), 4);
assert_eq!(offset_of!(Student, age), 5);
assert_eq!(offset_of!(Student, marks), 8);
assert_eq!(offset_of!(Student, is_male), 12);
#[repr(C, packed)]
pub struct Student_packed {
student_id: u32,
weight: u8,
age: u8,
marks: u32,
is_male: bool,
}
assert_eq!(offset_of!(Student_packed, student_id), 0);
assert_eq!(offset_of!(Student_packed, weight), 4);
assert_eq!(offset_of!(Student_packed, age), 5);
assert_eq!(offset_of!(Student_packed, marks), 6);
assert_eq!(offset_of!(Student_packed, is_male), 10);
}
#[test]
fn test_offset_of_recursive() {
mod recursive {
#[repr(C)]
pub struct grand_parent {
pub a: u8,
pub b: u32,
pub c: parent,
}
#[repr(C)]
pub struct parent {
pub a: u16,
pub b: i32,
pub c: son,
}
#[repr(C)]
pub struct son {
pub a: u32,
pub b: u8,
pub c: u64,
}
}
assert_eq!(offset_of!(recursive::grand_parent, a), 0);
assert_eq!(offset_of!(recursive::grand_parent, b), 4);
assert_eq!(offset_of!(recursive::grand_parent, c), 8);
assert_eq!(
offset_of!(recursive::grand_parent, c, recursive::parent, a),
8
);
assert_eq!(
offset_of!(recursive::grand_parent, c, recursive::parent, b),
12
);
assert_eq!(
offset_of!(recursive::grand_parent, c, recursive::parent, c),
16
);
assert_eq!(
offset_of!(
recursive::grand_parent,
c,
recursive::parent,
c,
recursive::son,
a
),
16
);
assert_eq!(
offset_of!(
recursive::grand_parent,
c,
recursive::parent,
c,
recursive::son,
b
),
20
);
assert_eq!(
offset_of!(
recursive::grand_parent,
c,
recursive::parent,
c,
recursive::son,
c
),
24
);
mod recursive_packed {
#[repr(C, packed)]
pub struct grand_parent {
pub a: u32,
pub b: u8,
pub c: parent,
}
#[repr(C, packed)]
pub struct parent {
pub a: u16,
pub b: i32,
pub c: son,
}
#[repr(C, packed)]
pub struct son {
pub a: u32,
pub b: u8,
pub c: u64,
}
}
assert_eq!(offset_of!(recursive_packed::grand_parent, a), 0);
assert_eq!(offset_of!(recursive_packed::grand_parent, b), 4);
assert_eq!(offset_of!(recursive_packed::grand_parent, c), 5);
assert_eq!(
offset_of!(
recursive_packed::grand_parent,
c,
recursive_packed::parent,
a
),
5
);
assert_eq!(
offset_of!(
recursive_packed::grand_parent,
c,
recursive_packed::parent,
b
),
7
);
assert_eq!(
offset_of!(
recursive_packed::grand_parent,
c,
recursive_packed::parent,
c
),
11
);
assert_eq!(
offset_of!(
recursive_packed::grand_parent,
c,
recursive_packed::parent,
c,
recursive_packed::son,
a
),
11
);
assert_eq!(
offset_of!(
recursive_packed::grand_parent,
c,
recursive_packed::parent,
c,
recursive_packed::son,
b
),
15
);
assert_eq!(
offset_of!(
recursive_packed::grand_parent,
c,
recursive_packed::parent,
c,
recursive_packed::son,
c
),
16
);
}
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарий ( 0 )