Skip to content

Commit

Permalink
version 0.3.0
Browse files Browse the repository at this point in the history
1. [refactoring] stop returning &mut _ in public API, use Pin<&mut _> instead
2. [bug fix] fix [bug #1](#1) for all mods, via using Pin<&mut _>
3. [refactoring] change Debug impls for `Link` in linked mod
4. [refactoring] [bug fix] make `potted::notation::TreeData` to be an unsafe trait
  • Loading branch information
oooutlk committed Feb 21, 2020
1 parent bbcb8e3 commit 83cd177
Show file tree
Hide file tree
Showing 24 changed files with 296 additions and 615 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "trees"
version = "0.3.0-a1"
version = "0.3.0"
edition = "2018"
authors = ["oooutlk <oooutlk@outlook.com>"]
license = "MIT/Apache-2.0"
Expand All @@ -12,7 +12,7 @@ categories = [ "data-structures", "no-std" ]
description = "General purpose tree data structures"

[dependencies]
indexed = "0.1"
indexed = "0.2"

[features]
no_std = []
48 changes: 24 additions & 24 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
//! Tree::from(( 0, ));
//! Tree::from(( 0, 1 ));
//! Tree::from(( 0, 1, 2 ));
//! Tree::from(( 0, (1, 2, 3), (4, 5, 6)));
//! ```
//!
//! 2. Forest notation
Expand Down Expand Up @@ -112,7 +113,7 @@
//!
//! 4. String representation
//!
//! The Debug and Display trait has been implemented that is essentially the same as tree_to_tring() mentioned above.
//! The Display trait has been implemented that is essentially the same as tree_to_tring() mentioned above.
//!
//! Children are seperated by spaces and grouped in the parentheses that follow their parent closely.
//!
Expand All @@ -122,14 +123,12 @@
//! let tree = tr(0) /( tr(1) /tr(2)/tr(3) ) /( tr(4) /tr(5)/tr(6) );
//! let str_repr = "0( 1( 2 3 ) 4( 5 6 ) )";
//! assert_eq!( tree.to_string(), str_repr );
//! assert_eq!( format!( "{:?}", tree ), str_repr );
//!
//! assert_eq!( fr::<i32>().to_string(), "()" );
//!
//! let forest = -( tr(1) /tr(2)/tr(3) ) -( tr(4) /tr(5)/tr(6) );
//! let str_repr = "( 1( 2 3 ) 4( 5 6 ) )";
//! assert_eq!( forest.to_string(), str_repr );
//! assert_eq!( format!( "{:?}", fr::<i32>() ), "()" );
//!```
//!
//! ## Slow start
Expand All @@ -139,16 +138,17 @@
//! 1. Tree is composed of a root Node and an optional Forest as its children. A tree can NOT be empty.
//! ```
//! use trees::{tr,Tree,Forest};
//! use std::pin::Pin;
//!
//! let mut tree: Tree<i32> = tr(0);
//!
//! let forest: Forest<i32> = -tr(1)-tr(2)-tr(3);
//! tree.append( forest );
//! tree.root_mut().append( forest );
//! assert_eq!( tree, tr(0) /tr(1) /tr(2) /tr(3) );
//!
//! { let _forest: &Forest<i32> = tree.forest(); }
//! { let _forest: &mut Forest<i32> = tree.forest_mut(); }
//! { let _forest: Forest<i32> = tree.abandon(); }
//! { let _forest: &Forest<i32> = tree.forest(); }
//! { let _forest: Pin<&mut Forest<i32>> = tree.root_mut().forest_mut(); }
//! { let _forest: Forest<i32> = tree.abandon(); }
//!
//! assert_eq!( tree, tr(0) );
//! ```
Expand All @@ -171,8 +171,8 @@
//! use trees::{tr,fr,Forest};
//!
//! let mut forest: Forest<i32> = fr(); // an empty forest
//! forest.push_back( tr(1) ); // forest has one tree
//! forest.push_back( tr(2) ); // forest has two trees
//! forest.push_back( tr(1) ); // forest has one tree, tr(1)
//! forest.push_back( tr(2) ); // forest has two trees, tr(1) and tr(2)
//! ```
//!
//! The potted version:
Expand All @@ -194,7 +194,7 @@
//! let second_child: &Node<i32> = tree.iter().nth(1).unwrap();
//! let third_child : &Node<i32> = tree.iter().last().unwrap();
//! }
//! let first_child: Tree<i32> = tree.pop_front().unwrap();
//! let first_child: Tree<i32> = tree.root_mut().pop_front().unwrap();
//! ```
//!
//! The potted version:
Expand All @@ -215,29 +215,29 @@
//!
//! 1. Using iter() to iterate over referenced child Nodes, you can:
//!
//! 1.1 read the data associated with each node.
//! - read the data associated with each node.
//!
//! 1.2 use iter() to iterate over children's children, etc.
//! - use iter() to iterate over children's children, etc.
//!
//! 2. Using iter_mut() to iterate over referenced child Nodes, you can:
//!
//! 2.1 read/write the data associated with each node, or prepend(), append, abandon(), push_front(), pop_front(), push_back(), pop_back() child node(s) in constant time.
//! - read/write the data associated with each node, or prepend(), append, abandon(), push_front(), pop_front(), push_back(), pop_back() child node(s) in constant time.
//!
//! Note that linked::singly does not have pop_back(), and potted tree/forest's methods are different in names and/or functionalities.
//!
//! 2.2 use iter_mut() to iterate over children's children, etc.
//! - use iter_mut() to iterate over children's children, etc.
//!
//! 3. Using onto_iter() to iterate over Subnodes, you can:
//!
//! 3.1 insert_before, insert_after(), depart() node(s) at any position.
//! - insert_before, insert_after(), depart() node(s) at any position.
//!
//! 3.2 do whatever iter() or iter_mut() can do.
//! - do whatever iter() or iter_mut() can do.
//!
//! Note that it is not implemented for potted version.
//!
//! 4. Using Forest::<T>::into_iter() to iterate over Trees, you can:
//!
//! Do whatever you want to.
//! - Do whatever you want to.
//!
//! Note that it is not implemented for potted version.
//!
Expand Down Expand Up @@ -280,7 +280,7 @@
//! ### Safety
//!
//! Collections of pointer-based tree implementation require many unsafes to do raw pointer dereferences.
//! Currently this crate contains **nearly 200 unsafe** blocks in its source code.
//! Currently this crate contains **200+ unsafe** blocks in its source code.
//! This crate relies on lifetime bounds and borrow check to keep memory-safety, in compile time.
//! The following are some simple demonstrations.
//!
Expand Down Expand Up @@ -331,23 +331,23 @@
extern crate indexed;

mod rust {
#[cfg(not(feature="no_std"))] pub(crate) use std::borrow::{Borrow,BorrowMut};
#[cfg(not(feature="no_std"))] pub(crate) use std::borrow::{Borrow,ToOwned};
#[cfg(not(feature="no_std"))] pub(crate) use std::boxed::Box;
#[cfg(not(feature="no_std"))] pub(crate) use std::collections::VecDeque;
#[cfg(not(feature="no_std"))] pub(crate) use std::cmp::Ordering::{self,*};
#[cfg(not(feature="no_std"))] pub(crate) use std::fmt::{self,Debug,Display,Formatter};
#[cfg(not(feature="no_std"))] pub(crate) use std::hash::{Hasher,Hash};
#[cfg(not(feature="no_std"))] pub(crate) use std::iter::{Iterator,FromIterator,IntoIterator,FusedIterator};
#[cfg(not(feature="no_std"))] pub(crate) use std::marker::PhantomData;
#[cfg(not(feature="no_std"))] pub(crate) use std::marker::{PhantomData,Unpin};
#[cfg(not(feature="no_std"))] pub(crate) use std::mem::{self,forget,transmute};
#[cfg(not(feature="no_std"))] pub(crate) use std::ops::{Add,AddAssign,Deref,DerefMut,Div,Neg,Sub,SubAssign};
#[cfg(not(feature="no_std"))] pub(crate) use std::ops::{Add,AddAssign,Deref,Div,Neg,Sub,SubAssign};
#[cfg(not(feature="no_std"))] pub(crate) use std::pin::Pin;
#[cfg(not(feature="no_std"))] pub(crate) use std::ptr::{self,NonNull,null,null_mut};
#[cfg(not(feature="no_std"))] pub(crate) use std::vec::Vec;

#[cfg(feature="no_std")] extern crate core;
#[cfg(feature="no_std")] extern crate alloc;
#[cfg(feature="no_std")] pub(crate) use self::alloc::borrow::{Borrow,BorrowMut,ToOwned};
#[cfg(feature="no_std")] pub(crate) use self::alloc::borrow::{Borrow,ToOwned};
#[cfg(feature="no_std")] pub(crate) use self::alloc::boxed::Box;
#[cfg(feature="no_std")] pub(crate) use self::alloc::string::String;
#[cfg(feature="no_std")]
Expand All @@ -360,9 +360,9 @@ mod rust {
#[cfg(feature="no_std")] pub(crate) use core::fmt::{self,Debug,Display,Formatter};
#[cfg(feature="no_std")] pub(crate) use core::hash::{Hasher,Hash};
#[cfg(feature="no_std")] pub(crate) use core::iter::{Iterator,FromIterator,IntoIterator,FusedIterator};
#[cfg(feature="no_std")] pub(crate) use core::marker::PhantomData;
#[cfg(feature="no_std")] pub(crate) use core::marker::{PhantomData,Unpin};
#[cfg(feature="no_std")] pub(crate) use core::mem::{self,forget,transmute};
#[cfg(feature="no_std")] pub(crate) use core::ops::{Add,AddAssign,Deref,DerefMut,Div,Neg,Sub,SubAssign};
#[cfg(feature="no_std")] pub(crate) use core::ops::{Add,AddAssign,Deref,Div,Neg,Sub,SubAssign};
#[cfg(feature="no_std")] pub(crate) use core::pin::Pin;
#[cfg(feature="no_std")] pub(crate) use core::ptr::{self,NonNull,null,null_mut};
}
Expand Down
88 changes: 35 additions & 53 deletions src/linked/fully/forest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ impl<T> Deref for Forest<T> {
fn deref( &self ) -> &Link { &self.link }
}

impl<T> DerefMut for Forest<T> {
fn deref_mut( &mut self ) -> &mut Link { &mut self.link }
}

impl<T> Forest<T> {
/// Makes an empty `Forest`.
#[inline] pub fn new() -> Forest<T> { Self::from( null_mut(), Size{ degree: 0, node_cnt: 0 })}
Expand Down Expand Up @@ -60,7 +56,10 @@ impl<T> Forest<T> {
#[inline] pub fn is_empty( &self ) -> bool { self.link.is_leaf() }

#[inline] pub(crate) fn set_parent( &mut self, parent: *mut Link ) {
for child in self.iter_mut() { child.set_parent( parent ); }
for child in self.iter_mut() {
let child = unsafe{ child.get_unchecked_mut() };
child.link.set_parent( parent );
}
}

#[inline] pub(crate) fn from( child: *mut Link, size: Size ) -> Self {
Expand Down Expand Up @@ -98,11 +97,11 @@ impl<T> Forest<T> {

/// Returns a mutable pointer to the first child of the forest,
/// or None if it is empty.
pub fn first_mut( &mut self ) -> Option<&mut Node<T>> {
pub fn first_mut( &mut self ) -> Option<Pin<&mut Node<T>>> {
if self.is_empty() {
None
} else {
unsafe { Some( &mut *( self.head() as *mut Node<T> ))}
unsafe { Some( Pin::new_unchecked( &mut *( self.head() as *mut Node<T> )))}
}
}

Expand All @@ -118,11 +117,11 @@ impl<T> Forest<T> {

/// Returns a mutable pointer to the last child of the forest,
/// or None if it is empty.
pub fn last_mut( &mut self ) -> Option<&mut Node<T>> {
pub fn last_mut( &mut self ) -> Option<Pin<&mut Node<T>>> {
if self.is_empty() {
None
} else {
unsafe { Some( &mut *( self.tail() as *mut Node<T> ))}
unsafe { Some( Pin::new_unchecked( &mut *( self.tail() as *mut Node<T> )))}
}
}

Expand All @@ -139,15 +138,15 @@ impl<T> Forest<T> {
/// assert_eq!( forest.to_string(), "( 2 1 )" );
/// ```
#[inline] pub fn push_front( &mut self, mut tree: Tree<T> ) {
let tree_root = tree.root_mut().plink();
let tree_root = tree.root_mut_().plink();
if self.is_empty() {
self.set_child( tree_root );
self.link.set_child( tree_root );
} else { unsafe {
tree.set_sib( self.tail(), self.head() );
self.adopt( tree_root, tree_root );
tree.link_mut().set_sib( self.tail(), self.head() );
self.link.adopt( tree_root, tree_root );
}}
self.size.degree += 1;
self.size.node_cnt += tree.root().size.node_cnt;
self.link.size.degree += 1;
self.link.size.node_cnt += tree.root().size.node_cnt;
tree.clear();
}

Expand All @@ -164,16 +163,16 @@ impl<T> Forest<T> {
/// assert_eq!( forest.to_string(), "( 1 2 )" );
/// ```
#[inline] pub fn push_back( &mut self, mut tree: Tree<T> ) {
let tree_root = tree.root_mut().plink();
let tree_root = tree.root_mut_().plink();
if !self.is_empty() {
unsafe {
tree.set_sib( self.tail(), self.head() );
self.adopt( tree_root, tree_root );
tree.link_mut().set_sib( self.tail(), self.head() );
self.link.adopt( tree_root, tree_root );
}
}
self.set_child( tree_root );
self.size.degree += 1;
self.size.node_cnt += tree.root().size.node_cnt;
self.link.set_child( tree_root );
self.link.size.degree += 1;
self.link.size.node_cnt += tree.root().size.node_cnt;
tree.clear();
}

Expand Down Expand Up @@ -202,8 +201,8 @@ impl<T> Forest<T> {
}
(*front).reset_parent();
(*front).reset_sib();
self.size.degree -= 1;
self.size.node_cnt -= (*front).size.node_cnt;
self.link.size.degree -= 1;
self.link.size.node_cnt -= (*front).size.node_cnt;
Some( Tree::from( front ))
}}
}
Expand Down Expand Up @@ -231,12 +230,12 @@ impl<T> Forest<T> {
let new_tail = self.new_tail();
(*new_tail).next = self.head();
(*self.head()).prev = new_tail;
self.set_child( new_tail );
self.link.set_child( new_tail );
}
(*back).reset_parent();
(*back).reset_sib();
self.size.degree -= 1;
self.size.node_cnt -= (*back).size.node_cnt;
self.link.size.degree -= 1;
self.link.size.node_cnt -= (*back).size.node_cnt;
Some( Tree::from( back ))
}}
}
Expand All @@ -256,13 +255,13 @@ impl<T> Forest<T> {
#[inline] pub fn prepend( &mut self, mut forest: Forest<T> ) {
if !forest.is_empty() {
if self.is_empty() {
self.set_child( forest.tail() );
self.link.set_child( forest.tail() );
} else { unsafe {
let forest_head = forest.head();
forest.set_sib( self.tail(), self.head() );
self.adopt( forest.tail(), forest_head );
self.link.adopt( forest.tail(), forest_head );
}}
self.size += forest.size;
self.link.size += forest.size;
forest.clear();
}
}
Expand All @@ -284,10 +283,10 @@ impl<T> Forest<T> {
if !self.is_empty() { unsafe {
let forest_head = forest.head();
forest.set_sib( self.tail(), self.head() );
self.adopt( forest.tail(), forest_head );
self.link.adopt( forest.tail(), forest_head );
}}
self.set_child( forest.tail() );
self.size += forest.size;
self.link.set_child( forest.tail() );
self.link.size += forest.size;
forest.clear();
}
}
Expand Down Expand Up @@ -317,15 +316,6 @@ impl<T> Forest<T> {
}}
}

