use crate::bitmap::BitmapIndex;
#[cfg(test)]
use crate::{
bitmap::{Bitmap, BitmapRef, SpecializedBitmap, SpecializedBitmapRef},
object::TopologyObject,
topology::Topology,
};
use proptest::{
collection::SizeRange,
prelude::*,
sample::Select,
strategy::{Map, TupleUnion, WA},
string::RegexGeneratorStrategy,
};
use std::{
ffi::{c_uchar, c_uint},
fmt::Debug,
ops::{Range, RangeInclusive},
};
use strum::IntoEnumIterator;
pub(crate) fn any_string() -> AnyString {
prop::string::string_regex(".*").expect("this is a valid regex")
}
pub(crate) type AnyString = RegexGeneratorStrategy<String>;
pub(crate) fn hwloc_bool() -> HwlocBool {
prop_oneof![
4 => prop::bool::ANY.prop_map(c_uchar::from),
1 => 2..=c_uchar::MAX,
]
}
pub(crate) type HwlocBool = TupleUnion<(
WA<Map<prop::bool::Any, fn(bool) -> c_uchar>>,
WA<RangeInclusive<c_uchar>>,
)>;
pub(crate) fn int_special0<Int: Arbitrary + Copy>(zero: Int, one: Int, max: Int) -> IntSpecial0<Int>
where
RangeInclusive<Int>: Strategy,
{
prop_oneof![
4 => one..=max,
1 => Just(zero)
]
}
pub(crate) type IntSpecial0<Int> = TupleUnion<(WA<RangeInclusive<Int>>, WA<Just<Int>>)>;
pub(crate) fn u64_special0() -> IntSpecial0<u64> {
int_special0(0, 1, u64::MAX)
}
pub(crate) fn uint_special0() -> IntSpecial0<c_uint> {
int_special0(0, 1, c_uint::MAX)
}
pub(crate) fn enum_repr<Enum: IntoEnumIterator, Repr: Copy + Debug + From<Enum>>() -> EnumRepr<Repr>
{
let valid_reprs = <Enum as IntoEnumIterator>::iter()
.map(Repr::from)
.collect::<Vec<_>>();
prop::sample::select(valid_reprs)
}
pub(crate) type EnumRepr<Repr> = Select<Repr>;
pub(crate) fn bitmap_index() -> BitmapIndexStrategy {
let max_idx = SizeRange::default().end_excl();
(0..max_idx).prop_map(|idx| BitmapIndex::try_from(idx).unwrap_or(BitmapIndex::MAX))
}
pub(crate) type BitmapIndexStrategy = Map<Range<usize>, fn(usize) -> BitmapIndex>;
#[cfg(test)]
pub(crate) fn any_object() -> impl Strategy<Value = &'static TopologyObject> {
#[cfg(feature = "hwloc-2_3_0")]
{
prop_oneof![
4 => test_object(),
1 => prop::sample::select(Topology::foreign_objects())
]
}
#[cfg(not(feature = "hwloc-2_3_0"))]
test_object()
}
#[cfg(test)]
pub(crate) fn test_object() -> impl Strategy<Value = &'static TopologyObject> {
prop::sample::select(Topology::test_objects())
}
#[cfg(test)]
pub(crate) fn set_with_reference<SetRef: SpecializedBitmapRef>(
reference: SetRef,
) -> impl Strategy<Value = SetRef::Owned> {
let ref_set = reference.as_bitmap_ref();
let finite_set = if ref_set.weight().is_some() {
ref_set.clone()
} else {
!ref_set
};
assert!(
finite_set.weight().is_some(),
"since bitmaps can only be infinite in one direction, \
the complement of an infinite bitmap must be finite"
);
let finite_elems = finite_set.iter_set().collect::<Vec<_>>();
let num_finite_elems = finite_elems.len();
let inside_elems = prop_oneof![
3 => prop::sample::subsequence(finite_elems.clone(), 0..=num_finite_elems),
1 => Just(Vec::new()),
1 => Just(finite_elems)
]
.prop_map(|seq| seq.into_iter().collect::<Bitmap>());
let outside_elems = prop_oneof![
Just(Bitmap::new()),
any::<Bitmap>().prop_map(move |any_elems| any_elems - &finite_set),
];
(inside_elems, outside_elems)
.prop_map(|(inside_elems, outside_elems)| SetRef::Owned::from(inside_elems | outside_elems))
}
#[cfg(test)]
pub(crate) fn topology_related_set<Set: SpecializedBitmap>(
topology_set: impl FnOnce(&Topology) -> BitmapRef<'_, Set>,
) -> impl Strategy<Value = Set> {
set_with_reference(topology_set(Topology::test_instance()))
}