rbtree
This commit is contained in:
parent
d9942857bc
commit
e89e44d129
@ -2,6 +2,7 @@
|
||||
//! simple static types, which are completely [Context]-independent.
|
||||
|
||||
pub mod atomic_object;
|
||||
pub mod boolean;
|
||||
pub mod plain;
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
65
src/std/atomic/boolean.rs
Normal file
65
src/std/atomic/boolean.rs
Normal 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;
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
//! Standard generic collections.
|
||||
|
||||
pub mod pair;
|
||||
pub mod rbtree;
|
||||
pub mod stack;
|
||||
|
260
src/std/collections/rbtree.rs
Normal file
260
src/std/collections/rbtree.rs
Normal 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))
|
||||
}
|
||||
}
|
@ -52,6 +52,8 @@ pub trait ConstSizeAtomic: InlineableAtomic {
|
||||
const SIZE: usize;
|
||||
}
|
||||
|
||||
impl<A: ConstSizeAtomic> InlineableAtomic for A {}
|
||||
|
||||
impl<A: Atomic + InlineableAtomic> InlineableFactory for AtomicFactory<A> {}
|
||||
|
||||
impl<A: Atomic + ConstSizeAtomic> FixedSizeFactory for AtomicFactory<A> {
|
||||
|
@ -12,9 +12,10 @@ pub enum Nullable<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> {
|
||||
}
|
||||
|
||||
/// 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: A::Fctr,
|
||||
factory: F,
|
||||
}
|
||||
|
||||
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> {
|
||||
type Fctr = NullableFactory<'a, Ctx, A>;
|
||||
type Fctr = NullableFactory<A::Fctr>;
|
||||
|
||||
fn factory(&self) -> Self::Fctr {
|
||||
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> {
|
||||
fn clone(&self) -> Self {
|
||||
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>;
|
||||
impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for NullableFactory<F> {
|
||||
type Mtbl = Nullable<'a, Ctx, F::Mtbl>;
|
||||
|
||||
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> {
|
||||
pub fn new(factory: A::Fctr) -> Self {
|
||||
impl<F> NullableFactory<F> {
|
||||
pub fn new(factory: F) -> Self {
|
||||
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
|
||||
for NullableFactory<'a, Ctx, A>
|
||||
{
|
||||
impl<F> AlwaysConstSize for NullableFactory<F> {
|
||||
const _SIZE: usize = HASH_SIZE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user