Skip to content

Commit 2d8a66a

Browse files
committed
Adapt DagIterable
1 parent f28d109 commit 2d8a66a

File tree

4 files changed

+79
-22
lines changed

4 files changed

+79
-22
lines changed

src/core/commit.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
//
1515

1616
use crate::core::Value;
17+
use crate::impl_ref_wrapper;
1718
use crate::jet::{Application, JetNode};
1819
use crate::merkle::cmr;
1920
use crate::merkle::cmr::Cmr;
@@ -358,3 +359,9 @@ impl<Witness, App: Application> CommitNode<Witness, App> {
358359
}
359360
}
360361
}
362+
363+
/// Wrapper of references to [`CommitNode`].
364+
#[derive(Debug)]
365+
pub struct RefWrapper<'a, Witness, App: Application>(pub &'a CommitNode<Witness, App>);
366+
367+
impl_ref_wrapper!(RefWrapper);

src/core/iter.rs

Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,19 @@
1414

1515
//! Iterators over DAGs
1616
17-
use crate::core::Term;
18-
use crate::jet::Application;
1917
use std::collections::HashSet;
2018
use std::hash::Hash;
2119

2220
/// Structure that can be iterated like a DAG _(directed acyclic graph)_.
23-
pub trait DagIterable: Sized {
24-
/// Node in the DAG
25-
type Node: Copy + Eq + Hash;
26-
21+
pub trait DagIterable: Copy + Eq + Hash {
2722
/// Return the DAG root, if the DAG is nonempty.
28-
fn root(&self) -> Option<Self::Node>;
23+
fn root(self) -> Option<Self>;
2924

3025
/// Return the left child of the given `node`.
31-
fn left_of(&self, node: Self::Node) -> Option<Self::Node>;
26+
fn get_left(self) -> Option<Self>;
3227

3328
/// Return the right child of the given `node`.
34-
fn right_of(&self, node: Self::Node) -> Option<Self::Node>;
29+
fn get_right(self) -> Option<Self>;
3530

3631
/// Return a post-order iterator over the DAG.
3732
fn iter_post_order(&self) -> PostOrderIter<Self> {
@@ -43,34 +38,32 @@ pub trait DagIterable: Sized {
4338
/// That means, left children appear before right ones, and children appear before their parent.
4439
/// Shared nodes appear only once at their leftmost position.
4540
#[derive(Clone, Debug)]
46-
pub struct PostOrderIter<'a, D: DagIterable> {
47-
dag: &'a D,
48-
stack: Vec<D::Node>,
49-
maybe_current: Option<D::Node>,
50-
visited: HashSet<D::Node>,
41+
pub struct PostOrderIter<D: DagIterable> {
42+
stack: Vec<D>,
43+
maybe_current: Option<D>,
44+
visited: HashSet<D>,
5145
}
5246

53-
impl<'a, D: DagIterable> PostOrderIter<'a, D> {
47+
impl<D: DagIterable> PostOrderIter<D> {
5448
/// Create a new iterator from the given `dag`.
55-
pub fn new(dag: &'a D) -> Self {
49+
pub fn new(dag: &D) -> Self {
5650
PostOrderIter {
57-
dag,
5851
stack: Vec::new(),
5952
maybe_current: dag.root(),
6053
visited: HashSet::new(),
6154
}
6255
}
6356
}
6457

65-
impl<'a, D: DagIterable> Iterator for PostOrderIter<'a, D> {
66-
type Item = D::Node;
58+
impl<D: DagIterable> Iterator for PostOrderIter<D> {
59+
type Item = D;
6760

6861
fn next(&mut self) -> Option<Self::Item> {
6962
loop {
7063
if let Some(current) = self.maybe_current {
7164
self.stack.push(current);
7265

73-
if let Some(left) = self.dag.left_of(current) {
66+
if let Some(left) = current.get_left() {
7467
if !self.visited.contains(&left) {
7568
self.maybe_current = Some(left);
7669
continue;
@@ -79,7 +72,7 @@ impl<'a, D: DagIterable> Iterator for PostOrderIter<'a, D> {
7972
// else
8073
self.maybe_current = None;
8174
} else if let Some(top) = self.stack.last() {
82-
if let Some(right) = self.dag.right_of(*top) {
75+
if let Some(right) = top.get_right() {
8376
if !self.visited.contains(&right) {
8477
self.maybe_current = Some(right);
8578
continue;
@@ -97,6 +90,55 @@ impl<'a, D: DagIterable> Iterator for PostOrderIter<'a, D> {
9790
}
9891
}
9992

93+
/// Convenience macro for wrappers of references to structures over
94+
/// `<Witness, App: Application>`.
95+
///
96+
/// Implements `Clone`, `Copy`, `Eq` and `Hash` using pointers.
97+
/// Implements [`DagIterable`] using `self.0.get_left()` and `self.0.get_right()`.
98+
#[macro_export]
99+
macro_rules! impl_ref_wrapper {
100+
($wrapper:ident) => {
101+
impl<'a, Witness, App: Application> Clone for $wrapper<'a, Witness, App> {
102+
fn clone(&self) -> Self {
103+
$wrapper(&(self.0).clone())
104+
}
105+
}
106+
107+
impl<'a, Witness, App: Application> Copy for $wrapper<'a, Witness, App> {}
108+
109+
impl<'a, Witness, App: Application> PartialEq for $wrapper<'a, Witness, App> {
110+
fn eq(&self, other: &Self) -> bool {
111+
std::ptr::eq(self.0, other.0)
112+
}
113+
}
114+
115+
impl<'a, Witness, App: Application> Eq for $wrapper<'a, Witness, App> {}
116+
117+
impl<'a, Witness, App: Application> std::hash::Hash for $wrapper<'a, Witness, App> {
118+
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
119+
std::ptr::hash(self.0, state)
120+
}
121+
}
122+
123+
impl<'a, Witness, App: Application> $crate::core::iter::DagIterable
124+
for $wrapper<'a, Witness, App>
125+
{
126+
fn root(self) -> Option<Self> {
127+
Some(self)
128+
}
129+
130+
fn get_left(self) -> Option<Self> {
131+
self.0.get_left().map(|x| RefWrapper(x))
132+
}
133+
134+
fn get_right(self) -> Option<Self> {
135+
self.0.get_right().map(|x| RefWrapper(x))
136+
}
137+
}
138+
};
139+
}
140+
141+
/*
100142
/// Convert the given iterator over [`Term`]s into an iterator over the contained `Witness` values.
101143
pub fn into_witness<'a, Witness, App: Application, I>(
102144
iter: I,
@@ -113,3 +155,4 @@ where
113155
}
114156
})
115157
}
158+
*/

src/core/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
//!
1818
//! Defines Simplicity terms, values, types, DAGs and programs.
1919
20-
// pub mod iter;
2120
pub mod commit;
21+
pub mod iter;
2222
pub mod node;
2323
#[allow(dead_code)]
2424
pub mod types;

src/core/node.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
//
1414

1515
use crate::core::types::Type;
16+
use crate::impl_ref_wrapper;
1617
use crate::jet::{Application, JetNode};
1718
use crate::merkle::cmr::Cmr;
1819
use crate::merkle::imr::Imr;
@@ -142,3 +143,9 @@ impl<Witness, App: Application> Node<Witness, App> {
142143
}
143144
}
144145
}
146+
147+
/// Wrapper of references to [`Node`].
148+
#[derive(Debug)]
149+
pub struct RefWrapper<'a, Witness, App: Application>(pub &'a Node<Witness, App>);
150+
151+
impl_ref_wrapper!(RefWrapper);

0 commit comments

Comments
 (0)