1#[doc(hidden)]
29pub mod sealed {
30 #[doc(hidden)]
31 pub(crate) struct SealToken;
32
33 #[allow(private_interfaces)]
34 pub trait Sealed {
35 #[doc(hidden)]
36 fn _sealed() -> SealToken;
37 }
38}
39
40pub trait ActiveSet: sealed::Sealed + Copy + 'static {
46 const MASK: u64;
48 const NAME: &'static str;
50}
51
52#[diagnostic::on_unimplemented(
57 message = "`{Self}` is not the complement of `{Other}` — cannot merge these sub-warps",
58 label = "merge requires complementary active sets (e.g., Even + Odd, LowHalf + HighHalf)",
59 note = "use `diverge_even_odd()` or `diverge_halves()` to create valid complement pairs, then merge them"
60)]
61pub trait ComplementOf<Other: ActiveSet>: sealed::Sealed + ActiveSet {}
62
63pub trait ComplementWithin<Other: ActiveSet, Parent: ActiveSet>:
68 sealed::Sealed + ActiveSet
69{
70}
71
72#[diagnostic::on_unimplemented(
76 message = "`{Self}` cannot be split into `{TrueBranch}` + `{FalseBranch}`",
77 label = "this diverge pattern is not defined in the active set hierarchy",
78 note = "valid diverge patterns: All → Even/Odd, All → LowHalf/HighHalf, Even → EvenLow/EvenHigh, etc."
79)]
80pub trait CanDiverge<TrueBranch: ActiveSet, FalseBranch: ActiveSet>:
81 sealed::Sealed + ActiveSet + Sized
82{
83 fn diverge(
84 warp: crate::warp::Warp<Self>,
85 ) -> (
86 crate::warp::Warp<TrueBranch>,
87 crate::warp::Warp<FalseBranch>,
88 );
89}
90
91#[derive(Copy, Clone, Debug, Default)]
93pub struct Empty;
94#[allow(private_interfaces)]
95impl sealed::Sealed for Empty {
96 fn _sealed() -> sealed::SealToken {
97 sealed::SealToken
98 }
99}
100impl ActiveSet for Empty {
101 const MASK: u64 = 0;
102 const NAME: &'static str = "Empty";
103}
104
105warp_types_macros::warp_sets! {
117 All = 0xFFFFFFFF {
118 Even = 0x55555555 / Odd = 0xAAAAAAAA,
119 LowHalf = 0x0000FFFF / HighHalf = 0xFFFF0000,
120 Lane0 = 0x00000001 / NotLane0 = 0xFFFFFFFE,
121 }
122 Even = 0x55555555 {
123 EvenLow = 0x00005555 / EvenHigh = 0x55550000,
124 }
125 Odd = 0xAAAAAAAA {
126 OddLow = 0x0000AAAA / OddHigh = 0xAAAA0000,
127 }
128 LowHalf = 0x0000FFFF {
129 EvenLow = 0x00005555 / OddLow = 0x0000AAAA,
130 }
131 HighHalf = 0xFFFF0000 {
132 EvenHigh = 0x55550000 / OddHigh = 0xAAAA0000,
133 }
134}
135
136impl ComplementOf<Empty> for All {}
139impl ComplementOf<All> for Empty {}
140
141#[cfg(test)]
147mod tests {
148 use super::*;
149
150 #[test]
151 fn test_mask_values() {
152 assert_eq!(All::MASK, 0xFFFFFFFF);
153 assert_eq!(Empty::MASK, 0x00000000);
154 assert_eq!(Even::MASK, 0x55555555);
155 assert_eq!(Odd::MASK, 0xAAAAAAAA);
156 assert_eq!(LowHalf::MASK, 0x0000FFFF);
157 assert_eq!(HighHalf::MASK, 0xFFFF0000);
158 assert_eq!(Lane0::MASK, 0x00000001);
159 assert_eq!(NotLane0::MASK, 0xFFFFFFFE);
160 assert_eq!(EvenLow::MASK, 0x00005555);
161 assert_eq!(EvenHigh::MASK, 0x55550000);
162 assert_eq!(OddLow::MASK, 0x0000AAAA);
163 assert_eq!(OddHigh::MASK, 0xAAAA0000);
164 }
165
166 #[test]
167 fn test_intersection_properties() {
168 assert_eq!(Even::MASK & LowHalf::MASK, EvenLow::MASK);
169 assert_eq!(Even::MASK & HighHalf::MASK, EvenHigh::MASK);
170 assert_eq!(Odd::MASK & LowHalf::MASK, OddLow::MASK);
171 assert_eq!(Odd::MASK & HighHalf::MASK, OddHigh::MASK);
172 }
173
174 #[test]
175 fn test_union_properties() {
176 assert_eq!(EvenLow::MASK | EvenHigh::MASK, Even::MASK);
177 assert_eq!(OddLow::MASK | OddHigh::MASK, Odd::MASK);
178 assert_eq!(EvenLow::MASK | OddLow::MASK, LowHalf::MASK);
179 assert_eq!(EvenHigh::MASK | OddHigh::MASK, HighHalf::MASK);
180 assert_eq!(
181 EvenLow::MASK | EvenHigh::MASK | OddLow::MASK | OddHigh::MASK,
182 All::MASK
183 );
184 }
185
186 #[test]
187 fn test_pairwise_disjoint() {
188 let sets = [EvenLow::MASK, EvenHigh::MASK, OddLow::MASK, OddHigh::MASK];
189 for i in 0..sets.len() {
190 for j in (i + 1)..sets.len() {
191 assert_eq!(sets[i] & sets[j], 0, "sets {} and {} overlap", i, j);
192 }
193 }
194 }
195
196 #[test]
197 fn test_complement_symmetry() {
198 assert_eq!(Even::MASK | Odd::MASK, All::MASK);
199 assert_eq!(Even::MASK & Odd::MASK, 0);
200 assert_eq!(LowHalf::MASK | HighHalf::MASK, All::MASK);
201 assert_eq!(LowHalf::MASK & HighHalf::MASK, 0);
202 assert_eq!(Lane0::MASK | NotLane0::MASK, All::MASK);
203 assert_eq!(Lane0::MASK & NotLane0::MASK, 0);
204 }
205}