1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/openeuler-stratovirt

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Это зеркальный репозиторий, синхронизируется ежедневно с исходного репозитория.
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
offsetof.rs 7 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
yexiao Отправлено год назад 8c394a6
// 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 )

Вы можете оставить комментарий после Вход в систему

1
https://gitlife.ru/oschina-mirror/openeuler-stratovirt.git
git@gitlife.ru:oschina-mirror/openeuler-stratovirt.git
oschina-mirror
openeuler-stratovirt
openeuler-stratovirt
master