-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlayout.rs
More file actions
154 lines (126 loc) · 4.42 KB
/
Copy pathlayout.rs
File metadata and controls
154 lines (126 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#![cfg(any(not(feature = "no_alloc"), feature = "std"))]
use {
::core::mem::{align_of, size_of},
memapi2::{error::LayoutErr, helpers::USIZE_HIGH_BIT, layout::Layout},
std::alloc::Layout as StdLayout
};
#[test]
fn layout_from_stdlib() {
let std_layout = StdLayout::from_size_align(1024, 64).unwrap();
let layout = Layout::from_stdlib(std_layout);
assert_eq!(std_layout.size(), layout.size(), "size mismatch");
assert_eq!(std_layout.align(), layout.align(), "align mismatch");
assert_eq!(std_layout, layout.to_stdlib(), "back to stdlib mismatch");
assert_eq!(std_layout, layout, "partialeq mismatch");
}
#[test]
fn layout_to_stdlib() {
let layout = Layout::from_size_align(1024, 64).unwrap();
let std_layout = layout.to_stdlib();
assert_eq!(layout.size(), std_layout.size(), "size mismatch");
assert_eq!(layout.align(), std_layout.align(), "align mismatch");
assert_eq!(layout, Layout::from_stdlib(std_layout), "back to custom mismatch");
assert_eq!(layout, std_layout, "partialeq mismatch");
}
#[test]
fn from_size_align_invalid_zero_align() {
let err = Layout::from_size_align(8, 0).unwrap_err();
assert_eq!(err, LayoutErr::ZeroAlign);
}
#[test]
fn from_size_align_invalid_non_power_of_two() {
let err = Layout::from_size_align(8, 3).unwrap_err();
assert_eq!(err, LayoutErr::NonPowerOfTwoAlign(3));
}
#[test]
fn align_to() {
let l = Layout::from_size_align(16, 8).unwrap();
// no change if aligned to < align
let l2 = l.align_to(4).unwrap();
assert_eq!(l2.size(), 16);
assert_eq!(l2.align(), 8);
// same for == align
let l3 = l.align_to(8).unwrap();
assert_eq!(l3.size(), 16);
assert_eq!(l3.align(), 8);
// should change for higher align
let l4 = l.align_to(16).unwrap();
assert_eq!(l4.size(), 16);
assert_eq!(l4.align(), 16);
}
#[test]
fn padding_needed_for_invalid() {
let l = Layout::from_size_align(6, 8).unwrap();
assert_eq!(l.padding_needed_for(3), Err(LayoutErr::NonPowerOfTwoAlign(3)));
}
#[test]
fn pad_to_align() {
let l = Layout::from_size_align(6, 8).unwrap();
let p = l.pad_to_align();
assert_eq!(p.size(), 8);
assert_eq!(p.align(), 8);
}
#[test]
fn repeat_and_repeat_packed() {
// base layout with size not multiple of align
let base = Layout::from_size_align(3, 2).unwrap();
// repeat uses padded size as stride
let (arr, stride) = base.repeat(3).unwrap();
assert_eq!(stride, base.pad_to_align().size()); // 4
assert_eq!(arr.size(), 12);
assert_eq!(arr.align(), 2);
// repeat_packed uses no padding
let packed = base.repeat_packed(3).unwrap();
assert_eq!(packed.size(), 9);
assert_eq!(packed.align(), 2);
}
#[test]
fn array_layout_basic_and_zst() {
let l = Layout::array::<u16>(3).unwrap();
assert_eq!(l.size(), 6);
assert_eq!(l.align(), 2);
let zst = Layout::array::<()>(10).unwrap();
assert_eq!(zst.size(), 0);
assert_eq!(zst.align(), 1);
}
#[test]
fn array_layout_exceeds_max() {
let max = (USIZE_HIGH_BIT - align_of::<u8>()) / size_of::<u8>();
let err = Layout::array::<u8>(max + 1).unwrap_err();
assert_eq!(err, LayoutErr::ExceedsMax(1, 1, max + 1));
}
#[test]
fn layout_for_value_slice() {
let data = [10u16, 20, 30];
let layout = Layout::for_value(&data[..]);
assert_eq!(layout.size(), size_of::<u16>() * data.len());
assert_eq!(layout.align(), align_of::<u16>());
}
#[test]
fn layout_for_value_raw() {
let value = 42u32;
let ptr = &value as *const u32;
let layout = unsafe { Layout::for_value_raw(ptr) };
assert_eq!(layout, Layout::new::<u32>());
}
#[test]
fn align_to_multiple_of_rounds_up() {
let l = unsafe { Layout::from_size_align_unchecked(30, 8) };
let rounded = l.align_to_multiple_of(16).unwrap();
assert_eq!(rounded.align(), 16);
assert_eq!(rounded.size(), 30);
let same = rounded.align_to_multiple_of(8).unwrap();
assert_eq!(same, rounded);
}
#[test]
fn posix_memalign_compatible_roundtrip() {
let original = Layout::from_size_align(10, 1).unwrap();
let compatible = original.to_posix_memalign_compatible().unwrap();
let from_fn = Layout::posix_memalign_compatible_from_size_align(10, 1).unwrap();
let ptr_sz = size_of::<usize>();
assert_eq!(compatible, from_fn);
assert!(compatible.align() >= ptr_sz);
assert_eq!(compatible.align() % ptr_sz, 0);
assert!(compatible.size() >= original.size());
assert!(compatible.align().is_power_of_two());
}