1#![doc = include_str!("../../doc/slice/ops.md")]
2
3use core::ops::{
4 BitAnd,
5 BitAndAssign,
6 BitOr,
7 BitOrAssign,
8 BitXor,
9 BitXorAssign,
10 Index,
11 IndexMut,
12 Not,
13 Range,
14 RangeFrom,
15 RangeFull,
16 RangeInclusive,
17 RangeTo,
18 RangeToInclusive,
19};
20
21use super::{
22 BitSlice,
23 BitSliceIndex,
24};
25use crate::{
26 domain::Domain,
27 order::{
28 BitOrder,
29 Lsb0,
30 Msb0,
31 },
32 store::BitStore,
33};
34
35impl<T1, T2, O1, O2> BitAndAssign<&BitSlice<T2, O2>> for BitSlice<T1, O1>
36where
37 T1: BitStore,
38 T2: BitStore,
39 O1: BitOrder,
40 O2: BitOrder,
41{
42 #[inline]
43 #[doc = include_str!("../../doc/slice/bitop_assign.md")]
44 fn bitand_assign(&mut self, rhs: &BitSlice<T2, O2>) {
45 if let (Some(this), Some(that)) =
46 (self.coerce_mut::<T1, Lsb0>(), rhs.coerce::<T1, Lsb0>())
47 {
48 return this.sp_bitop_assign(that, BitAnd::bitand, BitAnd::bitand);
49 }
50 if let (Some(this), Some(that)) =
51 (self.coerce_mut::<T1, Msb0>(), rhs.coerce::<T1, Msb0>())
52 {
53 return this.sp_bitop_assign(that, BitAnd::bitand, BitAnd::bitand);
54 }
55 for (this, that) in self.as_mut_bitptr_range().zip(rhs.as_bitptr_range())
56 {
57 unsafe {
58 this.write(this.read() & that.read());
59 }
60 }
61 if let Some(rem) = self.get_mut(rhs.len() ..) {
62 rem.fill(false);
63 }
64 }
65}
66
67impl<T1, T2, O1, O2> BitOrAssign<&BitSlice<T2, O2>> for BitSlice<T1, O1>
68where
69 T1: BitStore,
70 T2: BitStore,
71 O1: BitOrder,
72 O2: BitOrder,
73{
74 #[inline]
75 #[doc = include_str!("../../doc/slice/bitop_assign.md")]
76 fn bitor_assign(&mut self, rhs: &BitSlice<T2, O2>) {
77 if let (Some(this), Some(that)) =
78 (self.coerce_mut::<T1, Lsb0>(), rhs.coerce::<T1, Lsb0>())
79 {
80 return this.sp_bitop_assign(that, BitOr::bitor, BitOr::bitor);
81 }
82 if let (Some(this), Some(that)) =
83 (self.coerce_mut::<T1, Msb0>(), rhs.coerce::<T1, Msb0>())
84 {
85 return this.sp_bitop_assign(that, BitOr::bitor, BitOr::bitor);
86 }
87 for (this, that) in self.as_mut_bitptr_range().zip(rhs.as_bitptr_range())
88 {
89 unsafe {
90 this.write(this.read() | that.read());
91 }
92 }
93 }
94}
95
96impl<T1, T2, O1, O2> BitXorAssign<&BitSlice<T2, O2>> for BitSlice<T1, O1>
97where
98 T1: BitStore,
99 T2: BitStore,
100 O1: BitOrder,
101 O2: BitOrder,
102{
103 #[inline]
104 #[doc = include_str!("../../doc/slice/bitop_assign.md")]
105 fn bitxor_assign(&mut self, rhs: &BitSlice<T2, O2>) {
106 if let (Some(this), Some(that)) =
107 (self.coerce_mut::<T1, Lsb0>(), rhs.coerce::<T1, Lsb0>())
108 {
109 return this.sp_bitop_assign(that, BitXor::bitxor, BitXor::bitxor);
110 }
111 if let (Some(this), Some(that)) =
112 (self.coerce_mut::<T1, Msb0>(), rhs.coerce::<T1, Msb0>())
113 {
114 return this.sp_bitop_assign(that, BitXor::bitxor, BitXor::bitxor);
115 }
116 for (this, that) in self.as_mut_bitptr_range().zip(rhs.as_bitptr_range())
117 {
118 unsafe {
119 this.write(this.read() ^ that.read());
120 }
121 }
122 }
123}
124
125impl<T, O> Index<usize> for BitSlice<T, O>
126where
127 T: BitStore,
128 O: BitOrder,
129{
130 type Output = bool;
131
132 #[inline]
158 fn index(&self, index: usize) -> &Self::Output {
159 match *index.index(self) {
160 true => &true,
161 false => &false,
162 }
163 }
164}
165
166macro_rules! index {
168 ($($t:ty),+ $(,)?) => { $(
169 impl<T, O> Index<$t> for BitSlice<T, O>
170 where
171 O: BitOrder,
172 T: BitStore,
173 {
174 type Output = Self;
175
176 #[inline]
177 #[track_caller]
178 fn index(&self, index: $t) -> &Self::Output {
179 index.index(self)
180 }
181 }
182
183 impl<T, O> IndexMut<$t> for BitSlice<T, O>
184 where
185 O: BitOrder,
186 T: BitStore,
187 {
188 #[inline]
189 #[track_caller]
190 fn index_mut(&mut self, index: $t) -> &mut Self::Output {
191 index.index_mut(self)
192 }
193 }
194 )+ };
195}
196
197index! {
198 Range<usize>,
199 RangeFrom<usize>,
200 RangeFull,
201 RangeInclusive<usize>,
202 RangeTo<usize>,
203 RangeToInclusive<usize>,
204}
205
206impl<'a, T, O> Not for &'a mut BitSlice<T, O>
213where
214 T: BitStore,
215 O: BitOrder,
216{
217 type Output = Self;
218
219 #[inline]
220 fn not(self) -> Self::Output {
221 match self.domain_mut() {
222 Domain::Enclave(mut elem) => {
223 elem.invert();
224 },
225 Domain::Region { head, body, tail } => {
226 if let Some(mut elem) = head {
227 elem.invert();
228 }
229 for elem in body {
230 elem.store_value(!elem.load_value());
231 }
232 if let Some(mut elem) = tail {
233 elem.invert();
234 }
235 },
236 }
237 self
238 }
239}