This commit is contained in:
AF 2023-04-24 13:36:57 +00:00
parent d9942857bc
commit e89e44d129
6 changed files with 338 additions and 20 deletions

View File

@ -2,6 +2,7 @@
//! simple static types, which are completely [Context]-independent. //! simple static types, which are completely [Context]-independent.
pub mod atomic_object; pub mod atomic_object;
pub mod boolean;
pub mod plain; pub mod plain;
use std::marker::PhantomData; use std::marker::PhantomData;

65
src/std/atomic/boolean.rs Normal file
View File

@ -0,0 +1,65 @@
use crate::std::inlining::*;
use super::*;
impl Serializable for bool {
fn serialize(&self, serializer: &mut dyn Serializer) {
match self {
true => serializer.write(&[0]),
false => serializer.write(&[1]),
}
}
}
#[derive(Debug)]
pub enum BooleanParseError {
OutOfBounds(u8),
Eof,
ExtraData(usize),
}
impl Display for BooleanParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BooleanParseError::OutOfBounds(value) => {
f.write_fmt(format_args!("boolean value out of bounds: {}.", value))
}
BooleanParseError::Eof => {
f.write_fmt(format_args!("encountered EOF write parsing a boolean."))
}
BooleanParseError::ExtraData(length) => f.write_fmt(format_args!(
"encountered extra data of length {} while parsing a boolean",
length
)),
}
}
}
impl Error for BooleanParseError {}
impl From<&[u8]> for BooleanParseError {
fn from(_value: &[u8]) -> Self {
Self::Eof
}
}
impl Atomic for bool {
type ParseError = BooleanParseError;
fn deserialize(deserializer: &mut dyn Deserializer) -> Result<Self, Self::ParseError> {
let byte = deserializer.read_n_const::<1>()?;
match byte[0] {
0 => Ok(false),
1 => Ok(true),
value => Err(BooleanParseError::OutOfBounds(value)),
}
}
fn unexpected_tail(tail: &[u8]) -> Self::ParseError {
BooleanParseError::ExtraData(tail.len())
}
}
impl ConstSizeAtomic for bool {
const SIZE: usize = 1;
}

View File

@ -1,4 +1,5 @@
//! Standard generic collections. //! Standard generic collections.
pub mod pair; pub mod pair;
pub mod rbtree;
pub mod stack; pub mod stack;

View File

