Skip to main content

xwrust/
xwbmp.rs

1//! XWOS RUST:位图数组
2//! ========
3//!
4//!
5
6extern crate core;
7use core::ffi::*;
8use core::cmp::{PartialOrd, Ordering};
9use core::cell::UnsafeCell;
10use core::ops::*;
11use core::fmt;
12
13use crate::types::*;
14
15extern "C" {
16    pub(crate) fn xwbmpop_cmp(bmp: *mut c_void, opt: *mut c_void, num: XwSz) -> XwSsq;
17    pub(crate) fn xwbmpop_s1all(bmp: *mut c_void, num: XwSz);
18    pub(crate) fn xwbmpop_c0all(bmp: *mut c_void, num: XwSz);
19    pub(crate) fn xwbmpop_s1i(bmp: *mut c_void, n: XwSq);
20    pub(crate) fn xwbmpop_s1m(bmp: *mut c_void, msk: *mut c_void, num: XwSz);
21    pub(crate) fn xwbmpop_c0i(bmp: *mut c_void, n: XwSq);
22    pub(crate) fn xwbmpop_c0m(bmp: *mut c_void, msk: *mut c_void, num: XwSz);
23    pub(crate) fn xwbmpop_x1i(bmp: *mut c_void, n: XwSq);
24    pub(crate) fn xwbmpop_x1m(bmp: *mut c_void, msk: *mut c_void, num: XwSz);
25    pub(crate) fn xwbmpop_t1i(bmp: *mut c_void, n: XwSq) -> bool;
26    pub(crate) fn xwbmpop_t1ma(bmp: *mut c_void, msk: *mut c_void, num: XwSz) -> bool;
27    pub(crate) fn xwbmpop_t1ma_then_c0m(bmp: *mut c_void, msk: *mut c_void, num: XwSz) -> bool;
28    pub(crate) fn xwbmpop_t1mo(bmp: *mut c_void, msk: *mut c_void, num: XwSz) -> bool;
29    pub(crate) fn xwbmpop_t1mo_then_c0m(bmp: *mut c_void, msk: *mut c_void, num: XwSz) -> bool;
30    pub(crate) fn xwbmpop_t0ma(bmp: *mut c_void, msk: *mut c_void, num: XwSz) -> bool;
31    pub(crate) fn xwbmpop_t0ma_then_s1m(bmp: *mut c_void, msk: *mut c_void, num: XwSz) -> bool;
32    pub(crate) fn xwbmpop_t0mo(bmp: *mut c_void, msk: *mut c_void, num: XwSz) -> bool;
33    pub(crate) fn xwbmpop_t0mo_then_s1m(bmp: *mut c_void, msk: *mut c_void, num: XwSz) -> bool;
34    pub(crate) fn xwbmpop_not(bmp: *mut c_void, num: XwSz);
35    pub(crate) fn xwbmpop_and(bmp: *mut c_void, msk: *mut c_void, num: XwSz);
36    pub(crate) fn xwbmpop_or(bmp: *mut c_void, msk: *mut c_void, num: XwSz);
37    pub(crate) fn xwbmpop_xor(bmp: *mut c_void, msk: *mut c_void, num: XwSz);
38    pub(crate) fn xwbmpop_ffs(bmp: *mut c_void, num: XwSz) -> XwSsq;
39    pub(crate) fn xwbmpop_ffz(bmp: *mut c_void, num: XwSz) -> XwSsq;
40    pub(crate) fn xwbmpop_fls(bmp: *mut c_void, num: XwSz) -> XwSsq;
41    pub(crate) fn xwbmpop_flz(bmp: *mut c_void, num: XwSz) -> XwSsq;
42    pub(crate) fn xwbmpop_weight(bmp: *mut c_void, num: XwSz) -> XwSz;
43}
44
45#[repr(C)]
46#[cfg_attr(target_pointer_width = "32", repr(align(8)))]
47#[cfg_attr(target_pointer_width = "64", repr(align(16)))]
48pub(crate) struct BmpArray<const N: XwSz>
49where
50    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
51{
52    #[doc(hidden)]
53    pub(crate) array: [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize],
54}
55
56/// 位图类型
57///
58/// 常数 `N` 表示有多少位。
59pub struct Bmp<const N: XwSz>
60where
61    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
62{
63    #[doc(hidden)]
64    pub(crate) bmp: UnsafeCell<BmpArray<N>>,
65}
66
67unsafe impl<const N: XwSz> Send for Bmp<N>
68where
69    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
70{}
71
72unsafe impl<const N: XwSz> Sync for Bmp<N>
73where
74    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
75{}
76
77impl<const N: XwSz> Bmp<N>
78where
79    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
80{
81    /// 新建位图
82    ///
83    /// 此方法是编译期方法。
84    ///
85    /// # 示例
86    ///
87    /// + 具有 [`'static`] 约束的全局变量全局变量:
88    ///
89    /// ```rust
90    /// use xwrust::xwbmp::*;
91    ///
92    /// static GLOBAL_BMP = Bmp::<8>::new();
93    /// ```
94    ///
95    /// + 在函数中创建:
96    ///
97    /// ```rust
98    /// extern crate alloc;
99    /// use alloc::sync::Arc;
100    /// use xwrust::xwbmp::*;
101    ///
102    /// pub fn some_function() {
103    ///     let msk = Bmp::<8>::new();
104    /// }
105    /// ```
106    ///
107    /// + 在heap上创建:
108    ///
109    /// ```rust
110    /// extern crate alloc;
111    /// use alloc::sync::Arc;
112    /// use xwrust::xwbmp::*;
113    ///
114    /// pub fn some_function() {
115    ///     let msk = Arc::new(Bmp::<8>::new());
116    /// }
117    /// ```
118    ///
119    /// [`'static`]: https://doc.rust-lang.org/std/keyword.static.html
120    pub const fn new() -> Self {
121        Self {
122            bmp: UnsafeCell::new(BmpArray {
123                array: [0; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize],
124            }),
125        }
126    }
127
128    /// 获取位图位的数量
129    pub const fn bits(&self) -> XwSz {
130        N
131    }
132
133    /// 在位图中统计被置 **1** 的位的个数
134    pub fn weight(&self) -> XwSz {
135        unsafe {
136            xwbmpop_weight(self.bmp.get() as _ , N)
137        }
138    }
139
140    /// 将位图中所有位置 **1**
141    pub fn s1all(&self) {
142        unsafe {
143            xwbmpop_s1all(self.bmp.get() as _ , N);
144        }
145    }
146
147    /// 将位图中所有位清 **0**
148    pub fn c0all(&self) {
149        unsafe {
150            xwbmpop_c0all(self.bmp.get() as _ , N);
151        }
152    }
153
154    /// 将位图中单个位置 **1**
155    pub fn s1i(&self, n: XwSq) {
156        unsafe {
157            xwbmpop_s1i(self.bmp.get() as _ , n);
158        }
159    }
160
161    /// 将位图中掩码部分置 **1**
162    pub fn s1m(&self, msk: &Self) {
163        unsafe {
164            xwbmpop_s1m(self.bmp.get() as _ , msk.bmp.get() as _, N);
165        }
166    }
167
168    /// 将位图中单个位清 **0**
169    pub fn c0i(&self, n: XwSq) {
170        unsafe {
171            xwbmpop_c0i(self.bmp.get() as _ , n);
172        }
173    }
174
175    /// 将位图中掩码部分清 **0**
176    pub fn c0m(&self, msk: &Self) {
177        unsafe {
178            xwbmpop_c0m(self.bmp.get() as _ , msk.bmp.get() as _, N);
179        }
180    }
181
182    /// 将位图中单个位翻转
183    pub fn x1i(&self, n: XwSq) {
184        unsafe {
185            xwbmpop_x1i(self.bmp.get() as _ , n);
186        }
187    }
188
189    /// 将位图中掩码部分翻转
190    pub fn x1m(&self, msk: &Self) {
191        unsafe {
192            xwbmpop_x1m(self.bmp.get() as _ , msk.bmp.get() as _, N);
193        }
194    }
195
196    /// 测试位图中的单个位是否为 **1**
197    pub fn t1i(&self, n: XwSq) -> bool {
198        unsafe {
199            xwbmpop_t1i(self.bmp.get() as _ , n)
200        }
201    }
202
203    /// 测试位图中掩码部分是否全部为 **1**
204    pub fn t1ma(&self, msk: &Self) -> bool {
205        unsafe {
206            xwbmpop_t1ma(self.bmp.get() as _ , msk.bmp.get() as _, N)
207        }
208    }
209
210    /// 测试位图中掩码部分是否至少有一位为 **1**
211    pub fn t1mo(&self, msk: &Self) -> bool {
212        unsafe {
213            xwbmpop_t1mo(self.bmp.get() as _ , msk.bmp.get() as _, N)
214        }
215    }
216
217    /// 测试位图中掩码部分是否全部为 **1** ,如果是,就将掩码部分全部清 **0**
218    pub fn t1ma_then_c0m(&self, msk: &Self) -> bool {
219        unsafe {
220            xwbmpop_t1ma_then_c0m(self.bmp.get() as _ , msk.bmp.get() as _, N)
221        }
222    }
223
224    /// 测试位图中掩码部分是否至少有一位为 **1** ,如果是,就将掩码部分全部清 **0**
225    pub fn t1mo_then_c0m(&self, msk: &Self) -> bool {
226        unsafe {
227            xwbmpop_t1mo_then_c0m(self.bmp.get() as _ , msk.bmp.get() as _, N)
228        }
229    }
230
231    /// 测试位图中掩码部分是否全部为 **0** ,如果是,就将掩码部分全部置 **1**
232    pub fn t0ma_then_s1m(&self, msk: &Self) -> bool {
233        unsafe {
234            xwbmpop_t0ma_then_s1m(self.bmp.get() as _ , msk.bmp.get() as _, N)
235        }
236    }
237
238    /// 测试位图中掩码部分是否至少有一位为 **0** ,如果是,就将掩码部分全部置 **1**
239    pub fn t0mo_then_s1m(&self, msk: &Self) -> bool {
240        unsafe {
241            xwbmpop_t0mo_then_s1m(self.bmp.get() as _ , msk.bmp.get() as _, N)
242        }
243    }
244
245    /// 在位图中从最低位起查找第一个被置 **1** 的位
246    pub fn ffs(&self) -> XwSsq {
247        unsafe {
248            xwbmpop_ffs(self.bmp.get() as _ , N)
249        }
250    }
251
252    /// 在位图中从最低位起查找第一个被清 **0** 的位
253    pub fn ffz(&self) -> XwSsq {
254        unsafe {
255            xwbmpop_ffz(self.bmp.get() as _ , N)
256        }
257    }
258
259    /// 在位图中从最高位起查找第一个被置 **1** 的位
260    pub fn fls(&self) -> XwSsq {
261        unsafe {
262            xwbmpop_fls(self.bmp.get() as _ , N)
263        }
264    }
265
266    /// 在位图中从最高位起查找第一个被清 **0** 的位
267    pub fn flz(&self) -> XwSsq {
268        unsafe {
269            xwbmpop_flz(self.bmp.get() as _ , N)
270        }
271    }
272}
273
274impl<const N: XwSz> PartialEq for Bmp<N>
275where
276    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
277{
278    fn eq(&self, other: &Self) -> bool {
279        unsafe {
280            let rc = xwbmpop_cmp(self.bmp.get() as _, other.bmp.get() as _, N);
281            rc == 0
282        }
283    }
284}
285
286impl<const N: XwSz> PartialOrd for Bmp<N>
287where
288    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
289{
290    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
291        unsafe {
292            let rc = xwbmpop_cmp(self.bmp.get() as _, other.bmp.get() as _, N);
293            if rc < 0 {
294                Some(Ordering::Less)
295            } else if rc > 0 {
296                Some(Ordering::Greater)
297            } else {
298                Some(Ordering::Equal)
299            }
300        }
301    }
302}
303
304impl<const N: XwSz> BitAnd for Bmp<N>
305where
306    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
307{
308    type Output = Self;
309
310    fn bitand(self, other: Self) -> Self {
311        unsafe {
312            xwbmpop_and(self.bmp.get() as _, other.bmp.get() as _, N);
313            self
314        }
315    }
316}
317
318impl<const N: XwSz> BitAndAssign for Bmp<N>
319where
320    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
321{
322    fn bitand_assign(&mut self, other: Self) {
323        unsafe {
324            xwbmpop_and(self.bmp.get() as _, other.bmp.get() as _, N);
325        }
326    }
327}
328
329impl<const N: XwSz> BitOr for Bmp<N>
330where
331    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
332{
333    type Output = Self;
334
335    fn bitor(self, other: Self) -> Self {
336        unsafe {
337            xwbmpop_or(self.bmp.get() as _, other.bmp.get() as _, N);
338            self
339        }
340    }
341}
342
343impl<const N: XwSz> BitOrAssign for Bmp<N>
344where
345    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
346{
347    fn bitor_assign(&mut self, other: Self) {
348        unsafe {
349            xwbmpop_or(self.bmp.get() as _, other.bmp.get() as _, N);
350        }
351    }
352}
353
354impl<const N: XwSz> BitXor for Bmp<N>
355where
356    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
357{
358    type Output = Self;
359
360    fn bitxor(self, other: Self) -> Self {
361        unsafe {
362            xwbmpop_xor(self.bmp.get() as _, other.bmp.get() as _, N);
363            self
364        }
365    }
366}
367
368impl<const N: XwSz> BitXorAssign for Bmp<N>
369where
370    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
371{
372    fn bitxor_assign(&mut self, other: Self) {
373        unsafe {
374            xwbmpop_xor(self.bmp.get() as _, other.bmp.get() as _, N);
375        }
376    }
377}
378
379impl<const N: XwSz> Neg for Bmp<N>
380where
381    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
382{
383    type Output = Self;
384
385    fn neg(self) -> Self{
386        unsafe {
387            xwbmpop_not(self.bmp.get() as _, N);
388            self
389        }
390    }
391}
392
393impl<const N: XwSz> fmt::Debug for Bmp<N>
394where
395    [XwBmp; (N + XwBmp::BITS as usize - 1) / XwBmp::BITS as usize]: Sized
396{
397    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
398        unsafe {
399            f.debug_struct("Bmp")
400                .field("bits", &self.bits())
401                .field("array", &(*(self.bmp.get())).array)
402                .finish()
403        }
404    }
405}