use std::borrow::Borrow;
use crate::{
ScatteredMap,
hash::ConstHash,
map::{__ScatteredMapState, MapRecord},
};
#[doc = include_str!("../examples/set.rs")]
pub struct ScatteredSet<T: 'static> {
map: ScatteredMap<T, ()>,
}
impl<T: ConstHash + PartialEq + 'static> ScatteredSet<T> {
#[doc(hidden)]
pub const fn __new(state: &'static __ScatteredMapState<T, ()>) -> Self {
Self {
map: ScatteredMap::__new(state),
}
}
#[inline]
pub fn len(&self) -> usize {
self.map.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
#[inline]
pub fn contains<Q>(&self, key: &Q) -> bool
where
T: Borrow<Q>,
Q: ConstHash + Eq + ?Sized,
{
self.map.contains_key(key)
}
#[inline]
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.map.keys()
}
#[inline]
pub fn offset_of(this: &Self, key: &SetRecord<T>) -> Option<usize> {
ScatteredMap::offset_of(&this.map, key.as_map_record_ref())
}
}
#[repr(transparent)]
pub struct SetRecord<T: 'static> {
record: MapRecord<T, ()>,
}
impl<K: 'static> IntoIterator for &'static ScatteredSet<K> {
type Item = &'static K;
type IntoIter =
::std::iter::Map<::std::slice::Iter<'static, SetRecord<K>>, fn(&SetRecord<K>) -> &K>;
#[allow(unsafe_code)]
fn into_iter(self) -> Self::IntoIter {
let records: &[SetRecord<K>] = unsafe { core::mem::transmute(self.map.state.records()) };
records.iter().map(|record| &record.record.key)
}
}
impl<T: ConstHash + ::core::fmt::Debug + 'static> ::core::fmt::Debug for SetRecord<T> {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
::core::fmt::Debug::fmt(&self.record.key, f)
}
}
impl<T: ConstHash + 'static> SetRecord<T> {
#[doc(hidden)]
pub const fn new(key: T, hash: u64) -> Self {
Self {
record: MapRecord::new(key, (), hash),
}
}
}
impl<T: ConstHash + 'static> ::core::ops::Deref for SetRecord<T> {
type Target = MapRecord<T, ()>;
fn deref(&self) -> &Self::Target {
&self.record
}
}
impl<T: ConstHash + 'static> SetRecord<T> {
#[allow(unsafe_code)]
pub(crate) fn as_map_record_ref(&self) -> &MapRecord<T, ()> {
unsafe { core::mem::transmute(&self.record) }
}
}
impl<K: 'static> crate::ScatteredElementType for ScatteredSet<K> {
type T = SetRecord<K>;
}
#[macro_export]
#[doc(hidden)]
macro_rules! __set {
(@gather $unique:ident $(#[$meta:meta])* $vis:vis static $name:ident: ($($set:tt)*) < $key:ty >;) => {
#[doc(hidden)]
#[allow(unused, non_camel_case_types)]
$vis type $name = $($set)* <$key>;
$(#[$meta])*
$vis static $name: $($set)* <$key> = {
$crate::__support::link_section::declarative::section!(
#[section(unsafe, type = typed, name = $name :: $unique)]
static $name: $crate::__support::link_section::TypedSection<
$crate::set::SetRecord<$key>
>;
);
$crate::__support::link_section::declarative::section!(
#[section(unsafe, type = mutable, name = $name :: $unique :: MAP_META)]
static MAP_META: $crate::__support::link_section::TypedMutableSection<u8>;
);
$crate::__support::link_section::declarative::in_section!(
#[in_section(unsafe, type = mutable, name = $name :: $unique :: MAP_META)]
const _: $crate::map::MapMetadataChunkBase = $crate::map::MAP_METADATA_CHUNK_BASE_ZERO;
);
static __MAP_STATE: $crate::map::__ScatteredMapState<$key, ()> = $crate::map::__ScatteredMapState::new(unsafe { core::mem::transmute($name.const_deref()) }, MAP_META.const_deref());
$crate::__support::ctor::declarative::ctor!(
#[ctor(unsafe, anonymous, priority = 0)]
fn __map_init() {
__MAP_STATE.__initialize();
}
);
$crate::set::ScatteredSet::__new(&__MAP_STATE)
};
};
(@scatter [$collection_name:ident :: $unique:ident] ([$($meta:tt)*] => $(#[$imeta:meta])* $vis:vis $kind:ident $name:tt: $ty:ty = $key_expr:expr;)) => {
$crate::__support::link_section::declarative::in_section!(
#[in_section(unsafe, name = $collection_name :: $unique, type = typed)]
$(#[$imeta])*
$vis $kind $name: <$($meta)* as $crate::ScatteredElementType>::T = $crate::set::SetRecord::new(
$key_expr,
$crate::const_hash!($key_expr)
);
);
$crate::__support::link_section::declarative::in_section!(
#[in_section(unsafe, name = $collection_name :: $unique :: MAP_META, type = mutable)]
const _: $crate::map::MapMetadataChunk = $crate::map::MAP_METADATA_CHUNK_ZERO;
);
};
}