@ -0,0 +1,260 @@
use std::{error::Error, fmt::Display};
use crate::core::*;
use crate::std::{
atomic::{boolean::*, *},
nullable::*,
point::*,
};
const B: bool = false;
const R: bool = true;
type RB = bool;
#[derive(Debug)]
pub enum TreeParseError<E> {
Boolean(BooleanParseError),
Point(PointParseError),
Key(E),
}
impl<E> From<BooleanParseError> for TreeParseError<E> {
fn from(value: BooleanParseError) -> Self {
TreeParseError::Boolean(value)
}
}
impl<E> From<PointParseError> for TreeParseError<E> {
fn from(value: PointParseError) -> Self {
TreeParseError::Point(value)
}
}
impl<E: Display> Display for TreeParseError<E> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TreeParseError::Boolean(boolean_error) => {
f.write_fmt(format_args!("failed to parse RB flag: {}", boolean_error))
}
TreeParseError::Point(point_error) => f.write_fmt(format_args!(
"failed to parse RB tree reference: {}",
point_error
)),
TreeParseError::Key(key_error) => {
f.write_fmt(format_args!("failed to parse RB tree key: {}", key_error))
}
}
}
}
impl<E: Error> Error for TreeParseError<E> {}
pub enum RBNode<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> {
R(RNode<'a, Ctx, A>),
B(BNode<'a, Ctx, A>),
}
pub struct BNode<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> {
cl: Nullable<'a, Ctx, RBNode<'a, Ctx, A>>,
cr: Nullable<'a, Ctx, RBNode<'a, Ctx, A>>,
key: A,
}
pub struct RNode<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> {
cl: Nullable<'a, Ctx, BNode<'a, Ctx, A>>,
cr: Nullable<'a, Ctx, BNode<'a, Ctx, A>>,
key: A,
}
#[derive(Clone)]
pub struct RBFactory<F> {
key_factory: F,
}
#[derive(Clone)]
pub struct BFactory<F> {
key_factory: F,
}
#[derive(Clone)]
pub struct RFactory<F> {
key_factory: F,
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> RBNode<'a, Ctx, A> {
fn key(&self) -> &A {
match self {
RBNode::R(RNode { key, .. }) => key,
RBNode::B(BNode { key, .. }) => key,
}
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for RBNode<'a, Ctx, A> {
fn serialize(&self, serializer: &mut dyn Serializer) {
match self {
RBNode::R(r) => {
R.serialize(serializer);
r.serialize(serializer);
}
RBNode::B(b) => {
B.serialize(serializer);
b.serialize(serializer);
}
}
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for BNode<'a, Ctx, A> {
fn serialize(&self, serializer: &mut dyn Serializer) {
self.cl.serialize(serializer);
self.cr.serialize(serializer);
self.key.serialize(serializer);
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for RNode<'a, Ctx, A> {
fn serialize(&self, serializer: &mut dyn Serializer) {
self.cl.serialize(serializer);
self.cr.serialize(serializer);
self.key.serialize(serializer);
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for RBNode<'a, Ctx, A> {
type Fctr = RBFactory<A::Fctr>;
fn factory(&self) -> Self::Fctr {
RBFactory {
key_factory: self.key().factory(),
}
}
fn points(&self, points: &mut Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>) {
match self {
RBNode::R(r) => r.points(points),
RBNode::B(b) => b.points(points),
}
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for BNode<'a, Ctx, A> {
type Fctr = BFactory<A::Fctr>;
fn factory(&self) -> Self::Fctr {
BFactory {
key_factory: self.key.factory(),
}
}
fn points(&self, points: &mut Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>) {
self.cl.points(points);
self.cr.points(points);
self.key.points(points);
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for RNode<'a, Ctx, A> {
type Fctr = RFactory<A::Fctr>;
fn factory(&self) -> Self::Fctr {
RFactory {
key_factory: self.key.factory(),
}
}
fn points(&self, points: &mut Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>) {
self.cl.points(points);
self.cr.points(points);
self.key.points(points);
}
}
impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for RBFactory<F> {
type Mtbl = RBNode<'a, Ctx, F::Mtbl>;
type ParseError = TreeParseError<F::ParseError>;
fn deserialize(
&self,
deserializer: &mut dyn Deserializer,
resolver: std::rc::Rc<dyn Resolver<'a, Ctx>>,
addresses: &mut Addresses,
) -> ParseResult<'a, Ctx, Self> {
let rb = RB::deserialize(deserializer)?;
Ok(match rb {
R => RBNode::R(
RFactory {
key_factory: self.key_factory.clone(),
}
.deserialize(deserializer, resolver, addresses)?,
),
B => RBNode::B(
BFactory {
key_factory: self.key_factory.clone(),
}
.deserialize(deserializer, resolver, addresses)?,
),
})
}
fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError {
TreeParseError::Key(self.key_factory.unexpected_tail(tail))
}
}
impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for BFactory<F> {
type Mtbl = BNode<'a, Ctx, F::Mtbl>;
type ParseError = TreeParseError<F::ParseError>;
fn deserialize(
&self,
deserializer: &mut dyn Deserializer,
resolver: std::rc::Rc<dyn Resolver<'a, Ctx>>,
addresses: &mut Addresses,
) -> ParseResult<'a, Ctx, Self> {
let nullable_factory = NullableFactory::new(RBFactory {
key_factory: self.key_factory.clone(),
});
let cl = nullable_factory.deserialize(deserializer, resolver.clone(), addresses)?;
let cr = nullable_factory.deserialize(deserializer, resolver.clone(), addresses)?;
let key = self
.key_factory
.deserialize(deserializer, resolver, addresses)
.map_err(TreeParseError::Key)?;
Ok(BNode { cl, cr, key })
}
fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError {
TreeParseError::Key(self.key_factory.unexpected_tail(tail))
}
}
impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for RFactory<F> {
type Mtbl = RNode<'a, Ctx, F::Mtbl>;
type ParseError = TreeParseError<F::ParseError>;
fn deserialize(
&self,
deserializer: &mut dyn Deserializer,
resolver: std::rc::Rc<dyn Resolver<'a, Ctx>>,
addresses: &mut Addresses,
) -> ParseResult<'a, Ctx, Self> {
let nullable_factory = NullableFactory::new(BFactory {
key_factory: self.key_factory.clone(),
});
let cl = nullable_factory.deserialize(deserializer, resolver.clone(), addresses)?;
let cr = nullable_factory.deserialize(deserializer, resolver.clone(), addresses)?;
let key = self
.key_factory
.deserialize(deserializer, resolver, addresses)
.map_err(TreeParseError::Key)?;
Ok(RNode { cl, cr, key })
}
fn unexpected_tail(&self, tail: &[u8]) -> Self::ParseError {
TreeParseError::Key(self.key_factory.unexpected_tail(tail))
}
}

View File

@ -52,6 +52,8 @@ pub trait ConstSizeAtomic: InlineableAtomic {
const SIZE: usize; const SIZE: usize;
} }
impl<A: ConstSizeAtomic> InlineableAtomic for A {}
impl<A: Atomic + InlineableAtomic> InlineableFactory for AtomicFactory<A> {} impl<A: Atomic + InlineableAtomic> InlineableFactory for AtomicFactory<A> {}
impl<A: Atomic + ConstSizeAtomic> FixedSizeFactory for AtomicFactory<A> { impl<A: Atomic + ConstSizeAtomic> FixedSizeFactory for AtomicFactory<A> {

View File

@ -12,9 +12,10 @@ pub enum Nullable<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> {
} }
/// Nullable reference factory. /// Nullable reference factory.
pub struct NullableFactory<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> { #[derive(Clone)]
pub struct NullableFactory<F> {
/// Factory of the referenced object. /// Factory of the referenced object.
factory: A::Fctr, factory: F,
} }
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for Nullable<'a, Ctx, A> { impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for Nullable<'a, Ctx, A> {
@ -27,7 +28,7 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for Nullable<'
} }
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Nullable<'a, Ctx, A> { impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Nullable<'a, Ctx, A> {
type Fctr = NullableFactory<'a, Ctx, A>; type Fctr = NullableFactory<A::Fctr>;
fn factory(&self) -> Self::Fctr { fn factory(&self) -> Self::Fctr {
match self { match self {
@ -48,18 +49,8 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Nu
} }
} }
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Clone for NullableFactory<'a, Ctx, A> { impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for NullableFactory<F> {
fn clone(&self) -> Self { type Mtbl = Nullable<'a, Ctx, F::Mtbl>;
Self {
factory: self.factory.clone(),
}
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Factory<'a, Ctx>
for NullableFactory<'a, Ctx, A>
{
type Mtbl = Nullable<'a, Ctx, A>;
type ParseError = PointParseError; type ParseError = PointParseError;
@ -96,8 +87,8 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Nullable<'a, Ctx, Nullable<
} }
} }
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> NullableFactory<'a, Ctx, A> { impl<F> NullableFactory<F> {
pub fn new(factory: A::Fctr) -> Self { pub fn new(factory: F) -> Self {
Self { factory } Self { factory }
} }
} }
@ -111,8 +102,6 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Clone for Nullable<'a, Ctx,
} }
} }
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> AlwaysConstSize impl<F> AlwaysConstSize for NullableFactory<F> {
for NullableFactory<'a, Ctx, A>
{
const _SIZE: usize = HASH_SIZE; const _SIZE: usize = HASH_SIZE;
} }