#[deprecated( since="0.2.0", note="please use `iter` instead" )]
#[inline] pub fn children<'a>( &self ) -> Iter<'a,T> {
if self.is_empty() {
Iter::new( null(), null(), 0 )
} else { unsafe {
Iter::new( self.head(), self.tail(), self.size.degree as usize )
}}
}

/// Provides a forward iterator over child `Node`s with mutable references.
///
/// # Examples
Expand All @@ -337,7 +327,7 @@ impl<T> Forest<T> {
/// assert_eq!( forest.iter_mut().next(), None );
///
/// let mut forest = -tr(1)-tr(2);
/// for child in forest.iter_mut() { child.data *= 10; }
/// for mut child in forest.iter_mut() { child.data *= 10; }
/// assert_eq!( forest.to_string(), "( 10 20 )" );
/// ```
#[inline] pub fn iter_mut<'a>( &mut self ) -> IterMut<'a,T> {
Expand All @@ -348,15 +338,6 @@ impl<T> Forest<T> {
}}
}

#[deprecated( since="0.2.0", note="please use `iter_mut` instead" )]
#[inline] pub fn children_mut<'a>( &mut self ) -> IterMut<'a,T> {
if self.is_empty() {
IterMut::new( null_mut(), null_mut(), 0 )
} else { unsafe {
IterMut::new( self.head(), self.tail(), self.size.degree as usize )
}}
}

/// Provide an iterator over `Forest`'s `Subnode`s for insert/remove at any position.
/// See `Subnode`'s document for more.
#[inline] pub fn onto_iter<'a>( &mut self ) -> OntoIter<'a,T> {
Expand Down Expand Up @@ -540,11 +521,12 @@ impl<T> Extend<Tree<T>> for Forest<T> {

impl<T:Debug> Debug for Forest<T> { fn fmt( &self, f: &mut Formatter ) -> fmt::Result {
if self.is_empty() {
write!( f, "()" )
self.link.fmt(f)
} else {
self.link.fmt(f)?;
write!( f, "( " )?;
for child in self.iter() {
write!( f, "{:?} ", child )?;
child.fmt(f)?;
}
write!( f, ")" )
}
Expand Down
2 changes: 1 addition & 1 deletion src/linked/fully/heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub(crate) fn make_node<T>( data: T ) -> *mut Node<T> {
data,
}
);
node.reset_sib();
node.link.reset_sib();
Box::into_raw( node )
}

Expand Down
Loading

0 comments on commit 83cd177

Please sign in to comment.