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
use MaybeUninit;
use AtomicU64;
use crate;
/// Marker for types that are sound to reinterpret raw bytes as, in either direction:
/// an arbitrary byte buffer can be read as them, and their own bytes can be read raw.
///
/// A private mirror of this trait lives in `zisk-stream` (`zisk_stream.rs`), which cannot
/// depend on `zisk-common`; keep the two in sync.
///
/// # Safety
///
/// Implementors must both:
/// - accept *every* bit pattern as a valid value (so an arbitrary byte buffer can be
/// reinterpreted into them — the destination requirement), and
/// - contain no padding or otherwise uninitialized bytes (so reading their own bytes is
/// never a read of uninitialized memory — the source requirement).
///
/// Integer types qualify; `bool`, `char`, `NonZero*`, niche enums, references, and structs
/// with padding do not.
pub unsafe
// SAFETY: `u8` has no invalid bit patterns.
unsafe
// SAFETY: `u64` has no invalid bit patterns.
unsafe
/// Creates a `Vec<AtomicU64>` of `size` elements by zeroing the backing allocation in
/// bulk instead of constructing each element — a fast path for atomic counters.
/// Reinterprets a `Vec<T>` as a `Vec<U>` over the same bytes.
///
/// A private mirror of this function lives in `zisk-stream` (`zisk_stream.rs`), which
/// cannot depend on `zisk-common`; keep the two in sync.
///
/// When the source allocation can legally be handed to `Vec<U>`'s deallocator —
/// identical element alignment and a byte length/capacity that are whole numbers of `U`
/// — the buffer is reused in place (zero-copy). Otherwise (e.g. `u8` → `u64`, where the
/// alignment differs) the bytes are copied into a fresh `Vec<U>` allocated — and
/// therefore freed — under `U`'s own layout, so the result is sound to drop on any
/// global allocator.
///
/// If the byte length is not a whole number of `U`, the trailing partial `U` is
/// zero-padded. Callers streaming data in chunks must therefore cut on `size_of::<U>()`
/// boundaries, or the padding will shift every subsequent value.
///
/// The `T: AnyBitPattern` bound guarantees the source bytes are fully initialized (no
/// padding to read as uninitialized memory) and the `U: AnyBitPattern` bound guarantees
/// the reinterpreted bytes form valid `U` values, so this function is safe.
///
/// # Arguments
/// * `v` - The source vector to reinterpret.
///
/// # Type Parameters
/// * `T` - Source element type; must be `Copy` (destructor-free and bitwise-copyable, so
/// drop behavior is identical on the zero-copy and copy paths) and `AnyBitPattern` (no
/// padding/uninitialized bytes, so reading its raw bytes is sound).
/// * `U` - Destination element type; must be `AnyBitPattern`.
///
/// # Errors
///
/// - [`CommonError::Invalid`] if `U` is a zero-sized type.