rbtree
This commit is contained in:
parent
d9942857bc
commit
e89e44d129
@ -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
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.
|
//! Standard generic collections.
|
||||||
|
|
||||||
pub mod pair;
|
pub mod pair;
|
||||||
|
pub mod rbtree;
|
||||||
pub mod stack;
|
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;
|
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> {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user