bitvec/
devel.rs

1//! Support utilities for crate development.
2
3use core::any::TypeId;
4
5use crate::{
6	order::BitOrder,
7	store::BitStore,
8};
9
10/// Constructs formatting-trait implementations by delegating.
11macro_rules! easy_fmt {
12	($(impl $fmt:ident)+ for BitArray) => { $(
13		impl<A, O> core::fmt::$fmt for $crate::array::BitArray<A, O>
14		where
15			O: $crate::order::BitOrder,
16			A: $crate::view::BitViewSized,
17		{
18			#[inline]
19			#[cfg(not(tarpaulin_include))]
20			fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
21				core::fmt::$fmt::fmt(self.as_bitslice(), fmt)
22			}
23		}
24	)+ };
25	($(impl $fmt:ident)+ for $this:ident) => { $(
26		impl<T, O> core::fmt::$fmt for $this<T, O>
27		where
28			O: $crate::order::BitOrder,
29			T: $crate::store::BitStore,
30		{
31			#[inline]
32			#[cfg(not(tarpaulin_include))]
33			fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
34				core::fmt::$fmt::fmt(self.as_bitslice(), fmt)
35			}
36		}
37	)+ };
38}
39
40/// Implements some `Iterator` functions that have boilerplate behavior.
41macro_rules! easy_iter {
42	() => {
43		#[inline]
44		fn size_hint(&self) -> (usize, Option<usize>) {
45			let len = self.len();
46			(len, Some(len))
47		}
48
49		#[inline]
50		fn count(self) -> usize {
51			self.len()
52		}
53
54		#[inline]
55		fn last(mut self) -> Option<Self::Item> {
56			self.next_back()
57		}
58	};
59}
60
61/// Tests if two `BitOrder` implementors are the same.
62#[inline]
63pub fn match_order<O, P>() -> bool
64where
65	O: BitOrder,
66	P: BitOrder,
67{
68	eq_types::<O, P>()
69}
70
71/// Tests if two `BitStore` implementors are the same.
72#[inline]
73pub fn match_store<T, U>() -> bool
74where
75	T: BitStore,
76	U: BitStore,
77{
78	eq_types::<T, U>()
79}
80
81/// Tests if two `BitSlice` type parameter pairs match each other.
82#[inline]
83pub fn match_types<T1, O1, T2, O2>() -> bool
84where
85	O1: BitOrder,
86	T1: BitStore,
87	O2: BitOrder,
88	T2: BitStore,
89{
90	match_order::<O1, O2>() && match_store::<T1, T2>()
91}
92
93/// Tests if a type is known to be an unsigned integer.
94///
95/// Returns `true` for `u{8,16,32,64,128,size}` and `false` for all others.
96#[inline]
97pub fn is_unsigned<T>() -> bool
98where T: 'static {
99	eq_types::<T, u8>()
100		|| eq_types::<T, u16>()
101		|| eq_types::<T, u32>()
102		|| eq_types::<T, u64>()
103		|| eq_types::<T, u128>()
104		|| eq_types::<T, usize>()
105}
106
107/// Tests if two types are identical, even through different names.
108#[inline]
109fn eq_types<T, U>() -> bool
110where
111	T: 'static,
112	U: 'static,
113{
114	TypeId::of::<T>() == TypeId::of::<U>()
115}